[ES6] Use @isObject to check Object Type instead of using instanceof
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 17 Apr 2016 21:53:11 +0000 (21:53 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 17 Apr 2016 21:53:11 +0000 (21:53 +0000)
https://bugs.webkit.org/show_bug.cgi?id=156676

Reviewed by Darin Adler.

Use @isObject instead of `instanceof @Object`.
The `instanceof` check is not enough to check Object Type.
For example, given 2 realms, the object created in one realm does not inherit the Object of another realm.
Another example is that the object which does not inherit Object.
This object can be easily created by calling `Object.create(null)`.

* builtins/RegExpPrototype.js:
(match):
* jsc.cpp:
(GlobalObject::finishCreation):
(functionCreateGlobalObject):
* tests/stress/regexp-match-in-other-realm-should-work.js: Added.
(shouldBe):
* tests/stress/regexp-match-should-work-with-objects-not-inheriting-object-prototype.js: Added.
(shouldBe):
(regexp.exec):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@199647 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/builtins/RegExpPrototype.js
Source/JavaScriptCore/jsc.cpp
Source/JavaScriptCore/tests/stress/regexp-match-in-other-realm-should-work.js [new file with mode: 0644]
Source/JavaScriptCore/tests/stress/regexp-match-should-work-with-objects-not-inheriting-object-prototype.js [new file with mode: 0644]

index 9db911b..f2674c8 100644 (file)
@@ -1,3 +1,27 @@
+2016-04-17  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Use @isObject to check Object Type instead of using instanceof
+        https://bugs.webkit.org/show_bug.cgi?id=156676
+
+        Reviewed by Darin Adler.
+
+        Use @isObject instead of `instanceof @Object`.
+        The `instanceof` check is not enough to check Object Type.
+        For example, given 2 realms, the object created in one realm does not inherit the Object of another realm.
+        Another example is that the object which does not inherit Object.
+        This object can be easily created by calling `Object.create(null)`.
+
+        * builtins/RegExpPrototype.js:
+        (match):
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionCreateGlobalObject):
+        * tests/stress/regexp-match-in-other-realm-should-work.js: Added.
+        (shouldBe):
+        * tests/stress/regexp-match-should-work-with-objects-not-inheriting-object-prototype.js: Added.
+        (shouldBe):
+        (regexp.exec):
+
 2016-04-17  Darin Adler  <darin@apple.com>
 
         Remove more uses of Deprecated::ScriptXXX
index 1b6026b..a8df330 100644 (file)
@@ -47,7 +47,7 @@ function match(str)
 {
     "use strict";
 
-    if (!(this instanceof @Object))
+    if (!@isObject(this))
         throw new @TypeError("RegExp.prototype.@@match requires that |this| be an Object");
 
     let regexp = @Object(this);
index 0a3400a..69a7a7e 100644 (file)
@@ -555,6 +555,7 @@ static EncodedJSValue JSC_HOST_CALL functionCreateRuntimeArray(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionCreateImpureGetter(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionCreateCustomGetterObject(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionCreateBuiltin(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionCreateGlobalObject(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState*);
 
 static EncodedJSValue JSC_HOST_CALL functionSetElementRoot(ExecState*);
@@ -800,6 +801,7 @@ protected:
         addFunction(vm, "createImpureGetter", functionCreateImpureGetter, 1);
         addFunction(vm, "createCustomGetterObject", functionCreateCustomGetterObject, 0);
         addFunction(vm, "createBuiltin", functionCreateBuiltin, 2);
+        addFunction(vm, "createGlobalObject", functionCreateGlobalObject, 0);
         addFunction(vm, "setImpureGetterDelegate", functionSetImpureGetterDelegate, 2);
 
         addFunction(vm, "dumpTypesForAllVariables", functionDumpTypesForAllVariables , 0);
@@ -1776,6 +1778,12 @@ EncodedJSValue JSC_HOST_CALL functionCreateBuiltin(ExecState* exec)
     return JSValue::encode(func);
 }
 
+EncodedJSValue JSC_HOST_CALL functionCreateGlobalObject(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    return JSValue::encode(GlobalObject::create(vm, GlobalObject::createStructure(vm, jsNull()), Vector<String>()));
+}
+
 EncodedJSValue JSC_HOST_CALL functionCheckModuleSyntax(ExecState* exec)
 {
     String source = exec->argument(0).toString(exec)->value(exec);
diff --git a/Source/JavaScriptCore/tests/stress/regexp-match-in-other-realm-should-work.js b/Source/JavaScriptCore/tests/stress/regexp-match-in-other-realm-should-work.js
new file mode 100644 (file)
index 0000000..3a9c8e8
--- /dev/null
@@ -0,0 +1,10 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error(`bad value: ${String(actual)}`);
+}
+
+var regexp = /Hello/;
+var string = "Hello";
+var otherRealm = createGlobalObject();
+shouldBe(otherRealm.RegExp.prototype[Symbol.match].call(regexp, string)[0], string)
+
diff --git a/Source/JavaScriptCore/tests/stress/regexp-match-should-work-with-objects-not-inheriting-object-prototype.js b/Source/JavaScriptCore/tests/stress/regexp-match-should-work-with-objects-not-inheriting-object-prototype.js
new file mode 100644 (file)
index 0000000..a047623
--- /dev/null
@@ -0,0 +1,11 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error(`bad value: ${String(actual)}`);
+}
+var regexp = Object.create(null);
+regexp.reg = /Hello/;
+regexp.exec = function (value) {
+    return regexp.reg.exec(value);
+};
+var string = "Hello";
+shouldBe(RegExp.prototype[Symbol.match].call(regexp, string)[0], string)