Add fake hash and use it to compare functions and class instances

This commit is contained in:
Andrew Morris
2023-07-26 17:27:03 +10:00
parent b683e47bc5
commit 69663190ee
6 changed files with 119 additions and 2 deletions

View File

@@ -281,12 +281,18 @@ impl BytecodeDecoder {
}
pub fn decode_function(&mut self, is_generator: bool) -> Val {
// TODO: Use actual content hash
let mut hash = [0u8; 32];
hash[0] = (self.pos & 0xff) as u8;
hash[1] = ((self.pos >> 8) & 0xff) as u8;
// TODO: Support >256
let register_count = self.decode_byte() as usize;
let parameter_count = self.decode_byte() as usize;
VsFunction {
bytecode: self.bytecode.clone(),
hash,
is_generator,
register_count,
parameter_count,

View File

@@ -146,6 +146,17 @@ pub fn op_eq_impl(left: &Val, right: &Val) -> Result<bool, Val> {
true
}
(Val::Object(left_object), Val::Object(right_object)) => 'b: {
match (&left_object.prototype, &right_object.prototype) {
(None, None) => {}
(None, Some(_)) => return Ok(false),
(Some(_), None) => return Ok(false),
(Some(ref left_proto), Some(ref right_proto)) => {
if !op_eq_impl(left_proto, right_proto)? {
return Ok(false);
}
}
}
if left_object.prototype.is_some() || right_object.prototype.is_some() {
return Err("TODO: class instance comparison".to_internal_error());
}
@@ -172,6 +183,19 @@ pub fn op_eq_impl(left: &Val, right: &Val) -> Result<bool, Val> {
true
}
(Val::Function(left), Val::Function(right)) => {
if left.binds.len() != right.binds.len() {
return Ok(false);
}
for i in 0..left.binds.len() {
if !op_eq_impl(&left.binds[i], &right.binds[i])? {
return Ok(false);
}
}
left.hash == right.hash
}
_ => {
if left.is_truthy() != right.is_truthy() {
return Ok(false);
@@ -248,8 +272,15 @@ pub fn op_triple_eq_impl(left: &Val, right: &Val) -> Result<bool, Val> {
true
}
(Val::Object(left_object), Val::Object(right_object)) => 'b: {
if left_object.prototype.is_some() || right_object.prototype.is_some() {
return Err("TODO: class instance comparison".to_internal_error());
match (&left_object.prototype, &right_object.prototype) {
(None, None) => {}
(None, Some(_)) => return Ok(false),
(Some(_), None) => return Ok(false),
(Some(ref left_proto), Some(ref right_proto)) => {
if !op_triple_eq_impl(left_proto, right_proto)? {
return Ok(false);
}
}
}
if std::ptr::eq(&**left_object, &**right_object) {
@@ -274,6 +305,19 @@ pub fn op_triple_eq_impl(left: &Val, right: &Val) -> Result<bool, Val> {
true
}
(Val::Function(left), Val::Function(right)) => {
if left.binds.len() != right.binds.len() {
return Ok(false);
}
for i in 0..left.binds.len() {
if !op_triple_eq_impl(&left.binds[i], &right.binds[i])? {
return Ok(false);
}
}
left.hash == right.hash
}
(Val::Static(..) | Val::Dynamic(..) | Val::CopyCounter(..), _)
| (_, Val::Static(..) | Val::Dynamic(..) | Val::CopyCounter(..)) => {
if left.typeof_() != right.typeof_() {

View File

@@ -12,6 +12,7 @@ use super::vs_value::Val;
#[derive(Debug, Clone)]
pub struct VsFunction {
pub bytecode: Rc<Bytecode>,
pub hash: [u8; 32],
pub is_generator: bool,
pub register_count: usize,
pub parameter_count: usize,
@@ -29,6 +30,7 @@ impl VsFunction {
VsFunction {
bytecode: self.bytecode.clone(),
hash: self.hash,
is_generator: self.is_generator,
register_count: self.register_count,
parameter_count: self.parameter_count,