summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGaming4JC <g4jc@hyperbola.info>2019-06-08 18:43:21 -0400
committerGaming4JC <g4jc@hyperbola.info>2019-07-18 22:38:21 -0400
commit2ea840b045e7db434d6960f72f5313b9621ffd03 (patch)
tree13c8f55ddcc44434bdd309d5979afb1a9865c5ef
parent0bc46526909e579acf7f7dc5c59668fd79662437 (diff)
downloaduxp-2ea840b045e7db434d6960f72f5313b9621ffd03.tar.gz
1175823 - Implement [[DefineOwnProperty]] for mapped arguments object.
-rw-r--r--js/src/jsobj.cpp2
-rw-r--r--js/src/vm/ArgumentsObject.cpp68
-rw-r--r--js/src/vm/ArgumentsObject.h3
3 files changed, 71 insertions, 2 deletions
diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp
index 5f6331ac88..bea01daf40 100644
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -471,7 +471,7 @@ js::SetIntegrityLevel(JSContext* cx, HandleObject obj, IntegrityLevel level)
// Steps 8-9, loosely interpreted.
if (obj->isNative() && !obj->as<NativeObject>().inDictionaryMode() &&
- !obj->is<TypedArrayObject>())
+ !obj->is<TypedArrayObject>() && !obj->is<MappedArgumentsObject>())
{
HandleNativeObject nobj = obj.as<NativeObject>();
diff --git a/js/src/vm/ArgumentsObject.cpp b/js/src/vm/ArgumentsObject.cpp
index 717aa10508..f9a939e6e8 100644
--- a/js/src/vm/ArgumentsObject.cpp
+++ b/js/src/vm/ArgumentsObject.cpp
@@ -590,6 +590,64 @@ MappedArgumentsObject::obj_enumerate(JSContext* cx, HandleObject obj)
return true;
}
+// ES 2017 draft 9.4.4.2
+/* static */ bool
+MappedArgumentsObject::obj_defineProperty(JSContext* cx, HandleObject obj, HandleId id,
+ Handle<PropertyDescriptor> desc, ObjectOpResult& result)
+{
+ // Step 1.
+ Rooted<MappedArgumentsObject*> argsobj(cx, &obj->as<MappedArgumentsObject>());
+
+ // Steps 2-3.
+ bool isMapped = false;
+ if (JSID_IS_INT(id)) {
+ unsigned arg = unsigned(JSID_TO_INT(id));
+ isMapped = arg < argsobj->initialLength() && !argsobj->isElementDeleted(arg);
+ }
+
+ // Step 4.
+ Rooted<PropertyDescriptor> newArgDesc(cx, desc);
+ if (!desc.isAccessorDescriptor() && isMapped) {
+ // In this case the live mapping is supposed to keep working,
+ // we have to pass along the Getter/Setter otherwise they are overwritten.
+ newArgDesc.setGetter(MappedArgGetter);
+ newArgDesc.setSetter(MappedArgSetter);
+ }
+
+ // Steps 5-6. NativeDefineProperty will lookup [[Value]] for us.
+ if (!NativeDefineProperty(cx, obj.as<NativeObject>(), id, newArgDesc, result))
+ return false;
+ // Step 7.
+ if (!result.ok())
+ return true;
+
+ // Step 8.
+ if (isMapped) {
+ unsigned arg = unsigned(JSID_TO_INT(id));
+ if (desc.isAccessorDescriptor()) {
+ if (!argsobj->markElementDeleted(cx, arg))
+ return false;
+ } else {
+ if (desc.hasValue()) {
+ RootedFunction callee(cx, &argsobj->callee());
+ RootedScript script(cx, callee->getOrCreateScript(cx));
+ if (!script)
+ return false;
+ argsobj->setElement(cx, arg, desc.value());
+ if (arg < script->functionNonDelazifying()->nargs())
+ TypeScript::SetArgument(cx, script, arg, desc.value());
+ }
+ if (desc.hasWritable() && !desc.writable()) {
+ if (!argsobj->markElementDeleted(cx, arg))
+ return false;
+ }
+ }
+ }
+
+ // Step 9.
+ return result.succeed();
+}
+
static bool
UnmappedArgGetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp)
{
@@ -804,6 +862,11 @@ const ClassOps MappedArgumentsObject::classOps_ = {
ArgumentsObject::trace
};
+const ObjectOps MappedArgumentsObject::objectOps_ = {
+ nullptr, /* lookupProperty */
+ MappedArgumentsObject::obj_defineProperty
+};
+
const Class MappedArgumentsObject::class_ = {
"Arguments",
JSCLASS_DELAY_METADATA_BUILDER |
@@ -811,7 +874,10 @@ const Class MappedArgumentsObject::class_ = {
JSCLASS_HAS_CACHED_PROTO(JSProto_Object) |
JSCLASS_SKIP_NURSERY_FINALIZE |
JSCLASS_BACKGROUND_FINALIZE,
- &MappedArgumentsObject::classOps_
+ &MappedArgumentsObject::classOps_,
+ nullptr,
+ nullptr,
+ &MappedArgumentsObject::objectOps_
};
/*
diff --git a/js/src/vm/ArgumentsObject.h b/js/src/vm/ArgumentsObject.h
index 247c7cd943..988e41951b 100644
--- a/js/src/vm/ArgumentsObject.h
+++ b/js/src/vm/ArgumentsObject.h
@@ -389,6 +389,7 @@ class ArgumentsObject : public NativeObject
class MappedArgumentsObject : public ArgumentsObject
{
static const ClassOps classOps_;
+ static const ObjectOps objectOps_;
public:
static const Class class_;
@@ -410,6 +411,8 @@ class MappedArgumentsObject : public ArgumentsObject
private:
static bool obj_enumerate(JSContext* cx, HandleObject obj);
static bool obj_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp);
+ static bool obj_defineProperty(JSContext* cx, HandleObject obj, HandleId id,
+ Handle<JS::PropertyDescriptor> desc, ObjectOpResult& result);
};
class UnmappedArgumentsObject : public ArgumentsObject