Bridge canonicalize: add compare/branch/jump diff tests; Map field bad-key stable tag with smoke; Update smokes README with diff canary policy
This commit is contained in:
@ -30,7 +30,13 @@ pub(super) fn try_handle_map_box(
|
||||
"MapBox.getField expects 1 arg".into(),
|
||||
));
|
||||
}
|
||||
let k = this.reg_load(args[0])?.to_nyash_box();
|
||||
let k_vm = this.reg_load(args[0])?;
|
||||
// Field access expects a String key; otherwise return a stable tag.
|
||||
if !matches!(k_vm, VMValue::String(_)) {
|
||||
if let Some(d) = dst { this.regs.insert(d, VMValue::String("[map/bad-key] field name must be string".to_string())); }
|
||||
return Ok(true);
|
||||
}
|
||||
let k = k_vm.to_nyash_box();
|
||||
let ret = mb.get(k);
|
||||
if let Some(d) = dst {
|
||||
this.regs.insert(d, VMValue::from_nyash_box(ret));
|
||||
@ -43,7 +49,12 @@ pub(super) fn try_handle_map_box(
|
||||
"MapBox.setField expects 2 args".into(),
|
||||
));
|
||||
}
|
||||
let k = this.reg_load(args[0])?.to_nyash_box();
|
||||
let k_vm = this.reg_load(args[0])?;
|
||||
if !matches!(k_vm, VMValue::String(_)) {
|
||||
if let Some(d) = dst { this.regs.insert(d, VMValue::String("[map/bad-key] field name must be string".to_string())); }
|
||||
return Ok(true);
|
||||
}
|
||||
let k = k_vm.to_nyash_box();
|
||||
let v = this.reg_load(args[1])?.to_nyash_box();
|
||||
let ret = mb.set(k, v);
|
||||
if let Some(d) = dst {
|
||||
|
||||
@ -40,6 +40,24 @@ pub(super) fn try_handle_object_fields(
|
||||
if args.len() != 1 {
|
||||
return Err(VMError::InvalidInstruction("getField expects 1 arg".into()));
|
||||
}
|
||||
// MapBox special-case: bridge to MapBox.get, with string-only key
|
||||
if let Ok(VMValue::BoxRef(bref)) = this.reg_load(box_val) {
|
||||
if bref.as_any().downcast_ref::<crate::boxes::map_box::MapBox>().is_some() {
|
||||
let key_vm = this.reg_load(args[0])?;
|
||||
if let VMValue::String(_) = key_vm {
|
||||
let k = key_vm.to_nyash_box();
|
||||
let map = bref.share_box();
|
||||
if let Some(mb) = map.as_any().downcast_ref::<crate::boxes::map_box::MapBox>() {
|
||||
let ret = mb.get(k);
|
||||
if let Some(d) = dst { this.regs.insert(d, VMValue::from_nyash_box(ret)); }
|
||||
return Ok(true);
|
||||
}
|
||||
} else {
|
||||
if let Some(d) = dst { this.regs.insert(d, VMValue::String("[map/bad-key] field name must be string".to_string())); }
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if std::env::var("NYASH_VM_TRACE").ok().as_deref() == Some("1") {
|
||||
let rk = match this.reg_load(box_val) {
|
||||
Ok(VMValue::BoxRef(ref b)) => format!("BoxRef({})", b.type_name()),
|
||||
@ -282,6 +300,25 @@ pub(super) fn try_handle_object_fields(
|
||||
"setField expects 2 args".into(),
|
||||
));
|
||||
}
|
||||
// MapBox special-case: bridge to MapBox.set, with string-only key
|
||||
if let Ok(VMValue::BoxRef(bref)) = this.reg_load(box_val) {
|
||||
if bref.as_any().downcast_ref::<crate::boxes::map_box::MapBox>().is_some() {
|
||||
let key_vm = this.reg_load(args[0])?;
|
||||
if let VMValue::String(_) = key_vm {
|
||||
let k = key_vm.to_nyash_box();
|
||||
let v = this.reg_load(args[1])?.to_nyash_box();
|
||||
let map = bref.share_box();
|
||||
if let Some(mb) = map.as_any().downcast_ref::<crate::boxes::map_box::MapBox>() {
|
||||
let _ = mb.set(k, v);
|
||||
if let Some(d) = dst { this.regs.insert(d, VMValue::Void); }
|
||||
return Ok(true);
|
||||
}
|
||||
} else {
|
||||
if let Some(d) = dst { this.regs.insert(d, VMValue::String("[map/bad-key] field name must be string".to_string())); }
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
let fname = match this.reg_load(args[0])? {
|
||||
VMValue::String(s) => s,
|
||||
v => v.to_string(),
|
||||
|
||||
Reference in New Issue
Block a user