From 8ebfb027c0d0a0382559ea62ecfff18e1aa2674f Mon Sep 17 00:00:00 2001 From: Skyler Lipthay Date: Wed, 1 Jul 2020 15:27:07 -0600 Subject: [PATCH] Add 'Object::has(_index)' and 'Object::delete(_index)' (#412) --- src/binding.cc | 24 +++++++++++++++++ src/object.rs | 68 +++++++++++++++++++++++++++++++++++++++++++++++ tests/test_api.rs | 10 +++++++ 3 files changed, 102 insertions(+) diff --git a/src/binding.cc b/src/binding.cc index 085c07ce..ede648d4 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -752,6 +752,30 @@ const v8::Array* v8__Object__GetPropertyNames(const v8::Object* self, ptr_to_local(self)->GetPropertyNames(ptr_to_local(context))); } +MaybeBool v8__Object__Has(const v8::Object& self, const v8::Context& context, + const v8::Value& key) { + return maybe_to_maybe_bool( + ptr_to_local(&self)->Has(ptr_to_local(&context), ptr_to_local(&key))); +} + +MaybeBool v8__Object__HasIndex(const v8::Object& self, + const v8::Context& context, uint32_t index) { + return maybe_to_maybe_bool( + ptr_to_local(&self)->Has(ptr_to_local(&context), index)); +} + +MaybeBool v8__Object__Delete(const v8::Object& self, const v8::Context& context, + const v8::Value& key) { + return maybe_to_maybe_bool( + ptr_to_local(&self)->Delete(ptr_to_local(&context), ptr_to_local(&key))); +} + +MaybeBool v8__Object__DeleteIndex(const v8::Object& self, + const v8::Context& context, uint32_t index) { + return maybe_to_maybe_bool( + ptr_to_local(&self)->Delete(ptr_to_local(&context), index)); +} + const v8::Array* v8__Array__New(v8::Isolate* isolate, int length) { return local_to_ptr(v8::Array::New(isolate, length)); } diff --git a/src/object.rs b/src/object.rs index 1d386db2..68631e6c 100644 --- a/src/object.rs +++ b/src/object.rs @@ -79,6 +79,26 @@ extern "C" { this: *const Object, context: *const Context, ) -> *const Array; + fn v8__Object__Has( + this: *const Object, + context: *const Context, + key: *const Value, + ) -> MaybeBool; + fn v8__Object__HasIndex( + this: *const Object, + context: *const Context, + index: u32, + ) -> MaybeBool; + fn v8__Object__Delete( + this: *const Object, + context: *const Context, + key: *const Value, + ) -> MaybeBool; + fn v8__Object__DeleteIndex( + this: *const Object, + context: *const Context, + index: u32, + ) -> MaybeBool; fn v8__Array__New(isolate: *mut Isolate, length: int) -> *const Array; fn v8__Array__New_with_elements( @@ -311,6 +331,54 @@ impl Object { }) } } + + // Calls the abstract operation HasProperty(O, P) described in ECMA-262, + // 7.3.10. Returns true, if the object has the property, either own or on the + // prototype chain. Interceptors, i.e., PropertyQueryCallbacks, are called if + // present. + // + // This function has the same side effects as JavaScript's variable in object. + // For example, calling this on a revoked proxy will throw an exception. + // + // Note: This function converts the key to a name, which possibly calls back + // into JavaScript. + pub fn has<'s>( + &self, + scope: &mut HandleScope<'s>, + key: Local, + ) -> Option { + unsafe { v8__Object__Has(self, &*scope.get_current_context(), &*key) } + .into() + } + + pub fn has_index<'s>( + &self, + scope: &mut HandleScope<'s>, + index: u32, + ) -> Option { + unsafe { v8__Object__HasIndex(self, &*scope.get_current_context(), index) } + .into() + } + + pub fn delete<'s>( + &self, + scope: &mut HandleScope<'s>, + key: Local, + ) -> Option { + unsafe { v8__Object__Delete(self, &*scope.get_current_context(), &*key) } + .into() + } + + pub fn delete_index<'s>( + &self, + scope: &mut HandleScope<'s>, + index: u32, + ) -> Option { + unsafe { + v8__Object__DeleteIndex(self, &*scope.get_current_context(), index) + } + .into() + } } impl Array { diff --git a/tests/test_api.rs b/tests/test_api.rs index 62613a97..0df76c66 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -1190,6 +1190,12 @@ fn object() { assert!(!object_.is_null_or_undefined()); let id = object_.get_identity_hash(); assert_ne!(id, 0); + + assert!(object.has(scope, n1.into()).unwrap()); + let n_unused = v8::String::new(scope, "unused").unwrap().into(); + assert!(!object.has(scope, n_unused).unwrap()); + assert!(object.delete(scope, n1.into()).unwrap()); + assert!(!object.has(scope, n1.into()).unwrap()); } } @@ -1230,6 +1236,10 @@ fn array() { let maybe_v2 = array.get_index(scope, 1); assert!(maybe_v2.is_some()); assert!(maybe_v2.unwrap().same_value(s2.into())); + + assert!(array.has_index(scope, 1).unwrap()); + assert!(array.delete_index(scope, 1).unwrap()); + assert!(!array.has_index(scope, 1).unwrap()); } }