mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-01-15 00:18:06 -05:00
Implement direct class comparison
This commit is contained in:
@@ -40,6 +40,8 @@ impl BuiltinObject for ErrorBuiltin {
|
||||
|
||||
fn bo_as_class_data() -> Option<Rc<VsClass>> {
|
||||
Some(Rc::new(VsClass {
|
||||
name: "Error".to_string(),
|
||||
content_hash: None,
|
||||
constructor: SET_MESSAGE.to_val(),
|
||||
prototype: make_error_prototype(),
|
||||
static_: VsObject::default().to_val(),
|
||||
|
||||
@@ -39,6 +39,8 @@ impl BuiltinObject for InternalErrorBuiltin {
|
||||
|
||||
fn bo_as_class_data() -> Option<Rc<VsClass>> {
|
||||
Some(Rc::new(VsClass {
|
||||
name: "InternalError".to_string(),
|
||||
content_hash: None,
|
||||
constructor: Val::Static(&SET_MESSAGE),
|
||||
prototype: make_internal_error_prototype(),
|
||||
static_: VsObject::default().to_val(),
|
||||
|
||||
@@ -31,6 +31,8 @@ impl BuiltinObject for RangeErrorBuiltin {
|
||||
|
||||
fn bo_as_class_data() -> Option<Rc<VsClass>> {
|
||||
Some(Rc::new(VsClass {
|
||||
name: "RangeError".to_string(),
|
||||
content_hash: None,
|
||||
constructor: Val::Static(&SET_MESSAGE),
|
||||
prototype: make_range_error_prototype(),
|
||||
static_: VsObject::default().to_val(),
|
||||
|
||||
@@ -39,6 +39,8 @@ impl BuiltinObject for TypeErrorBuiltin {
|
||||
|
||||
fn bo_as_class_data() -> Option<Rc<VsClass>> {
|
||||
Some(Rc::new(VsClass {
|
||||
name: "TypeError".to_string(),
|
||||
content_hash: None,
|
||||
constructor: Val::Static(&SET_MESSAGE),
|
||||
prototype: make_type_error_prototype(),
|
||||
static_: VsObject::default().to_val(),
|
||||
|
||||
@@ -6,7 +6,6 @@ use num_bigint::BigInt;
|
||||
use num_bigint::Sign;
|
||||
use valuescript_common::InstructionByte;
|
||||
|
||||
use crate::builtins::internal_error_builtin::ToInternalError;
|
||||
use crate::builtins::BUILTIN_VALS;
|
||||
use crate::bytecode::Bytecode;
|
||||
use crate::vs_class::VsClass;
|
||||
@@ -147,12 +146,18 @@ impl BytecodeDecoder {
|
||||
val => take(val),
|
||||
},
|
||||
BytecodeType::Builtin => BUILTIN_VALS[self.decode_varsize_uint()](),
|
||||
BytecodeType::Class => VsClass {
|
||||
constructor: self.decode_val(registers),
|
||||
prototype: self.decode_val(registers),
|
||||
static_: self.decode_val(registers),
|
||||
BytecodeType::Class => {
|
||||
let meta = self.decode_meta();
|
||||
|
||||
VsClass {
|
||||
name: meta.name,
|
||||
content_hash: meta.content_hash,
|
||||
constructor: self.decode_val(registers),
|
||||
prototype: self.decode_val(registers),
|
||||
static_: self.decode_val(registers),
|
||||
}
|
||||
.to_val()
|
||||
}
|
||||
.to_val(),
|
||||
BytecodeType::BigInt => self.decode_bigint().to_val(),
|
||||
BytecodeType::GeneratorFunction => self.decode_function(true),
|
||||
BytecodeType::Unrecognized => panic!("Unrecognized bytecode type at {}", self.pos - 1),
|
||||
@@ -314,20 +319,19 @@ impl BytecodeDecoder {
|
||||
InstructionByte::from_byte(self.decode_byte())
|
||||
}
|
||||
|
||||
pub fn decode_content_hash(&mut self) -> Result<[u8; 32], Val> {
|
||||
pub fn decode_meta(&mut self) -> Meta {
|
||||
if self.decode_byte() != 0x16 {
|
||||
return Err("Can't decode a content hash here".to_internal_error());
|
||||
panic!("Expected meta");
|
||||
}
|
||||
|
||||
if self.decode_type() != BytecodeType::String {
|
||||
return Err("Expected string".to_internal_error());
|
||||
panic!("Expected string");
|
||||
}
|
||||
|
||||
let name_len = self.decode_varsize_uint();
|
||||
self.pos += name_len;
|
||||
let name = self.decode_string();
|
||||
|
||||
match self.decode_byte() {
|
||||
0 | 1 => Err("Missing content hash".to_internal_error()), // Empty | Src
|
||||
let content_hash = match self.decode_byte() {
|
||||
0 | 1 => None, // Empty | Src
|
||||
2 => {
|
||||
// Hash
|
||||
let mut res = [0u8; 32];
|
||||
@@ -336,9 +340,16 @@ impl BytecodeDecoder {
|
||||
*b = self.decode_byte();
|
||||
}
|
||||
|
||||
Ok(res)
|
||||
Some(res)
|
||||
}
|
||||
_ => Err("Unrecognized content_hashable case".to_internal_error()),
|
||||
}
|
||||
_ => panic!("Unrecognized ContentHashable case"),
|
||||
};
|
||||
|
||||
Meta { name, content_hash }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Meta {
|
||||
pub name: String,
|
||||
pub content_hash: Option<[u8; 32]>,
|
||||
}
|
||||
|
||||
@@ -205,6 +205,11 @@ pub fn op_eq_impl(left: &Val, right: &Val) -> Result<bool, Val> {
|
||||
|
||||
true
|
||||
}
|
||||
(Val::Class(left), Val::Class(right)) => match (&left.content_hash, &right.content_hash) {
|
||||
(None, None) => std::ptr::eq(&**left, &**right),
|
||||
(None, Some(_)) | (Some(_), None) => return Ok(false),
|
||||
(Some(left_hash), Some(right_hash)) => left_hash == right_hash,
|
||||
},
|
||||
_ => {
|
||||
if left.is_truthy() != right.is_truthy() {
|
||||
return Ok(false);
|
||||
@@ -350,6 +355,11 @@ pub fn op_triple_eq_impl(left: &Val, right: &Val) -> Result<bool, Val> {
|
||||
format!("TODO: op=== with special types ({}, {})", left, right).to_internal_error(),
|
||||
);
|
||||
}
|
||||
(Val::Class(left), Val::Class(right)) => match (&left.content_hash, &right.content_hash) {
|
||||
(None, None) => std::ptr::eq(&**left, &**right),
|
||||
(None, Some(_)) | (Some(_), None) => return Ok(false),
|
||||
(Some(left_hash), Some(right_hash)) => left_hash == right_hash,
|
||||
},
|
||||
_ => {
|
||||
assert!(left.typeof_() != right.typeof_());
|
||||
false
|
||||
|
||||
@@ -6,6 +6,8 @@ use super::vs_value::Val;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VsClass {
|
||||
pub name: String,
|
||||
pub content_hash: Option<[u8; 32]>,
|
||||
pub constructor: Val,
|
||||
pub prototype: Val,
|
||||
pub static_: Val,
|
||||
|
||||
@@ -42,7 +42,10 @@ impl VsFunction {
|
||||
|
||||
pub fn content_hash(&self) -> Result<[u8; 32], Val> {
|
||||
match self.meta_pos {
|
||||
Some(p) => self.bytecode.decoder(p).decode_content_hash(),
|
||||
Some(p) => match self.bytecode.decoder(p).decode_meta().content_hash {
|
||||
Some(content_hash) => Ok(content_hash),
|
||||
None => Err("content_hash missing".to_internal_error()),
|
||||
},
|
||||
None => Err("Can't get content_hash without meta_pos".to_internal_error()),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user