From c581dce4e3ba9703625a20c520f87f4f4ae9e340 Mon Sep 17 00:00:00 2001 From: y21 <30553356+y21@users.noreply.github.com> Date: Sun, 5 May 2024 23:19:21 +0200 Subject: [PATCH] implement `Object.defineProperties` --- crates/dash_middle/src/interner.rs | 1 + crates/dash_node_impl/src/lib.rs | 2 +- crates/dash_vm/src/js_std/object.rs | 21 +++++++++++++++++++++ crates/dash_vm/src/lib.rs | 1 + crates/dash_vm/src/statics.rs | 2 ++ crates/dash_vm/src/value/object.rs | 6 +++--- 6 files changed, 29 insertions(+), 4 deletions(-) diff --git a/crates/dash_middle/src/interner.rs b/crates/dash_middle/src/interner.rs index f5da3567..605c6e5b 100644 --- a/crates/dash_middle/src/interner.rs +++ b/crates/dash_middle/src/interner.rs @@ -141,6 +141,7 @@ pub mod sym { getOwnPropertyDescriptor, getOwnPropertyDescriptors, defineProperty, + defineProperties, entries, assign, Object, diff --git a/crates/dash_node_impl/src/lib.rs b/crates/dash_node_impl/src/lib.rs index f616564a..e2ee6bd7 100644 --- a/crates/dash_node_impl/src/lib.rs +++ b/crates/dash_node_impl/src/lib.rs @@ -191,7 +191,7 @@ impl Object for RequireFunction { let is_path = matches!(arg.chars().next(), Some('.' | '/' | '~')); let result = if is_path { - if !arg.ends_with(".js") { + if !arg.ends_with(".js") && !arg.ends_with(".json") { arg += ".js"; } diff --git a/crates/dash_vm/src/js_std/object.rs b/crates/dash_vm/src/js_std/object.rs index 47af8a5a..1826d01f 100644 --- a/crates/dash_vm/src/js_std/object.rs +++ b/crates/dash_vm/src/js_std/object.rs @@ -153,6 +153,27 @@ pub fn define_property(cx: CallContext) -> Result { Ok(Value::Object(object.clone())) } +pub fn define_properties(cx: CallContext) -> Result { + let object = match cx.args.first() { + Some(Value::Object(o)) => o.clone(), + _ => throw!( + cx.scope, + TypeError, + "Object.prototype.hasOwnProperty called on non-object" + ), + }; + + let properties = cx.args.get(1).unwrap_or_undefined(); + for key in properties.own_keys(cx.scope)? { + let key = key.to_js_string(cx.scope)?; + let descriptor = properties.get_property(cx.scope, key.into()).root(cx.scope)?; + let descriptor = PropertyValue::from_descriptor_value(cx.scope, descriptor)?; + object.set_property(cx.scope, key.into(), descriptor)?; + } + + Ok(Value::Object(object)) +} + pub fn assign(cx: CallContext) -> Result { let mut args = cx.args.into_iter(); let to = args.next().unwrap_or_undefined().to_object(cx.scope)?; diff --git a/crates/dash_vm/src/lib.rs b/crates/dash_vm/src/lib.rs index e93f064e..dc09ce31 100644 --- a/crates/dash_vm/src/lib.rs +++ b/crates/dash_vm/src/lib.rs @@ -240,6 +240,7 @@ impl Vm { (sym::getOwnPropertyDescriptor, scope.statics.object_get_own_property_descriptor.clone()), (sym::getOwnPropertyDescriptors, scope.statics.object_get_own_property_descriptors.clone()), (sym::defineProperty, scope.statics.object_define_property.clone()), + (sym::defineProperties, scope.statics.object_define_properties.clone()), (sym::entries, scope.statics.object_entries.clone()), (sym::assign, scope.statics.object_assign.clone()), (sym::getPrototypeOf, scope.statics.object_get_prototype_of.clone()), diff --git a/crates/dash_vm/src/statics.rs b/crates/dash_vm/src/statics.rs index 8484a637..17b43a63 100644 --- a/crates/dash_vm/src/statics.rs +++ b/crates/dash_vm/src/statics.rs @@ -78,6 +78,7 @@ pub struct Statics { pub object_get_own_property_descriptors: Handle, pub object_has_own_property: Handle, pub object_define_property: Handle, + pub object_define_properties: Handle, pub object_assign: Handle, pub object_entries: Handle, pub object_get_prototype_of: Handle, @@ -293,6 +294,7 @@ impl Statics { ), object_has_own_property: function(gc, sym::hasOwnProperty, js_std::object::has_own_property), object_define_property: function(gc, sym::defineProperty, js_std::object::define_property), + object_define_properties: function(gc, sym::defineProperties, js_std::object::define_properties), object_assign: function(gc, sym::assign, js_std::object::assign), object_entries: function(gc, sym::entries, js_std::object::entries), object_get_prototype_of: function(gc, sym::getPrototypeOf, js_std::object::get_prototype_of), diff --git a/crates/dash_vm/src/value/object.rs b/crates/dash_vm/src/value/object.rs index a5e4996f..ec4645a7 100755 --- a/crates/dash_vm/src/value/object.rs +++ b/crates/dash_vm/src/value/object.rs @@ -365,13 +365,13 @@ impl PropertyValue { let enumerable = value.get_property(sc, sym::enumerable.into()).root(sc)?.into_option(); let writable = value.get_property(sc, sym::writable.into()).root(sc)?.into_option(); - if configurable.map_or(true, |v| v.is_truthy(sc)) { + if configurable.is_some_and(|v| v.is_truthy(sc)) { flags |= PropertyDataDescriptor::CONFIGURABLE; } - if enumerable.map_or(true, |v| v.is_truthy(sc)) { + if enumerable.is_some_and(|v| v.is_truthy(sc)) { flags |= PropertyDataDescriptor::ENUMERABLE; } - if writable.map_or(true, |v| v.is_truthy(sc)) { + if writable.is_some_and(|v| v.is_truthy(sc)) { flags |= PropertyDataDescriptor::WRITABLE; }