feat: 支持 Object 成员方法

This commit is contained in:
2026-06-07 01:59:30 +08:00
parent 439b61e359
commit 9ca35d75e0
16 changed files with 568 additions and 47 deletions
@@ -0,0 +1,53 @@
use oxide_compiler::compiler::Compiler;
use oxide_vm::vm::Vm;
fn eval(source: &str) -> Result<oxide_types::value::JsValue, String> {
let allocator = oxide_parser::Allocator::default();
let program =
oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?;
let module = Compiler::new()
.compile(&program)
.map_err(|e| format!("Compile error: {}", e))?;
let mut vm = Vm::new();
vm.run(&module)
}
#[test]
fn object_keys_empty() {
let result = eval("Object.keys({})").unwrap();
assert!(result.is_object());
}
#[test]
fn object_keys_has_own_property() {
eval("Object.keys({a:1})").unwrap();
}
#[test]
fn object_create_null_proto() {
eval("Object.create(null)").unwrap();
}
#[test]
fn object_assign_copies() {
let result = eval("Object.assign({a:1},{b:2})").unwrap();
assert!(result.is_object());
}
#[test]
fn object_get_own_property_descriptor_value() {
let result = eval("Object.getOwnPropertyDescriptor({a:1},'a')").unwrap();
assert!(result.is_object());
}
#[test]
fn object_get_own_property_descriptor_missing() {
let result = eval("Object.getOwnPropertyDescriptor({},'x')").unwrap();
assert!(result.is_undefined());
}
#[test]
fn object_define_property_sets_value() {
let result = eval("Object.defineProperty({},'x',{value:42})").unwrap();
assert!(result.is_object());
}
@@ -0,0 +1,46 @@
use oxide_compiler::compiler::Compiler;
use oxide_vm::vm::Vm;
#[test]
fn eval_object_is_object() {
let allocator = oxide_parser::Allocator::default();
let program = oxide_parser::parse(&allocator, "Object").unwrap();
let module = Compiler::new().compile(&program).unwrap();
let mut vm = Vm::new();
let result = vm.run(&module).unwrap();
assert!(
result.is_object(),
"Object should be an object, got {:?}",
result
);
}
#[test]
fn verify_global_object_props() {
let vm = Vm::new();
let global = vm.kernel().global_object();
let obj_si = vm.kernel().string_forge().intern("Object").0;
let mut shape_id = global.shape_id();
let mut found = false;
while shape_id != oxide_kernel::shape_forge::EMPTY_SHAPE_ID {
if let Some(shape) = vm.kernel().shape_forge().get_shape(shape_id) {
if shape.property_name == obj_si {
found = true;
let val = global.get_prop(shape.property_offset);
assert!(
val.is_object(),
"Object prop should be object, got {:?}",
val
);
break;
}
shape_id = shape
.parent
.unwrap_or(oxide_kernel::shape_forge::EMPTY_SHAPE_ID);
} else {
break;
}
}
assert!(found, "Object property not found on global object");
}
+3 -1
View File
@@ -121,7 +121,9 @@ fn as_js_object_ptr_non_object_returns_null() {
assert!(JsValue::null().as_js_object_ptr().is_null());
assert!(JsValue::undefined().as_js_object_ptr().is_null());
let x = 42u8;
assert!(!JsValue::object(&x as *const u8).as_js_object_ptr().is_null());
assert!(!JsValue::object(&x as *const u8)
.as_js_object_ptr()
.is_null());
}
#[test]