Implement new instruction

This commit is contained in:
Andrew Morris
2022-05-27 14:09:18 +10:00
parent 7d58ba3c34
commit f19d1094b6
8 changed files with 83 additions and 13 deletions

View File

@@ -3,6 +3,7 @@ use std::rc::Rc;
use super::vs_value::{Val, VsType, ValTrait, LoadFunctionResult};
use super::vs_array::VsArray;
use super::vs_object::VsObject;
use super::vs_class::VsClass;
use super::native_function::NativeFunction;
use super::operations::to_u32;
@@ -24,6 +25,7 @@ impl ValTrait for Math {
fn as_array_data(&self) -> Option<Rc<VsArray>> { None }
fn as_object_data(&self) -> Option<Rc<VsObject>> { None }
fn as_class_data(&self) -> Option<Rc<VsClass>> { None }
fn load_function(&self) -> LoadFunctionResult {
LoadFunctionResult::NotAFunction

View File

@@ -8,6 +8,7 @@ use super::vs_value::{
};
use super::vs_object::VsObject;
use super::vs_array::VsArray;
use super::vs_class::VsClass;
pub struct NativeFunction {
pub fn_: fn(this: &mut Val, params: Vec<Val>) -> Val,
@@ -29,6 +30,7 @@ impl ValTrait for NativeFunction {
fn as_array_data(&self) -> Option<Rc<VsArray>> { None }
fn as_object_data(&self) -> Option<Rc<VsObject>> { None }
fn as_class_data(&self) -> Option<Rc<VsClass>> { None }
fn load_function(&self) -> LoadFunctionResult {
LoadFunctionResult::NativeFunction(self.fn_)

View File

@@ -218,9 +218,10 @@ pub fn op_typeof(input: Val) -> Val {
Array => "object".to_string(),
Object => "object".to_string(),
Function => "function".to_string(),
Class => "function".to_string(),
}));
}
pub fn op_instance_of(_left: Val, _right: Val) -> Val {
std::panic!("Not implemented: op_instance_of");
}
@@ -286,6 +287,7 @@ pub fn op_sub(left: Val, right: Val) -> Val {
return object_data.sub(right);
},
Val::Function(_) => Val::Undefined,
Val::Class(_) => Val::Undefined,
Val::Static(s) => s.sub(right),
Val::Custom(custom_data) => custom_data.sub(right),
}
@@ -325,6 +327,7 @@ pub fn op_submov(target: &mut Val, subscript: Val, value: Val) {
Rc::make_mut(object_data).string_map.insert(subscript.val_to_string(), value);
},
Val::Function(_) => std::panic!("Not implemented: function subscript assignment"),
Val::Class(_) => std::panic!("Not implemented: class subscript assignment"),
Val::Static(_) => std::panic!("Not implemented: exceptions"),
Val::Custom(_) => std::panic!("Not implemented"),
}

View File

@@ -1,6 +1,7 @@
use std::rc::Rc;
use super::vs_value::{Val, ValTrait, LoadFunctionResult};
use super::vs_object::VsObject;
use super::operations;
use super::bytecode_decoder::BytecodeDecoder;
use super::bytecode_decoder::BytecodeType;
@@ -233,7 +234,7 @@ impl VirtualMachine {
self.push(new_frame);
},
LoadFunctionResult::NativeFunction(native_fn) => {
LoadFunctionResult::NativeFunction(_native_fn) => {
std::panic!("Not implemented");
},
}
@@ -366,7 +367,44 @@ impl VirtualMachine {
UnaryPlus => self.frame.apply_unary_op(operations::op_unary_plus),
UnaryMinus => self.frame.apply_unary_op(operations::op_unary_minus),
New => std::panic!("Not implemented"),
New => {
let class = self.frame.decoder.decode_val(&self.frame.registers)
.as_class_data()
.expect("Not implemented: throw exception (not constructible)");
let mut instance = Val::Object(Rc::new(VsObject {
string_map: Default::default(),
prototype: Some(class.instance_prototype.clone()),
}));
match class.constructor.load_function() {
LoadFunctionResult::NotAFunction =>
std::panic!("Not implemented: throw exception (class.constructor is not a function)")
,
LoadFunctionResult::StackFrame(mut new_frame) => {
transfer_parameters(&mut self.frame, &mut new_frame);
new_frame.registers[1] = instance;
self.frame.return_target = None;
self.frame.this_target = self.frame.decoder.decode_register_index();
self.push(new_frame);
},
LoadFunctionResult::NativeFunction(native_fn) => {
native_fn(
&mut instance,
get_parameters(&mut self.frame),
);
match self.frame.decoder.decode_register_index() {
Some(target) => {
self.frame.registers[target] = instance;
},
None => {},
};
},
};
}
};
}

View File

@@ -8,6 +8,7 @@ use super::vs_value::{
LoadFunctionResult,
};
use super::vs_object::VsObject;
use super::vs_class::VsClass;
use super::native_function::NativeFunction;
use super::operations::op_triple_eq_impl;
@@ -47,6 +48,7 @@ impl ValTrait for ArrayPrototype {
fn as_array_data(&self) -> Option<Rc<VsArray>> { None }
fn as_object_data(&self) -> Option<Rc<VsObject>> { None }
fn as_class_data(&self) -> Option<Rc<VsClass>> { None }
fn load_function(&self) -> LoadFunctionResult {
LoadFunctionResult::NotAFunction

View File

@@ -1,10 +1,7 @@
use std::rc::Rc;
use super::vs_value::Val;
use super::vs_function::VsFunction;
pub struct VsClass {
pub constructor: Rc<VsFunction>,
pub constructor: Val,
pub instance_prototype: Val,
}

View File

@@ -5,6 +5,7 @@ use super::vs_value::{Val, ValTrait, VsType, LoadFunctionResult};
use super::bytecode_decoder::{BytecodeDecoder, BytecodeType};
use super::vs_object::VsObject;
use super::vs_array::VsArray;
use super::vs_class::VsClass;
pub struct VsPointer {
bytecode: Rc<Vec<u8>>,
@@ -118,6 +119,10 @@ impl ValTrait for VsPointer {
return self.resolve().as_object_data();
}
fn as_class_data(&self) -> Option<Rc<VsClass>> {
return self.resolve().as_class_data();
}
fn load_function(&self) -> LoadFunctionResult {
return self.resolve().load_function();
}

View File

@@ -5,7 +5,7 @@ use super::vs_function::VsFunction;
use super::virtual_machine::StackFrame;
use super::vs_object::VsObject;
use super::vs_array::VsArray;
// use super::vs_class::VsClass;
use super::vs_class::VsClass;
use super::operations::{op_sub, op_submov};
#[derive(Clone)]
@@ -19,7 +19,7 @@ pub enum Val {
Array(Rc<VsArray>),
Object(Rc<VsObject>),
Function(Rc<VsFunction>),
// Class(Rc<VsClass>),
Class(Rc<VsClass>),
Static(&'static dyn ValTrait),
Custom(Rc<dyn ValTrait>),
}
@@ -34,6 +34,7 @@ pub enum VsType {
Array,
Object,
Function,
Class,
}
pub enum LoadFunctionResult {
@@ -56,6 +57,7 @@ pub trait ValTrait {
fn as_array_data(&self) -> Option<Rc<VsArray>>;
fn as_object_data(&self) -> Option<Rc<VsObject>>;
fn as_class_data(&self) -> Option<Rc<VsClass>>;
fn load_function(&self) -> LoadFunctionResult;
@@ -79,6 +81,7 @@ impl ValTrait for Val {
Array(_) => VsType::Array,
Object(_) => VsType::Object,
Function(_) => VsType::Function,
Class(_) => VsType::Class,
Static(val) => val.typeof_(),
Custom(val) => val.typeof_(),
};
@@ -117,6 +120,7 @@ impl ValTrait for Val {
},
Object(_) => "[object Object]".to_string(),
Function(_) => "[function]".to_string(),
Class(_) => "[class]".to_string(),
Static(val) => val.val_to_string(),
Custom(val) => val.val_to_string(),
};
@@ -139,6 +143,7 @@ impl ValTrait for Val {
},
Object(_) => f64::NAN,
Function(_) => f64::NAN,
Class(_) => f64::NAN,
Static(val) => val.to_number(),
Custom(val) => val.to_number(),
};
@@ -160,6 +165,7 @@ impl ValTrait for Val {
Array(_) => None,
Object(_) => None,
Function(_) => None,
Class(_) => None,
Static(val) => val.to_index(),
Custom(val) => val.to_index(),
};
@@ -178,6 +184,7 @@ impl ValTrait for Val {
Array(_) => false,
Object(_) => false,
Function(_) => false,
Class(_) => false,
Static(val) => val.is_primitive(), // TODO: false?
Custom(val) => val.is_primitive(),
}
@@ -204,6 +211,7 @@ impl ValTrait for Val {
Array(_) => true,
Object(_) => true,
Function(_) => true,
Class(_) => true,
Static(val) => val.is_truthy(), // TODO: true?
Custom(val) => val.is_truthy(),
};
@@ -222,6 +230,7 @@ impl ValTrait for Val {
Array(_) => false,
Object(_) => false,
Function(_) => false,
Class(_) => false,
Static(_) => false,
Custom(val) => val.is_nullish(),
};
@@ -235,7 +244,7 @@ impl ValTrait for Val {
Custom(val) => val.bind(params),
_ => None,
}
};
}
fn as_array_data(&self) -> Option<Rc<VsArray>> {
@@ -246,7 +255,7 @@ impl ValTrait for Val {
Custom(val) => val.as_array_data(),
_ => None,
}
};
}
fn as_object_data(&self) -> Option<Rc<VsObject>> {
@@ -257,7 +266,18 @@ impl ValTrait for Val {
Custom(val) => val.as_object_data(),
_ => None,
}
};
}
fn as_class_data(&self) -> Option<Rc<VsClass>> {
use Val::*;
return match self {
Class(class) => Some(class.clone()),
Custom(val) => val.as_class_data(),
_ => None,
};
}
fn load_function(&self) -> LoadFunctionResult {
@@ -269,7 +289,7 @@ impl ValTrait for Val {
Custom(val) => val.load_function(),
_ => LoadFunctionResult::NotAFunction,
}
};
}
fn sub(&self, key: Val) -> Val {
@@ -341,6 +361,7 @@ impl std::fmt::Display for Val {
f.write_str(" }")
},
Val::Function(_) => write!(f, "\x1b[36m[Function]\x1b[39m"),
Val::Class(_) => write!(f, "\x1b[36m[Class]\x1b[39m"),
// TODO: Improve printing these
Val::Static(s) => s.fmt(f),