InternalFunction::createSubclassStructure should use newTarget's globalObject
authorshvaikalesh@gmail.com <shvaikalesh@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 26 Apr 2020 21:30:38 +0000 (21:30 +0000)
committershvaikalesh@gmail.com <shvaikalesh@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 26 Apr 2020 21:30:38 +0000 (21:30 +0000)
https://bugs.webkit.org/show_bug.cgi?id=202599

Reviewed by Yusuke Suzuki.

JSTests:

* stress/promise-proto-from-ctor-realm.js: Added.
* test262/expectations.yaml: Mark 88 test cases as passing.

LayoutTests/imported/w3c:

* web-platform-tests/WebIDL/ecmascript-binding/constructors-expected.txt:
* web-platform-tests/custom-elements/htmlconstructor/newtarget-expected.txt:
* web-platform-tests/wasm/jsapi/proto-from-ctor-realm-expected.txt:

Source/JavaScriptCore:

If "prototype" of NewTarget is not an object, built-in constructors [1] should acquire
default [[Prototype]] from realm of NewTarget, utilizing GetFunctionRealm helper [2].
Before this change, realm of active constructor was used instead. This patch introduces
GetFunctionRealm and aligns all subclassable constructors with the spec, V8, and SpiderMonkey.

This change inlines fast paths checks of InternalFunction::createSubclassStructure() and
simplifies its signature; getFunctionRealm() is invoked in slow paths only.

While a dynamically created function uses NewTarget's realm for its default [[Prototype]]
similar to other built-ins, its "prototype" object inherit from ObjectPrototype
of active constructor's realm [3] (just like their scope), making it retain references
to 2 different global objects. To accomodate this behavior, this change introduces
`scopeGlobalObject` in JSFunction.cpp methods.

Above-mentioned behavior also simplifies creation of JSGenerator and JSAsyncGenerator
instances since NewTarget's realm is irrelevant to them.

IntlCollatorConstructor::collatorStructure() and 6 similar methods are removed:
a) to impose good practice of using newTarget's globalObject;
b) with this change, each of them have 1 call site max;
c) other JSC constructors have no methods alike.

[1]: https://tc39.es/ecma262/#sec-map-constructor (step 2)
[2]: https://tc39.es/ecma262/#sec-getfunctionrealm
[3]: https://tc39.es/ecma262/#sec-createdynamicfunction (steps 23-25)

* dfg/DFGOperations.cpp:
* runtime/AggregateErrorConstructor.cpp:
(JSC::callAggregateErrorConstructor):
(JSC::constructAggregateErrorConstructor):
* runtime/AggregateErrorConstructor.h:
* runtime/AsyncFunctionConstructor.cpp:
(JSC::constructAsyncFunctionConstructor):
* runtime/AsyncGeneratorFunctionConstructor.cpp:
(JSC::constructAsyncGeneratorFunctionConstructor):
* runtime/BooleanConstructor.cpp:
(JSC::constructWithBooleanConstructor):
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
(JSC::createInternalFieldObject):
* runtime/DateConstructor.cpp:
(JSC::constructDate):
* runtime/ErrorConstructor.cpp:
(JSC::constructErrorConstructor):
* runtime/FunctionConstructor.cpp:
(JSC::constructFunctionSkippingEvalEnabledCheck):
* runtime/InternalFunction.cpp:
(JSC::InternalFunction::createSubclassStructure):
(JSC::getFunctionRealm):
(JSC::InternalFunction::createSubclassStructureSlow): Deleted.
* runtime/InternalFunction.h:
(JSC::InternalFunction::createSubclassStructure): Deleted.
* runtime/IntlCollatorConstructor.cpp:
(JSC::constructIntlCollator):
(JSC::callIntlCollator):
* runtime/IntlCollatorConstructor.h:
* runtime/IntlDateTimeFormatConstructor.cpp:
(JSC::constructIntlDateTimeFormat):
(JSC::callIntlDateTimeFormat):
* runtime/IntlDateTimeFormatConstructor.h:
* runtime/IntlNumberFormatConstructor.cpp:
(JSC::constructIntlNumberFormat):
(JSC::callIntlNumberFormat):
* runtime/IntlNumberFormatConstructor.h:
* runtime/IntlPluralRulesConstructor.cpp:
(JSC::constructIntlPluralRules):
* runtime/IntlPluralRulesConstructor.h:
* runtime/IntlRelativeTimeFormatConstructor.cpp:
(JSC::constructIntlRelativeTimeFormat):
* runtime/IntlRelativeTimeFormatConstructor.h:
* runtime/JSArrayBufferConstructor.cpp:
(JSC::JSGenericArrayBufferConstructor<sharingMode>::constructArrayBuffer):
* runtime/JSFunction.cpp:
(JSC::JSFunction::prototypeForConstruction):
(JSC::JSFunction::getOwnPropertySlot):
* runtime/JSGenericTypedArrayViewConstructorInlines.h:
(JSC::constructGenericTypedArrayView):
* runtime/JSGlobalObjectInlines.h:
(JSC::JSGlobalObject::arrayStructureForIndexingTypeDuringAllocation const):
* runtime/MapConstructor.cpp:
(JSC::constructMap):
* runtime/NativeErrorConstructor.cpp:
(JSC::NativeErrorConstructor<errorType>::constructNativeErrorConstructor):
(JSC::NativeErrorConstructor<errorType>::callNativeErrorConstructor):
* runtime/NativeErrorConstructor.h:
* runtime/NumberConstructor.cpp:
(JSC::constructNumberConstructor):
* runtime/ObjectConstructor.cpp:
(JSC::constructObjectWithNewTarget):
* runtime/RegExpConstructor.cpp:
(JSC::getRegExpStructure):
(JSC::constructRegExp):
(JSC::esSpecRegExpCreate):
* runtime/RegExpConstructor.h:
* runtime/SetConstructor.cpp:
(JSC::constructSet):
* runtime/StringConstructor.cpp:
(JSC::constructWithStringConstructor):
* runtime/WeakMapConstructor.cpp:
(JSC::constructWeakMap):
* runtime/WeakObjectRefConstructor.cpp:
(JSC::constructWeakRef):
* runtime/WeakSetConstructor.cpp:
(JSC::constructWeakSet):
* wasm/js/WebAssemblyCompileErrorConstructor.cpp:
(JSC::constructJSWebAssemblyCompileError):
* wasm/js/WebAssemblyInstanceConstructor.cpp:
(JSC::constructJSWebAssemblyInstance):
* wasm/js/WebAssemblyLinkErrorConstructor.cpp:
(JSC::constructJSWebAssemblyLinkError):
* wasm/js/WebAssemblyModuleConstructor.cpp:
(JSC::WebAssemblyModuleConstructor::createModule):
* wasm/js/WebAssemblyRuntimeErrorConstructor.cpp:
(JSC::constructJSWebAssemblyRuntimeError):

Source/WebCore:

Accounts for InternalFunction::createSubclassStructure() signature change and
utilizes getFunctionRealm() helper to handle cross-realm JSBoundFunction and
ProxyObject instances as NewTarget value.

Tests: web-platform-tests/WebIDL/ecmascript-binding/constructors.html
       web-platform-tests/custom-elements/htmlconstructor/newtarget.html

* bindings/js/JSDOMWrapperCache.h:
(WebCore::setSubclassStructureIfNeeded):
* bindings/js/JSHTMLElementCustom.cpp:
(WebCore::constructJSHTMLElement):

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

54 files changed:
JSTests/ChangeLog
JSTests/stress/promise-proto-from-ctor-realm.js [new file with mode: 0644]
JSTests/test262/expectations.yaml
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/constructors-expected.txt
LayoutTests/imported/w3c/web-platform-tests/custom-elements/htmlconstructor/newtarget-expected.txt
LayoutTests/imported/w3c/web-platform-tests/wasm/jsapi/proto-from-ctor-realm-expected.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGOperations.cpp
Source/JavaScriptCore/runtime/AggregateErrorConstructor.cpp
Source/JavaScriptCore/runtime/AggregateErrorConstructor.h
Source/JavaScriptCore/runtime/AsyncFunctionConstructor.cpp
Source/JavaScriptCore/runtime/AsyncGeneratorFunctionConstructor.cpp
Source/JavaScriptCore/runtime/BooleanConstructor.cpp
Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
Source/JavaScriptCore/runtime/DateConstructor.cpp
Source/JavaScriptCore/runtime/ErrorConstructor.cpp
Source/JavaScriptCore/runtime/FunctionConstructor.cpp
Source/JavaScriptCore/runtime/InternalFunction.cpp
Source/JavaScriptCore/runtime/InternalFunction.h
Source/JavaScriptCore/runtime/IntlCollatorConstructor.cpp
Source/JavaScriptCore/runtime/IntlCollatorConstructor.h
Source/JavaScriptCore/runtime/IntlDateTimeFormatConstructor.cpp
Source/JavaScriptCore/runtime/IntlDateTimeFormatConstructor.h
Source/JavaScriptCore/runtime/IntlNumberFormatConstructor.cpp
Source/JavaScriptCore/runtime/IntlNumberFormatConstructor.h
Source/JavaScriptCore/runtime/IntlPluralRulesConstructor.cpp
Source/JavaScriptCore/runtime/IntlPluralRulesConstructor.h
Source/JavaScriptCore/runtime/IntlRelativeTimeFormatConstructor.cpp
Source/JavaScriptCore/runtime/IntlRelativeTimeFormatConstructor.h
Source/JavaScriptCore/runtime/JSArrayBufferConstructor.cpp
Source/JavaScriptCore/runtime/JSFunction.cpp
Source/JavaScriptCore/runtime/JSGenericTypedArrayViewConstructorInlines.h
Source/JavaScriptCore/runtime/JSGlobalObjectInlines.h
Source/JavaScriptCore/runtime/MapConstructor.cpp
Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
Source/JavaScriptCore/runtime/NativeErrorConstructor.h
Source/JavaScriptCore/runtime/NumberConstructor.cpp
Source/JavaScriptCore/runtime/ObjectConstructor.cpp
Source/JavaScriptCore/runtime/RegExpConstructor.cpp
Source/JavaScriptCore/runtime/RegExpConstructor.h
Source/JavaScriptCore/runtime/SetConstructor.cpp
Source/JavaScriptCore/runtime/StringConstructor.cpp
Source/JavaScriptCore/runtime/WeakMapConstructor.cpp
Source/JavaScriptCore/runtime/WeakObjectRefConstructor.cpp
Source/JavaScriptCore/runtime/WeakSetConstructor.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyCompileErrorConstructor.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyLinkErrorConstructor.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyRuntimeErrorConstructor.cpp
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSDOMWrapperCache.h
Source/WebCore/bindings/js/JSHTMLElementCustom.cpp

index cd74b5a..8bcb2b9 100644 (file)
@@ -1,3 +1,13 @@
+2020-04-26  Alexey Shvayka  <shvaikalesh@gmail.com>
+
+        InternalFunction::createSubclassStructure should use newTarget's globalObject
+        https://bugs.webkit.org/show_bug.cgi?id=202599
+
+        Reviewed by Yusuke Suzuki.
+
+        * stress/promise-proto-from-ctor-realm.js: Added.
+        * test262/expectations.yaml: Mark 88 test cases as passing.
+
 2020-04-26  Yusuke Suzuki  <ysuzuki@apple.com>
 
         [JSC] ValueAdd, VaueSub, ValueMul, Inc, Dec should say SpecBigInt32 prediction based on ArithProfile
diff --git a/JSTests/stress/promise-proto-from-ctor-realm.js b/JSTests/stress/promise-proto-from-ctor-realm.js
new file mode 100644 (file)
index 0000000..b9e26b2
--- /dev/null
@@ -0,0 +1,16 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+const realmA = createGlobalObject();
+const realmB = createGlobalObject();
+
+const executor = function() {};
+const newTarget = new realmA.Function();
+newTarget.prototype = null;
+
+for (let i = 0; i < 1e4; ++i) {
+    let promise = Reflect.construct(realmB.Promise, [executor], newTarget);
+    shouldBe(Object.getPrototypeOf(promise), realmA.Promise.prototype);
+}
index e9d814a..6418830 100644 (file)
@@ -633,15 +633,6 @@ test/annexB/language/statements/for-of/iterator-close-return-emulates-undefined-
 test/annexB/language/statements/function/default-parameters-emulates-undefined.js:
   default: 'Test262Error: Expected SameValue(«undefined», «[object Function]») to be true'
   strict mode: 'Test262Error: Expected SameValue(«undefined», «[object Function]») to be true'
-test/built-ins/Array/proto-from-ctor-realm-one.js:
-  default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«», «») to be true'
-  strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«», «») to be true'
-test/built-ins/Array/proto-from-ctor-realm-two.js:
-  default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«», «») to be true'
-  strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«», «») to be true'
-test/built-ins/Array/proto-from-ctor-realm-zero.js:
-  default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«», «») to be true'
-  strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«», «») to be true'
 test/built-ins/Array/prototype/concat/arg-length-exceeding-integer-limit.js:
   default: 'Test262Error: Expected a TypeError but got a RangeError'
   strict mode: 'Test262Error: Expected a TypeError but got a RangeError'
@@ -708,9 +699,6 @@ test/built-ins/Array/prototype/splice/throws-if-integer-limit-exceeded.js:
 test/built-ins/Array/prototype/unshift/clamps-to-integer-limit.js:
   default: 'Test262Error: Length is 2**53 - 1 Expected SameValue(«4294967295», «9007199254740991») to be true'
   strict mode: 'Test262Error: Length is 2**53 - 1 Expected SameValue(«4294967295», «9007199254740991») to be true'
-test/built-ins/ArrayBuffer/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«[object ArrayBuffer]», «[object ArrayBuffer]») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«[object ArrayBuffer]», «[object ArrayBuffer]») to be true'
 test/built-ins/ArrayBuffer/prototype/byteLength/detached-buffer.js:
   default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
   strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
@@ -747,12 +735,6 @@ test/built-ins/AsyncFromSyncIteratorPrototype/next/absent-value-not-passed.js:
 test/built-ins/AsyncFromSyncIteratorPrototype/return/absent-value-not-passed.js:
   default: 'Test262:AsyncTestFailure:Test262Error: Test262Error: Expected SameValue(«1», «0») to be true'
   strict mode: 'Test262:AsyncTestFailure:Test262Error: Test262Error: Expected SameValue(«1», «0») to be true'
-test/built-ins/AsyncFunction/proto-from-ctor-realm.js:
-  default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object AsyncFunction]», «[object AsyncFunction]») to be true'
-  strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object AsyncFunction]», «[object AsyncFunction]») to be true'
-test/built-ins/AsyncGeneratorFunction/proto-from-ctor-realm.js:
-  default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object AsyncGeneratorFunction]», «[object AsyncGeneratorFunction]») to be true'
-  strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object AsyncGeneratorFunction]», «[object AsyncGeneratorFunction]») to be true'
 test/built-ins/AsyncGeneratorPrototype/return/return-suspendedYield-promise.js:
   default: 'Test262:AsyncTestFailure:Test262Error: Test262Error: AsyncGeneratorResolve(generator, resultValue, true) Expected SameValue(«[object Promise]», «unwrapped-value») to be true'
   strict mode: 'Test262:AsyncTestFailure:Test262Error: Test262Error: AsyncGeneratorResolve(generator, resultValue, true) Expected SameValue(«[object Promise]», «unwrapped-value») to be true'
@@ -816,9 +798,6 @@ test/built-ins/BigInt/asUintN/bits-toindex.js:
 test/built-ins/BigInt/asUintN/order-of-steps.js:
   default: 'Test262Error: Expected SameValue(«0», «2») to be true'
   strict mode: 'Test262Error: Expected SameValue(«0», «2») to be true'
-test/built-ins/Boolean/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«false», «false») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«false», «false») to be true'
 test/built-ins/DataView/custom-proto-access-detaches-buffer.js:
   default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
   strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
@@ -828,9 +807,6 @@ test/built-ins/DataView/detached-buffer.js:
 test/built-ins/DataView/length.js:
   default: 'Test262Error: descriptor value should be 1'
   strict mode: 'Test262Error: descriptor value should be 1'
-test/built-ins/DataView/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«[object DataView]», «[object DataView]») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«[object DataView]», «[object DataView]») to be true'
 test/built-ins/DataView/prototype/byteLength/detached-buffer.js:
   default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
   strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
@@ -933,18 +909,6 @@ test/built-ins/DataView/prototype/setUint8/detached-buffer-before-outofrange-byt
 test/built-ins/DataView/prototype/setUint8/detached-buffer.js:
   default: 'Test262Error: Expected a TypeError but got a RangeError'
   strict mode: 'Test262Error: Expected a TypeError but got a RangeError'
-test/built-ins/Date/proto-from-ctor-realm-one.js:
-  default: 'Test262Error: Expected SameValue(«[object Object]», «[object Object]») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«[object Object]», «[object Object]») to be true'
-test/built-ins/Date/proto-from-ctor-realm-two.js:
-  default: 'Test262Error: Expected SameValue(«[object Object]», «[object Object]») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«[object Object]», «[object Object]») to be true'
-test/built-ins/Date/proto-from-ctor-realm-zero.js:
-  default: 'Test262Error: Expected SameValue(«[object Object]», «[object Object]») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«[object Object]», «[object Object]») to be true'
-test/built-ins/Error/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«Error», «Error») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«Error», «Error») to be true'
 test/built-ins/Function/call-bind-this-realm-undef.js:
   default: 'Test262Error: implicit undefined Expected SameValue(«[object global]», «[object Undefined]») to be true'
   strict mode: 'Test262Error: implicit undefined Expected SameValue(«[object global]», «[object Undefined]») to be true'
@@ -963,15 +927,6 @@ test/built-ins/Function/internals/Construct/derived-return-val-realm.js:
 test/built-ins/Function/internals/Construct/derived-this-uninitialized-realm.js:
   default: 'Test262Error: Expected a ReferenceError but got a ReferenceError'
   strict mode: 'Test262Error: Expected a ReferenceError but got a ReferenceError'
-test/built-ins/Function/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«function () {'
-  strict mode: 'Test262Error: Expected SameValue(«function () {'
-test/built-ins/Function/prototype/bind/get-fn-realm-recursive.js:
-  default: 'Test262Error: Expected true but got false'
-  strict mode: 'Test262Error: Expected true but got false'
-test/built-ins/Function/prototype/bind/get-fn-realm.js:
-  default: 'Test262Error: Expected true but got false'
-  strict mode: 'Test262Error: Expected true but got false'
 test/built-ins/Function/prototype/bind/length-exceeds-int32.js:
   default: 'Test262Error: Expected SameValue(«0», «2147483648») to be true'
   strict mode: 'Test262Error: Expected SameValue(«0», «2147483648») to be true'
@@ -1110,39 +1065,12 @@ test/built-ins/Function/prototype/toString/setter-object.js:
 test/built-ins/Function/prototype/toString/unicode.js:
   default: "Test262Error: Conforms to NativeFunction Syntax: 'function a(\\u{62}, \\u0063) { \\u0062 = \\u{00063}; return b; }'.(function \\u0061(\\u{62}, \\u0063) { \\u0062 = \\u{00063}; return b; })"
   strict mode: "Test262Error: Conforms to NativeFunction Syntax: 'function a(\\u{62}, \\u0063) { \\u0062 = \\u{00063}; return b; }'.(function \\u0061(\\u{62}, \\u0063) { \\u0062 = \\u{00063}; return b; })"
-test/built-ins/GeneratorFunction/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«[object GeneratorFunction]», «[object GeneratorFunction]») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«[object GeneratorFunction]», «[object GeneratorFunction]») to be true'
 test/built-ins/JSON/parse/reviver-object-non-configurable-prop-create.js:
   default: 'Test262Error: Expected SameValue(«22», «2») to be true'
   strict mode: 'Test262Error: Expected SameValue(«22», «2») to be true'
-test/built-ins/Map/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«[object Map]», «[object Map]») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«[object Map]», «[object Map]») to be true'
-test/built-ins/NativeErrors/EvalError/proto-from-ctor-realm.js:
-  default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«EvalError», «EvalError») to be true'
-  strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«EvalError», «EvalError») to be true'
-test/built-ins/NativeErrors/RangeError/proto-from-ctor-realm.js:
-  default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«RangeError», «RangeError») to be true'
-  strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«RangeError», «RangeError») to be true'
-test/built-ins/NativeErrors/ReferenceError/proto-from-ctor-realm.js:
-  default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«ReferenceError», «ReferenceError») to be true'
-  strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«ReferenceError», «ReferenceError») to be true'
-test/built-ins/NativeErrors/SyntaxError/proto-from-ctor-realm.js:
-  default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«SyntaxError», «SyntaxError») to be true'
-  strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«SyntaxError», «SyntaxError») to be true'
-test/built-ins/NativeErrors/TypeError/proto-from-ctor-realm.js:
-  default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«TypeError», «TypeError») to be true'
-  strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«TypeError», «TypeError») to be true'
-test/built-ins/NativeErrors/URIError/proto-from-ctor-realm.js:
-  default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«URIError», «URIError») to be true'
-  strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«URIError», «URIError») to be true'
 test/built-ins/Number/bigint-conversion.js:
   default: "TypeError: Conversion from 'BigInt' to 'number' is not allowed."
   strict mode: "TypeError: Conversion from 'BigInt' to 'number' is not allowed."
-test/built-ins/Number/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«0», «0») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«0», «0») to be true'
 test/built-ins/Object/entries/order-after-define-property.js:
   default: 'Test262Error: Expected [b, a] and [a, b] to have the same contents. '
   strict mode: 'Test262Error: Expected [b, a] and [a, b] to have the same contents. '
@@ -1165,9 +1093,6 @@ test/built-ins/Object/internals/DefineOwnProperty/consistent-value-regexp-dollar
 test/built-ins/Object/keys/order-after-define-property.js:
   default: 'Test262Error: Expected [b, a] and [a, b] to have the same contents. '
   strict mode: 'Test262Error: Expected [b, a] and [a, b] to have the same contents. '
-test/built-ins/Object/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«[object Object]», «[object Object]») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«[object Object]», «[object Object]») to be true'
 test/built-ins/Object/prototype/toString/proxy-function.js:
   default: 'Test262Error: function proxy Expected SameValue(«[object Object]», «[object Function]») to be true'
   strict mode: 'Test262Error: function proxy Expected SameValue(«[object Object]», «[object Function]») to be true'
@@ -1198,9 +1123,6 @@ test/built-ins/Promise/create-resolving-functions-resolve.js:
 test/built-ins/Promise/executor-function-nonconstructor.js:
   default: 'Test262Error: Expected SameValue(«true», «false») to be true'
   strict mode: 'Test262Error: Expected SameValue(«true», «false») to be true'
-test/built-ins/Promise/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«[object Promise]», «[object Promise]») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«[object Promise]», «[object Promise]») to be true'
 test/built-ins/Promise/prototype/finally/invokes-then-with-function.js:
   default: 'Test262Error: fulfillment handler is not constructor'
   strict mode: 'Test262Error: fulfillment handler is not constructor'
@@ -1252,12 +1174,6 @@ test/built-ins/Proxy/construct/return-not-object-throws-undefined-realm.js:
 test/built-ins/Proxy/construct/trap-is-not-callable-realm.js:
   default: 'Test262Error: Expected a TypeError but got a TypeError'
   strict mode: 'Test262Error: Expected a TypeError but got a TypeError'
-test/built-ins/Proxy/get-fn-realm-recursive.js:
-  default: 'Test262Error: Expected true but got false'
-  strict mode: 'Test262Error: Expected true but got false'
-test/built-ins/Proxy/get-fn-realm.js:
-  default: 'Test262Error: Expected true but got false'
-  strict mode: 'Test262Error: Expected true but got false'
 test/built-ins/Proxy/ownKeys/trap-is-undefined-target-is-proxy.js:
   default: 'Test262Error: Expected [length, foo, 0, Symbol()] and [Symbol(), length, foo, 0] to have the same contents. '
   strict mode: 'Test262Error: Expected [length, foo, 0, Symbol()] and [Symbol(), length, foo, 0] to have the same contents. '
@@ -1657,9 +1573,6 @@ test/built-ins/RegExp/property-escapes/generated/XID_Continue.js:
 test/built-ins/RegExp/property-escapes/generated/XID_Start.js:
   default: 'Test262Error: `\p{XID_Start}` should match U+001CFA (`ᳺ`)'
   strict mode: 'Test262Error: `\p{XID_Start}` should match U+001CFA (`ᳺ`)'
-test/built-ins/RegExp/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«/(?:)/», «/(?:)/») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«/(?:)/», «/(?:)/») to be true'
 test/built-ins/RegExp/prototype/Symbol.match/builtin-infer-unicode.js:
   default: 'Test262Error: Expected SameValue(«�», «null») to be true'
   strict mode: 'Test262Error: Expected SameValue(«�», «null») to be true'
@@ -1696,12 +1609,6 @@ test/built-ins/RegExp/prototype/unicode/cross-realm.js:
 test/built-ins/RegExp/quantifier-integer-limit.js:
   default: 'SyntaxError: Invalid regular expression: number too large in {} quantifier'
   strict mode: 'SyntaxError: Invalid regular expression: number too large in {} quantifier'
-test/built-ins/Set/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«[object Set]», «[object Set]») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«[object Set]», «[object Set]») to be true'
-test/built-ins/String/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«», «») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«», «») to be true'
 test/built-ins/String/prototype/replace/cstm-replace-is-null.js:
   default: 'TypeError: null is not a function'
   strict mode: 'TypeError: null is not a function'
@@ -1776,21 +1683,9 @@ test/built-ins/TypedArrayConstructors/ctors/buffer-arg/detachedbuffer.js:
 test/built-ins/TypedArrayConstructors/ctors/buffer-arg/length-to-number-detachbuffer.js:
   default: 'Test262Error: Expected a TypeError but got a RangeError (Testing with Float64Array.)'
   strict mode: 'Test262Error: Expected a TypeError but got a RangeError (Testing with Float64Array.)'
-test/built-ins/TypedArrayConstructors/ctors/buffer-arg/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«[object Float64ArrayPrototype]», «[object Float64ArrayPrototype]») to be true (Testing with Float64Array.)'
-  strict mode: 'Test262Error: Expected SameValue(«[object Float64ArrayPrototype]», «[object Float64ArrayPrototype]») to be true (Testing with Float64Array.)'
-test/built-ins/TypedArrayConstructors/ctors/length-arg/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«[object Float64ArrayPrototype]», «[object Float64ArrayPrototype]») to be true (Testing with Float64Array.)'
-  strict mode: 'Test262Error: Expected SameValue(«[object Float64ArrayPrototype]», «[object Float64ArrayPrototype]») to be true (Testing with Float64Array.)'
-test/built-ins/TypedArrayConstructors/ctors/no-args/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«[object Float64ArrayPrototype]», «[object Float64ArrayPrototype]») to be true (Testing with Float64Array.)'
-  strict mode: 'Test262Error: Expected SameValue(«[object Float64ArrayPrototype]», «[object Float64ArrayPrototype]») to be true (Testing with Float64Array.)'
 test/built-ins/TypedArrayConstructors/ctors/object-arg/length-excessive-throws.js:
   default: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
   strict mode: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
-test/built-ins/TypedArrayConstructors/ctors/object-arg/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«[object Float64ArrayPrototype]», «[object Float64ArrayPrototype]») to be true (Testing with Float64Array.)'
-  strict mode: 'Test262Error: Expected SameValue(«[object Float64ArrayPrototype]», «[object Float64ArrayPrototype]») to be true (Testing with Float64Array.)'
 test/built-ins/TypedArrayConstructors/ctors/typedarray-arg/detached-when-species-retrieved-different-type.js:
   default: 'Test262Error: TypeError thrown for detached source buffer Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
   strict mode: 'Test262Error: TypeError thrown for detached source buffer Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
@@ -1818,9 +1713,6 @@ test/built-ins/TypedArrayConstructors/ctors/typedarray-arg/other-ctor-buffer-cto
 test/built-ins/TypedArrayConstructors/ctors/typedarray-arg/other-ctor-buffer-ctor-species-prototype-throws.js:
   default: 'Test262Error: Expected a Test262Error to be thrown but no exception was thrown at all (Testing with Float64Array.)'
   strict mode: 'Test262Error: Expected a Test262Error to be thrown but no exception was thrown at all (Testing with Float64Array.)'
-test/built-ins/TypedArrayConstructors/ctors/typedarray-arg/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«[object Float64ArrayPrototype]», «[object Float64ArrayPrototype]») to be true (Testing with Float64Array.)'
-  strict mode: 'Test262Error: Expected SameValue(«[object Float64ArrayPrototype]», «[object Float64ArrayPrototype]») to be true (Testing with Float64Array.)'
 test/built-ins/TypedArrayConstructors/ctors/typedarray-arg/same-ctor-buffer-ctor-access-throws.js:
   default: 'Test262Error: Expected a Test262Error to be thrown but no exception was thrown at all (Testing with Float64Array.)'
   strict mode: 'Test262Error: Expected a Test262Error to be thrown but no exception was thrown at all (Testing with Float64Array.)'
@@ -1908,27 +1800,12 @@ test/built-ins/TypedArrayConstructors/of/custom-ctor.js:
 test/built-ins/TypedArrayConstructors/of/new-instance-using-custom-ctor.js:
   default: 'TypeError: TypedArray.of requires its this argument to subclass a TypedArray constructor (Testing with Float64Array.)'
   strict mode: 'TypeError: TypedArray.of requires its this argument to subclass a TypedArray constructor (Testing with Float64Array.)'
-test/built-ins/WeakMap/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«[object WeakMap]», «[object WeakMap]») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«[object WeakMap]», «[object WeakMap]») to be true'
-test/built-ins/WeakRef/proto-from-ctor-realm.js:
-  default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object WeakRef]», «[object WeakRef]») to be true'
-  strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object WeakRef]», «[object WeakRef]») to be true'
-test/built-ins/WeakSet/proto-from-ctor-realm.js:
-  default: 'Test262Error: Expected SameValue(«[object WeakSet]», «[object WeakSet]») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«[object WeakSet]», «[object WeakSet]») to be true'
 test/intl402/Collator/missing-unicode-ext-value-defaults-to-true.js:
   default: "Test262Error: \"kn-true\" is returned in locale, but shouldn't be. Expected SameValue(«7», «-1») to be true"
   strict mode: "Test262Error: \"kn-true\" is returned in locale, but shouldn't be. Expected SameValue(«7», «-1») to be true"
-test/intl402/Collator/proto-from-ctor-realm.js:
-  default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object Object]», «[object Object]») to be true'
-  strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object Object]», «[object Object]») to be true'
 test/intl402/Collator/usage-de.js:
   default: 'Test262Error: Expected [Ä, AE] and [AE, Ä] to have the same contents. search'
   strict mode: 'Test262Error: Expected [Ä, AE] and [AE, Ä] to have the same contents. search'
-test/intl402/DateTimeFormat/proto-from-ctor-realm.js:
-  default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object Object]», «[object Object]») to be true'
-  strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object Object]», «[object Object]») to be true'
 test/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-default.js:
   default: 'Test262Error: Expected SameValue(«h24», «h23») to be true'
   strict mode: 'Test262Error: Expected SameValue(«h24», «h23») to be true'
@@ -1974,18 +1851,9 @@ test/intl402/Intl/getCanonicalLocales/unicode-ext-canonicalize-yes-to-true.js:
 test/intl402/Intl/getCanonicalLocales/unicode-ext-key-with-digit.js:
   default: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all'
   strict mode: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all'
-test/intl402/NumberFormat/proto-from-ctor-realm.js:
-  default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object Object]», «[object Object]») to be true'
-  strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object Object]», «[object Object]») to be true'
-test/intl402/PluralRules/proto-from-ctor-realm.js:
-  default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object Object]», «[object Object]») to be true'
-  strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object Object]», «[object Object]») to be true'
 test/intl402/RelativeTimeFormat/constructor/constructor/locales-valid.js:
   default: 'Test262Error: Grandfathered Expected a RangeError to be thrown but no exception was thrown at all'
   strict mode: 'Test262Error: Grandfathered Expected a RangeError to be thrown but no exception was thrown at all'
-test/intl402/RelativeTimeFormat/constructor/constructor/proto-from-ctor-realm.js:
-  default: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object Intl.RelativeTimeFormat]», «[object Intl.RelativeTimeFormat]») to be true'
-  strict mode: 'Test262Error: newTarget.prototype is undefined Expected SameValue(«[object Intl.RelativeTimeFormat]», «[object Intl.RelativeTimeFormat]») to be true'
 test/intl402/RelativeTimeFormat/prototype/format/pl-pl-style-long.js:
   default: 'Test262Error: Expected SameValue(«za 1000 sekund», «za 1 000 sekund») to be true'
   strict mode: 'Test262Error: Expected SameValue(«za 1000 sekund», «za 1 000 sekund») to be true'
index 197a669..1ce56cd 100644 (file)
@@ -1,3 +1,14 @@
+2020-04-26  Alexey Shvayka  <shvaikalesh@gmail.com>
+
+        InternalFunction::createSubclassStructure should use newTarget's globalObject
+        https://bugs.webkit.org/show_bug.cgi?id=202599
+
+        Reviewed by Yusuke Suzuki.
+
+        * web-platform-tests/WebIDL/ecmascript-binding/constructors-expected.txt:
+        * web-platform-tests/custom-elements/htmlconstructor/newtarget-expected.txt:
+        * web-platform-tests/wasm/jsapi/proto-from-ctor-realm-expected.txt:
+
 2020-04-25  Darin Adler  <darin@apple.com>
 
         Move URL to use StringView when returning substrings of the URL
index dc604d2..c829e7e 100644 (file)
@@ -10,8 +10,8 @@ PASS Subclass constructor in parent window with parent class in child window
 PASS Subclass constructor in child window with parent class in parent window 
 PASS Constructor in child window with bad NewTarget from parent window 
 PASS Constructor in parent window with bad NewTarget from child window 
-FAIL Constructor in parent window with bad NewTarget from parent window that's a bound child window function assert_equals: expected object "[object DOMParserPrototype]" but got object "[object DOMParserPrototype]"
-FAIL Constructor in child window with bad NewTarget from child window that's a bound parent window function assert_equals: expected object "[object DOMParserPrototype]" but got object "[object DOMParserPrototype]"
-FAIL Constructor in parent window with bad NewTarget from parent window that's a proxy for a child window function assert_equals: expected object "[object DOMParserPrototype]" but got object "[object DOMParserPrototype]"
-FAIL Constructor in child window with bad NewTarget from child window that's a proxy for a parent window function assert_equals: expected object "[object DOMParserPrototype]" but got object "[object DOMParserPrototype]"
+PASS Constructor in parent window with bad NewTarget from parent window that's a bound child window function 
+PASS Constructor in child window with bad NewTarget from child window that's a bound parent window function 
+PASS Constructor in parent window with bad NewTarget from parent window that's a proxy for a child window function 
+PASS Constructor in child window with bad NewTarget from child window that's a proxy for a parent window function 
 
index 30adedf..4291dcc 100644 (file)
@@ -2,13 +2,13 @@
 PASS Use NewTarget's prototype, not the one stored at definition time 
 PASS Rethrow any exceptions thrown while getting the prototype 
 PASS If prototype is not object (null), derives the fallback from NewTarget's realm (autonomous custom elements) 
-FAIL If prototype is not object (null), derives the fallback from NewTarget's GetFunctionRealm (autonomous custom elements) assert_equals: Must use the HTMLElement from the realm of NewTarget expected object "[object HTMLElementPrototype]" but got object "[object HTMLElementPrototype]"
+PASS If prototype is not object (null), derives the fallback from NewTarget's GetFunctionRealm (autonomous custom elements) 
 PASS If prototype is not object (undefined), derives the fallback from NewTarget's realm (autonomous custom elements) 
-FAIL If prototype is not object (undefined), derives the fallback from NewTarget's GetFunctionRealm (autonomous custom elements) assert_equals: Must use the HTMLElement from the realm of NewTarget expected object "[object HTMLElementPrototype]" but got object "[object HTMLElementPrototype]"
+PASS If prototype is not object (undefined), derives the fallback from NewTarget's GetFunctionRealm (autonomous custom elements) 
 PASS If prototype is not object (5), derives the fallback from NewTarget's realm (autonomous custom elements) 
-FAIL If prototype is not object (5), derives the fallback from NewTarget's GetFunctionRealm (autonomous custom elements) assert_equals: Must use the HTMLElement from the realm of NewTarget expected object "[object HTMLElementPrototype]" but got object "[object HTMLElementPrototype]"
+PASS If prototype is not object (5), derives the fallback from NewTarget's GetFunctionRealm (autonomous custom elements) 
 PASS If prototype is not object (string), derives the fallback from NewTarget's realm (autonomous custom elements) 
-FAIL If prototype is not object (string), derives the fallback from NewTarget's GetFunctionRealm (autonomous custom elements) assert_equals: Must use the HTMLElement from the realm of NewTarget expected object "[object HTMLElementPrototype]" but got object "[object HTMLElementPrototype]"
+PASS If prototype is not object (string), derives the fallback from NewTarget's GetFunctionRealm (autonomous custom elements) 
 FAIL If prototype is not object (null), derives the fallback from NewTarget's realm (customized built-in elements) promise_test: Unhandled rejection with value: object "TypeError: Reflect.construct requires the first argument be a constructor"
 FAIL If prototype is not object (null), derives the fallback from NewTarget's GetFunctionRealm (customized built-in elements) promise_test: Unhandled rejection with value: object "TypeError: Reflect.construct requires the first argument be a constructor"
 FAIL If prototype is not object (undefined), derives the fallback from NewTarget's realm (customized built-in elements) promise_test: Unhandled rejection with value: object "TypeError: Reflect.construct requires the first argument be a constructor"
index 4b25108..8e07531 100644 (file)
@@ -1,34 +1,34 @@
 
-FAIL WebAssembly.Module: cross-realm NewTarget with `undefined` prototype assert_true: expected true got false
-FAIL WebAssembly.Module: cross-realm NewTarget with `null` prototype assert_true: expected true got false
-FAIL WebAssembly.Module: cross-realm NewTarget with `false` prototype assert_true: expected true got false
-FAIL WebAssembly.Module: cross-realm NewTarget with `true` prototype assert_true: expected true got false
-FAIL WebAssembly.Module: cross-realm NewTarget with `0` prototype assert_true: expected true got false
-FAIL WebAssembly.Module: cross-realm NewTarget with `-1` prototype assert_true: expected true got false
-FAIL WebAssembly.Module: cross-realm NewTarget with `""` prototype assert_true: expected true got false
-FAIL WebAssembly.Module: cross-realm NewTarget with `"str"` prototype assert_true: expected true got false
-FAIL WebAssembly.Module: cross-realm NewTarget with `symbol "Symbol()"` prototype assert_true: expected true got false
-FAIL WebAssembly.Module: bound cross-realm NewTarget with `undefined` prototype assert_true: expected true got false
-FAIL WebAssembly.Module: bound bound cross-realm NewTarget with `null` prototype assert_true: expected true got false
-FAIL WebAssembly.Module: bound Proxy of cross-realm NewTarget with `false` prototype assert_true: expected true got false
-FAIL WebAssembly.Module: Proxy of cross-realm NewTarget with `true` prototype assert_true: expected true got false
-FAIL WebAssembly.Module: Proxy of Proxy of cross-realm NewTarget with `-0` prototype assert_true: expected true got false
-FAIL WebAssembly.Module: Proxy of bound cross-realm NewTarget with `NaN` prototype assert_true: expected true got false
-FAIL WebAssembly.Instance: cross-realm NewTarget with `undefined` prototype assert_true: expected true got false
-FAIL WebAssembly.Instance: cross-realm NewTarget with `null` prototype assert_true: expected true got false
-FAIL WebAssembly.Instance: cross-realm NewTarget with `false` prototype assert_true: expected true got false
-FAIL WebAssembly.Instance: cross-realm NewTarget with `true` prototype assert_true: expected true got false
-FAIL WebAssembly.Instance: cross-realm NewTarget with `0` prototype assert_true: expected true got false
-FAIL WebAssembly.Instance: cross-realm NewTarget with `-1` prototype assert_true: expected true got false
-FAIL WebAssembly.Instance: cross-realm NewTarget with `""` prototype assert_true: expected true got false
-FAIL WebAssembly.Instance: cross-realm NewTarget with `"str"` prototype assert_true: expected true got false
-FAIL WebAssembly.Instance: cross-realm NewTarget with `symbol "Symbol()"` prototype assert_true: expected true got false
-FAIL WebAssembly.Instance: bound cross-realm NewTarget with `undefined` prototype assert_true: expected true got false
-FAIL WebAssembly.Instance: bound bound cross-realm NewTarget with `null` prototype assert_true: expected true got false
-FAIL WebAssembly.Instance: bound Proxy of cross-realm NewTarget with `false` prototype assert_true: expected true got false
-FAIL WebAssembly.Instance: Proxy of cross-realm NewTarget with `true` prototype assert_true: expected true got false
-FAIL WebAssembly.Instance: Proxy of Proxy of cross-realm NewTarget with `-0` prototype assert_true: expected true got false
-FAIL WebAssembly.Instance: Proxy of bound cross-realm NewTarget with `NaN` prototype assert_true: expected true got false
+PASS WebAssembly.Module: cross-realm NewTarget with `undefined` prototype 
+PASS WebAssembly.Module: cross-realm NewTarget with `null` prototype 
+PASS WebAssembly.Module: cross-realm NewTarget with `false` prototype 
+PASS WebAssembly.Module: cross-realm NewTarget with `true` prototype 
+PASS WebAssembly.Module: cross-realm NewTarget with `0` prototype 
+PASS WebAssembly.Module: cross-realm NewTarget with `-1` prototype 
+PASS WebAssembly.Module: cross-realm NewTarget with `""` prototype 
+PASS WebAssembly.Module: cross-realm NewTarget with `"str"` prototype 
+PASS WebAssembly.Module: cross-realm NewTarget with `symbol "Symbol()"` prototype 
+PASS WebAssembly.Module: bound cross-realm NewTarget with `undefined` prototype 
+PASS WebAssembly.Module: bound bound cross-realm NewTarget with `null` prototype 
+PASS WebAssembly.Module: bound Proxy of cross-realm NewTarget with `false` prototype 
+PASS WebAssembly.Module: Proxy of cross-realm NewTarget with `true` prototype 
+PASS WebAssembly.Module: Proxy of Proxy of cross-realm NewTarget with `-0` prototype 
+PASS WebAssembly.Module: Proxy of bound cross-realm NewTarget with `NaN` prototype 
+PASS WebAssembly.Instance: cross-realm NewTarget with `undefined` prototype 
+PASS WebAssembly.Instance: cross-realm NewTarget with `null` prototype 
+PASS WebAssembly.Instance: cross-realm NewTarget with `false` prototype 
+PASS WebAssembly.Instance: cross-realm NewTarget with `true` prototype 
+PASS WebAssembly.Instance: cross-realm NewTarget with `0` prototype 
+PASS WebAssembly.Instance: cross-realm NewTarget with `-1` prototype 
+PASS WebAssembly.Instance: cross-realm NewTarget with `""` prototype 
+PASS WebAssembly.Instance: cross-realm NewTarget with `"str"` prototype 
+PASS WebAssembly.Instance: cross-realm NewTarget with `symbol "Symbol()"` prototype 
+PASS WebAssembly.Instance: bound cross-realm NewTarget with `undefined` prototype 
+PASS WebAssembly.Instance: bound bound cross-realm NewTarget with `null` prototype 
+PASS WebAssembly.Instance: bound Proxy of cross-realm NewTarget with `false` prototype 
+PASS WebAssembly.Instance: Proxy of cross-realm NewTarget with `true` prototype 
+PASS WebAssembly.Instance: Proxy of Proxy of cross-realm NewTarget with `-0` prototype 
+PASS WebAssembly.Instance: Proxy of bound cross-realm NewTarget with `NaN` prototype 
 FAIL WebAssembly.Memory: cross-realm NewTarget with `undefined` prototype assert_true: expected true got false
 FAIL WebAssembly.Memory: cross-realm NewTarget with `null` prototype assert_true: expected true got false
 FAIL WebAssembly.Memory: cross-realm NewTarget with `false` prototype assert_true: expected true got false
@@ -74,49 +74,49 @@ FAIL WebAssembly.Global: bound Proxy of cross-realm NewTarget with `false` proto
 FAIL WebAssembly.Global: Proxy of cross-realm NewTarget with `true` prototype assert_true: expected true got false
 FAIL WebAssembly.Global: Proxy of Proxy of cross-realm NewTarget with `-0` prototype assert_true: expected true got false
 FAIL WebAssembly.Global: Proxy of bound cross-realm NewTarget with `NaN` prototype assert_true: expected true got false
-FAIL WebAssembly.CompileError: cross-realm NewTarget with `undefined` prototype assert_true: expected true got false
-FAIL WebAssembly.CompileError: cross-realm NewTarget with `null` prototype assert_true: expected true got false
-FAIL WebAssembly.CompileError: cross-realm NewTarget with `false` prototype assert_true: expected true got false
-FAIL WebAssembly.CompileError: cross-realm NewTarget with `true` prototype assert_true: expected true got false
-FAIL WebAssembly.CompileError: cross-realm NewTarget with `0` prototype assert_true: expected true got false
-FAIL WebAssembly.CompileError: cross-realm NewTarget with `-1` prototype assert_true: expected true got false
-FAIL WebAssembly.CompileError: cross-realm NewTarget with `""` prototype assert_true: expected true got false
-FAIL WebAssembly.CompileError: cross-realm NewTarget with `"str"` prototype assert_true: expected true got false
-FAIL WebAssembly.CompileError: cross-realm NewTarget with `symbol "Symbol()"` prototype assert_true: expected true got false
-FAIL WebAssembly.CompileError: bound cross-realm NewTarget with `undefined` prototype assert_true: expected true got false
-FAIL WebAssembly.CompileError: bound bound cross-realm NewTarget with `null` prototype assert_true: expected true got false
-FAIL WebAssembly.CompileError: bound Proxy of cross-realm NewTarget with `false` prototype assert_true: expected true got false
-FAIL WebAssembly.CompileError: Proxy of cross-realm NewTarget with `true` prototype assert_true: expected true got false
-FAIL WebAssembly.CompileError: Proxy of Proxy of cross-realm NewTarget with `-0` prototype assert_true: expected true got false
-FAIL WebAssembly.CompileError: Proxy of bound cross-realm NewTarget with `NaN` prototype assert_true: expected true got false
-FAIL WebAssembly.LinkError: cross-realm NewTarget with `undefined` prototype assert_true: expected true got false
-FAIL WebAssembly.LinkError: cross-realm NewTarget with `null` prototype assert_true: expected true got false
-FAIL WebAssembly.LinkError: cross-realm NewTarget with `false` prototype assert_true: expected true got false
-FAIL WebAssembly.LinkError: cross-realm NewTarget with `true` prototype assert_true: expected true got false
-FAIL WebAssembly.LinkError: cross-realm NewTarget with `0` prototype assert_true: expected true got false
-FAIL WebAssembly.LinkError: cross-realm NewTarget with `-1` prototype assert_true: expected true got false
-FAIL WebAssembly.LinkError: cross-realm NewTarget with `""` prototype assert_true: expected true got false
-FAIL WebAssembly.LinkError: cross-realm NewTarget with `"str"` prototype assert_true: expected true got false
-FAIL WebAssembly.LinkError: cross-realm NewTarget with `symbol "Symbol()"` prototype assert_true: expected true got false
-FAIL WebAssembly.LinkError: bound cross-realm NewTarget with `undefined` prototype assert_true: expected true got false
-FAIL WebAssembly.LinkError: bound bound cross-realm NewTarget with `null` prototype assert_true: expected true got false
-FAIL WebAssembly.LinkError: bound Proxy of cross-realm NewTarget with `false` prototype assert_true: expected true got false
-FAIL WebAssembly.LinkError: Proxy of cross-realm NewTarget with `true` prototype assert_true: expected true got false
-FAIL WebAssembly.LinkError: Proxy of Proxy of cross-realm NewTarget with `-0` prototype assert_true: expected true got false
-FAIL WebAssembly.LinkError: Proxy of bound cross-realm NewTarget with `NaN` prototype assert_true: expected true got false
-FAIL WebAssembly.RuntimeError: cross-realm NewTarget with `undefined` prototype assert_true: expected true got false
-FAIL WebAssembly.RuntimeError: cross-realm NewTarget with `null` prototype assert_true: expected true got false
-FAIL WebAssembly.RuntimeError: cross-realm NewTarget with `false` prototype assert_true: expected true got false
-FAIL WebAssembly.RuntimeError: cross-realm NewTarget with `true` prototype assert_true: expected true got false
-FAIL WebAssembly.RuntimeError: cross-realm NewTarget with `0` prototype assert_true: expected true got false
-FAIL WebAssembly.RuntimeError: cross-realm NewTarget with `-1` prototype assert_true: expected true got false
-FAIL WebAssembly.RuntimeError: cross-realm NewTarget with `""` prototype assert_true: expected true got false
-FAIL WebAssembly.RuntimeError: cross-realm NewTarget with `"str"` prototype assert_true: expected true got false
-FAIL WebAssembly.RuntimeError: cross-realm NewTarget with `symbol "Symbol()"` prototype assert_true: expected true got false
-FAIL WebAssembly.RuntimeError: bound cross-realm NewTarget with `undefined` prototype assert_true: expected true got false
-FAIL WebAssembly.RuntimeError: bound bound cross-realm NewTarget with `null` prototype assert_true: expected true got false
-FAIL WebAssembly.RuntimeError: bound Proxy of cross-realm NewTarget with `false` prototype assert_true: expected true got false
-FAIL WebAssembly.RuntimeError: Proxy of cross-realm NewTarget with `true` prototype assert_true: expected true got false
-FAIL WebAssembly.RuntimeError: Proxy of Proxy of cross-realm NewTarget with `-0` prototype assert_true: expected true got false
-FAIL WebAssembly.RuntimeError: Proxy of bound cross-realm NewTarget with `NaN` prototype assert_true: expected true got false
+PASS WebAssembly.CompileError: cross-realm NewTarget with `undefined` prototype 
+PASS WebAssembly.CompileError: cross-realm NewTarget with `null` prototype 
+PASS WebAssembly.CompileError: cross-realm NewTarget with `false` prototype 
+PASS WebAssembly.CompileError: cross-realm NewTarget with `true` prototype 
+PASS WebAssembly.CompileError: cross-realm NewTarget with `0` prototype 
+PASS WebAssembly.CompileError: cross-realm NewTarget with `-1` prototype 
+PASS WebAssembly.CompileError: cross-realm NewTarget with `""` prototype 
+PASS WebAssembly.CompileError: cross-realm NewTarget with `"str"` prototype 
+PASS WebAssembly.CompileError: cross-realm NewTarget with `symbol "Symbol()"` prototype 
+PASS WebAssembly.CompileError: bound cross-realm NewTarget with `undefined` prototype 
+PASS WebAssembly.CompileError: bound bound cross-realm NewTarget with `null` prototype 
+PASS WebAssembly.CompileError: bound Proxy of cross-realm NewTarget with `false` prototype 
+PASS WebAssembly.CompileError: Proxy of cross-realm NewTarget with `true` prototype 
+PASS WebAssembly.CompileError: Proxy of Proxy of cross-realm NewTarget with `-0` prototype 
+PASS WebAssembly.CompileError: Proxy of bound cross-realm NewTarget with `NaN` prototype 
+PASS WebAssembly.LinkError: cross-realm NewTarget with `undefined` prototype 
+PASS WebAssembly.LinkError: cross-realm NewTarget with `null` prototype 
+PASS WebAssembly.LinkError: cross-realm NewTarget with `false` prototype 
+PASS WebAssembly.LinkError: cross-realm NewTarget with `true` prototype 
+PASS WebAssembly.LinkError: cross-realm NewTarget with `0` prototype 
+PASS WebAssembly.LinkError: cross-realm NewTarget with `-1` prototype 
+PASS WebAssembly.LinkError: cross-realm NewTarget with `""` prototype 
+PASS WebAssembly.LinkError: cross-realm NewTarget with `"str"` prototype 
+PASS WebAssembly.LinkError: cross-realm NewTarget with `symbol "Symbol()"` prototype 
+PASS WebAssembly.LinkError: bound cross-realm NewTarget with `undefined` prototype 
+PASS WebAssembly.LinkError: bound bound cross-realm NewTarget with `null` prototype 
+PASS WebAssembly.LinkError: bound Proxy of cross-realm NewTarget with `false` prototype 
+PASS WebAssembly.LinkError: Proxy of cross-realm NewTarget with `true` prototype 
+PASS WebAssembly.LinkError: Proxy of Proxy of cross-realm NewTarget with `-0` prototype 
+PASS WebAssembly.LinkError: Proxy of bound cross-realm NewTarget with `NaN` prototype 
+PASS WebAssembly.RuntimeError: cross-realm NewTarget with `undefined` prototype 
+PASS WebAssembly.RuntimeError: cross-realm NewTarget with `null` prototype 
+PASS WebAssembly.RuntimeError: cross-realm NewTarget with `false` prototype 
+PASS WebAssembly.RuntimeError: cross-realm NewTarget with `true` prototype 
+PASS WebAssembly.RuntimeError: cross-realm NewTarget with `0` prototype 
+PASS WebAssembly.RuntimeError: cross-realm NewTarget with `-1` prototype 
+PASS WebAssembly.RuntimeError: cross-realm NewTarget with `""` prototype 
+PASS WebAssembly.RuntimeError: cross-realm NewTarget with `"str"` prototype 
+PASS WebAssembly.RuntimeError: cross-realm NewTarget with `symbol "Symbol()"` prototype 
+PASS WebAssembly.RuntimeError: bound cross-realm NewTarget with `undefined` prototype 
+PASS WebAssembly.RuntimeError: bound bound cross-realm NewTarget with `null` prototype 
+PASS WebAssembly.RuntimeError: bound Proxy of cross-realm NewTarget with `false` prototype 
+PASS WebAssembly.RuntimeError: Proxy of cross-realm NewTarget with `true` prototype 
+PASS WebAssembly.RuntimeError: Proxy of Proxy of cross-realm NewTarget with `-0` prototype 
+PASS WebAssembly.RuntimeError: Proxy of bound cross-realm NewTarget with `NaN` prototype 
 
index ec73f91..1ca6a15 100644 (file)
@@ -1,3 +1,125 @@
+2020-04-26  Alexey Shvayka  <shvaikalesh@gmail.com>
+
+        InternalFunction::createSubclassStructure should use newTarget's globalObject
+        https://bugs.webkit.org/show_bug.cgi?id=202599
+
+        Reviewed by Yusuke Suzuki.
+
+        If "prototype" of NewTarget is not an object, built-in constructors [1] should acquire
+        default [[Prototype]] from realm of NewTarget, utilizing GetFunctionRealm helper [2].
+        Before this change, realm of active constructor was used instead. This patch introduces
+        GetFunctionRealm and aligns all subclassable constructors with the spec, V8, and SpiderMonkey.
+
+        This change inlines fast paths checks of InternalFunction::createSubclassStructure() and
+        simplifies its signature; getFunctionRealm() is invoked in slow paths only.
+
+        While a dynamically created function uses NewTarget's realm for its default [[Prototype]]
+        similar to other built-ins, its "prototype" object inherit from ObjectPrototype
+        of active constructor's realm [3] (just like their scope), making it retain references
+        to 2 different global objects. To accomodate this behavior, this change introduces
+        `scopeGlobalObject` in JSFunction.cpp methods.
+
+        Above-mentioned behavior also simplifies creation of JSGenerator and JSAsyncGenerator
+        instances since NewTarget's realm is irrelevant to them.
+
+        IntlCollatorConstructor::collatorStructure() and 6 similar methods are removed:
+        a) to impose good practice of using newTarget's globalObject;
+        b) with this change, each of them have 1 call site max;
+        c) other JSC constructors have no methods alike.
+
+        [1]: https://tc39.es/ecma262/#sec-map-constructor (step 2)
+        [2]: https://tc39.es/ecma262/#sec-getfunctionrealm
+        [3]: https://tc39.es/ecma262/#sec-createdynamicfunction (steps 23-25)
+
+        * dfg/DFGOperations.cpp:
+        * runtime/AggregateErrorConstructor.cpp:
+        (JSC::callAggregateErrorConstructor):
+        (JSC::constructAggregateErrorConstructor):
+        * runtime/AggregateErrorConstructor.h:
+        * runtime/AsyncFunctionConstructor.cpp:
+        (JSC::constructAsyncFunctionConstructor):
+        * runtime/AsyncGeneratorFunctionConstructor.cpp:
+        (JSC::constructAsyncGeneratorFunctionConstructor):
+        * runtime/BooleanConstructor.cpp:
+        (JSC::constructWithBooleanConstructor):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        (JSC::createInternalFieldObject):
+        * runtime/DateConstructor.cpp:
+        (JSC::constructDate):
+        * runtime/ErrorConstructor.cpp:
+        (JSC::constructErrorConstructor):
+        * runtime/FunctionConstructor.cpp:
+        (JSC::constructFunctionSkippingEvalEnabledCheck):
+        * runtime/InternalFunction.cpp:
+        (JSC::InternalFunction::createSubclassStructure):
+        (JSC::getFunctionRealm):
+        (JSC::InternalFunction::createSubclassStructureSlow): Deleted.
+        * runtime/InternalFunction.h:
+        (JSC::InternalFunction::createSubclassStructure): Deleted.
+        * runtime/IntlCollatorConstructor.cpp:
+        (JSC::constructIntlCollator):
+        (JSC::callIntlCollator):
+        * runtime/IntlCollatorConstructor.h:
+        * runtime/IntlDateTimeFormatConstructor.cpp:
+        (JSC::constructIntlDateTimeFormat):
+        (JSC::callIntlDateTimeFormat):
+        * runtime/IntlDateTimeFormatConstructor.h:
+        * runtime/IntlNumberFormatConstructor.cpp:
+        (JSC::constructIntlNumberFormat):
+        (JSC::callIntlNumberFormat):
+        * runtime/IntlNumberFormatConstructor.h:
+        * runtime/IntlPluralRulesConstructor.cpp:
+        (JSC::constructIntlPluralRules):
+        * runtime/IntlPluralRulesConstructor.h:
+        * runtime/IntlRelativeTimeFormatConstructor.cpp:
+        (JSC::constructIntlRelativeTimeFormat):
+        * runtime/IntlRelativeTimeFormatConstructor.h:
+        * runtime/JSArrayBufferConstructor.cpp:
+        (JSC::JSGenericArrayBufferConstructor<sharingMode>::constructArrayBuffer):
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::prototypeForConstruction):
+        (JSC::JSFunction::getOwnPropertySlot):
+        * runtime/JSGenericTypedArrayViewConstructorInlines.h:
+        (JSC::constructGenericTypedArrayView):
+        * runtime/JSGlobalObjectInlines.h:
+        (JSC::JSGlobalObject::arrayStructureForIndexingTypeDuringAllocation const):
+        * runtime/MapConstructor.cpp:
+        (JSC::constructMap):
+        * runtime/NativeErrorConstructor.cpp:
+        (JSC::NativeErrorConstructor<errorType>::constructNativeErrorConstructor):
+        (JSC::NativeErrorConstructor<errorType>::callNativeErrorConstructor):
+        * runtime/NativeErrorConstructor.h:
+        * runtime/NumberConstructor.cpp:
+        (JSC::constructNumberConstructor):
+        * runtime/ObjectConstructor.cpp:
+        (JSC::constructObjectWithNewTarget):
+        * runtime/RegExpConstructor.cpp:
+        (JSC::getRegExpStructure):
+        (JSC::constructRegExp):
+        (JSC::esSpecRegExpCreate):
+        * runtime/RegExpConstructor.h:
+        * runtime/SetConstructor.cpp:
+        (JSC::constructSet):
+        * runtime/StringConstructor.cpp:
+        (JSC::constructWithStringConstructor):
+        * runtime/WeakMapConstructor.cpp:
+        (JSC::constructWeakMap):
+        * runtime/WeakObjectRefConstructor.cpp:
+        (JSC::constructWeakRef):
+        * runtime/WeakSetConstructor.cpp:
+        (JSC::constructWeakSet):
+        * wasm/js/WebAssemblyCompileErrorConstructor.cpp:
+        (JSC::constructJSWebAssemblyCompileError):
+        * wasm/js/WebAssemblyInstanceConstructor.cpp:
+        (JSC::constructJSWebAssemblyInstance):
+        * wasm/js/WebAssemblyLinkErrorConstructor.cpp:
+        (JSC::constructJSWebAssemblyLinkError):
+        * wasm/js/WebAssemblyModuleConstructor.cpp:
+        (JSC::WebAssemblyModuleConstructor::createModule):
+        * wasm/js/WebAssemblyRuntimeErrorConstructor.cpp:
+        (JSC::constructJSWebAssemblyRuntimeError):
+
 2020-04-26  Yusuke Suzuki  <ysuzuki@apple.com>
 
         [JSC] ValueAdd, VaueSub, ValueMul, Inc, Dec should say SpecBigInt32 prediction based on ArithProfile
index 5118ba6..443876a 100644 (file)
@@ -344,7 +344,9 @@ JSCell* JIT_OPERATION operationCreatePromise(JSGlobalObject* globalObject, JSObj
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     auto scope = DECLARE_THROW_SCOPE(vm);
-    Structure* structure = InternalFunction::createSubclassStructure(globalObject, globalObject->promiseConstructor(), constructor, globalObject->promiseStructure());
+    Structure* structure = constructor == globalObject->promiseConstructor()
+        ? globalObject->promiseStructure()
+        : InternalFunction::createSubclassStructure(globalObject, constructor, getFunctionRealm(vm, constructor)->promiseStructure());
     RETURN_IF_EXCEPTION(scope, nullptr);
     RELEASE_AND_RETURN(scope, JSPromise::create(vm, structure));
 }
@@ -355,7 +357,9 @@ JSCell* JIT_OPERATION operationCreateInternalPromise(JSGlobalObject* globalObjec
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     auto scope = DECLARE_THROW_SCOPE(vm);
-    Structure* structure = InternalFunction::createSubclassStructure(globalObject, globalObject->internalPromiseConstructor(), constructor, globalObject->internalPromiseStructure());
+    Structure* structure = constructor == globalObject->internalPromiseConstructor()
+        ? globalObject->internalPromiseStructure()
+        : InternalFunction::createSubclassStructure(globalObject, constructor, getFunctionRealm(vm, constructor)->internalPromiseStructure());
     RETURN_IF_EXCEPTION(scope, nullptr);
     RELEASE_AND_RETURN(scope, JSInternalPromise::create(vm, structure));
 }
@@ -366,7 +370,7 @@ JSCell* JIT_OPERATION operationCreateGenerator(JSGlobalObject* globalObject, JSO
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     auto scope = DECLARE_THROW_SCOPE(vm);
-    Structure* structure = InternalFunction::createSubclassStructure(globalObject, nullptr, constructor, globalObject->generatorStructure());
+    Structure* structure = InternalFunction::createSubclassStructure(globalObject, constructor, globalObject->generatorStructure());
     RETURN_IF_EXCEPTION(scope, nullptr);
     RELEASE_AND_RETURN(scope, JSGenerator::create(vm, structure));
 }
@@ -377,7 +381,7 @@ JSCell* JIT_OPERATION operationCreateAsyncGenerator(JSGlobalObject* globalObject
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
     auto scope = DECLARE_THROW_SCOPE(vm);
-    Structure* structure = InternalFunction::createSubclassStructure(globalObject, nullptr, constructor, globalObject->asyncGeneratorStructure());
+    Structure* structure = InternalFunction::createSubclassStructure(globalObject, constructor, globalObject->asyncGeneratorStructure());
     RETURN_IF_EXCEPTION(scope, nullptr);
     RELEASE_AND_RETURN(scope, JSAsyncGenerator::create(vm, structure));
 }
index d4e1829..bf013a8 100644 (file)
@@ -63,7 +63,7 @@ static EncodedJSValue JSC_HOST_CALL callAggregateErrorConstructor(JSGlobalObject
     VM& vm = globalObject->vm();
     JSValue errors = callFrame->argument(0);
     JSValue message = callFrame->argument(1);
-    Structure* errorStructure = jsCast<AggregateErrorConstructor*>(callFrame->jsCallee())->errorStructure(vm);
+    Structure* errorStructure = globalObject->errorStructure(ErrorType::AggregateError);
     return JSValue::encode(AggregateError::create(globalObject, vm, errorStructure, errors, message, nullptr, TypeNothing, false));
 }
 
@@ -73,12 +73,14 @@ static EncodedJSValue JSC_HOST_CALL constructAggregateErrorConstructor(JSGlobalO
     auto scope = DECLARE_THROW_SCOPE(vm);
     JSValue errors = callFrame->argument(0);
     JSValue message = callFrame->argument(1);
-    JSValue newTarget = callFrame->newTarget();
-    ASSERT(newTarget.isObject());
-    Structure* baseStructure = asObject(newTarget)->globalObject(vm)->errorStructure(ErrorType::AggregateError);
-    Structure* errorStructure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), newTarget, baseStructure);
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* errorStructure = newTarget == callFrame->jsCallee()
+        ? globalObject->errorStructure(ErrorType::AggregateError)
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->errorStructure(ErrorType::AggregateError));
+    RETURN_IF_EXCEPTION(scope, { });
     ASSERT(errorStructure);
+
     RELEASE_AND_RETURN(scope, JSValue::encode(AggregateError::create(globalObject, vm, errorStructure, errors, message, nullptr, TypeNothing, false)));
 }
 
index 8872d0c..bfbc1af 100644 (file)
@@ -55,8 +55,6 @@ public:
         return constructor;
     }
 
-    Structure* errorStructure(VM&) { return globalObject()->errorStructure(ErrorType::AggregateError); }
-
 private:
     explicit AggregateErrorConstructor(VM&, Structure*);
 
index 81eb671..d8099be 100644 (file)
@@ -45,7 +45,7 @@ static EncodedJSValue JSC_HOST_CALL callAsyncFunctionConstructor(JSGlobalObject*
 static EncodedJSValue JSC_HOST_CALL constructAsyncFunctionConstructor(JSGlobalObject* globalObject, CallFrame* callFrame)
 {
     ArgList args(callFrame);
-    return JSValue::encode(constructFunction(globalObject, callFrame, args, FunctionConstructionMode::Async));
+    return JSValue::encode(constructFunction(globalObject, callFrame, args, FunctionConstructionMode::Async, callFrame->newTarget()));
 }
 
 AsyncFunctionConstructor::AsyncFunctionConstructor(VM& vm, Structure* structure)
index f559b79..8f10945 100644 (file)
@@ -45,7 +45,7 @@ static EncodedJSValue JSC_HOST_CALL callAsyncGeneratorFunctionConstructor(JSGlob
 static EncodedJSValue JSC_HOST_CALL constructAsyncGeneratorFunctionConstructor(JSGlobalObject* globalObject, CallFrame* callFrame)
 {
     ArgList args(callFrame);
-    return JSValue::encode(constructFunction(globalObject, callFrame, args, FunctionConstructionMode::AsyncGenerator));
+    return JSValue::encode(constructFunction(globalObject, callFrame, args, FunctionConstructionMode::AsyncGenerator, callFrame->newTarget()));
 }
 
 AsyncGeneratorFunctionConstructor::AsyncGeneratorFunctionConstructor(VM& vm, Structure* structure)
index e6241aa..a626dbd 100644 (file)
@@ -43,8 +43,13 @@ static EncodedJSValue JSC_HOST_CALL constructWithBooleanConstructor(JSGlobalObje
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
     JSValue boolean = jsBoolean(callFrame->argument(0).toBoolean(globalObject));
-    Structure* booleanStructure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), globalObject->booleanObjectStructure());
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* booleanStructure = newTarget == callFrame->jsCallee()
+        ? globalObject->booleanObjectStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->booleanObjectStructure());
+    RETURN_IF_EXCEPTION(scope, { });
+
     BooleanObject* obj = BooleanObject::create(vm, booleanStructure);
     obj->setInternalValue(vm, boolean);
     return JSValue::encode(obj);
index 308edbc..cef09f0 100644 (file)
@@ -283,11 +283,15 @@ SLOW_PATH_DECL(slow_path_create_promise)
 
     JSPromise* result = nullptr;
     if (bytecode.m_isInternalPromise) {
-        Structure* structure = InternalFunction::createSubclassStructure(globalObject, globalObject->internalPromiseConstructor(), constructorAsObject, globalObject->internalPromiseStructure());
+        Structure* structure = constructorAsObject == globalObject->internalPromiseConstructor()
+            ? globalObject->internalPromiseStructure()
+            : InternalFunction::createSubclassStructure(globalObject, constructorAsObject, getFunctionRealm(vm, constructorAsObject)->internalPromiseStructure());
         CHECK_EXCEPTION();
         result = JSInternalPromise::create(vm, structure);
     } else {
-        Structure* structure = InternalFunction::createSubclassStructure(globalObject, globalObject->promiseConstructor(), constructorAsObject, globalObject->promiseStructure());
+        Structure* structure = constructorAsObject == globalObject->promiseConstructor()
+            ? globalObject->promiseStructure()
+            : InternalFunction::createSubclassStructure(globalObject, constructorAsObject, getFunctionRealm(vm, constructorAsObject)->promiseStructure());
         CHECK_EXCEPTION();
         result = JSPromise::create(vm, structure);
     }
@@ -320,7 +324,7 @@ static JSClass* createInternalFieldObject(JSGlobalObject* globalObject, VM& vm,
 {
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    Structure* structure = InternalFunction::createSubclassStructure(globalObject, nullptr, constructorAsObject, baseStructure);
+    Structure* structure = InternalFunction::createSubclassStructure(globalObject, constructorAsObject, baseStructure);
     RETURN_IF_EXCEPTION(scope, nullptr);
     JSClass* result = JSClass::create(vm, structure);
 
index e3146b0..a8801ce 100644 (file)
@@ -143,7 +143,9 @@ JSObject* constructDate(JSGlobalObject* globalObject, JSValue newTarget, const A
         value = millisecondsFromComponents(globalObject, args, WTF::LocalTime);
     RETURN_IF_EXCEPTION(scope, nullptr);
 
-    Structure* dateStructure = InternalFunction::createSubclassStructure(globalObject, globalObject->dateConstructor(), newTarget, globalObject->dateStructure());
+    Structure* dateStructure = !newTarget || newTarget == globalObject->dateConstructor()
+        ? globalObject->dateStructure()
+        : InternalFunction::createSubclassStructure(globalObject, asObject(newTarget), getFunctionRealm(vm, asObject(newTarget))->dateStructure());
     RETURN_IF_EXCEPTION(scope, nullptr);
 
     return DateInstance::create(vm, dateStructure, value);
index 685c7ac..662bb72 100644 (file)
@@ -57,8 +57,13 @@ EncodedJSValue JSC_HOST_CALL constructErrorConstructor(JSGlobalObject* globalObj
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
     JSValue message = callFrame->argument(0);
-    Structure* errorStructure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), globalObject->errorStructure());
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* errorStructure = newTarget == callFrame->jsCallee()
+        ? globalObject->errorStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->errorStructure());
+    RETURN_IF_EXCEPTION(scope, { });
+
     RELEASE_AND_RETURN(scope, JSValue::encode(ErrorInstance::create(globalObject, errorStructure, message, nullptr, TypeNothing, false)));
 }
 
index 49a8d50..69e26cc 100644 (file)
@@ -152,34 +152,38 @@ JSObject* constructFunctionSkippingEvalEnabledCheck(
         return nullptr;
     }
 
+    bool needsSubclassStructure = newTarget && newTarget != globalObject->functionConstructor();
+    JSGlobalObject* structureGlobalObject = needsSubclassStructure ? getFunctionRealm(vm, asObject(newTarget)) : globalObject;
     Structure* structure = nullptr;
     switch (functionConstructionMode) {
     case FunctionConstructionMode::Function:
-        structure = JSFunction::selectStructureForNewFuncExp(globalObject, function);
+        structure = JSFunction::selectStructureForNewFuncExp(structureGlobalObject, function);
         break;
     case FunctionConstructionMode::Generator:
-        structure = globalObject->generatorFunctionStructure();
+        structure = structureGlobalObject->generatorFunctionStructure();
         break;
     case FunctionConstructionMode::Async:
-        structure = globalObject->asyncFunctionStructure();
+        structure = structureGlobalObject->asyncFunctionStructure();
         break;
     case FunctionConstructionMode::AsyncGenerator:
-        structure = globalObject->asyncGeneratorFunctionStructure();
+        structure = structureGlobalObject->asyncGeneratorFunctionStructure();
         break;
     }
 
-    Structure* subclassStructure = InternalFunction::createSubclassStructure(globalObject, globalObject->functionConstructor(), newTarget, structure);
-    RETURN_IF_EXCEPTION(scope, nullptr);
+    if (needsSubclassStructure) {
+        structure = InternalFunction::createSubclassStructure(globalObject, asObject(newTarget), structure);
+        RETURN_IF_EXCEPTION(scope, nullptr);
+    }
 
     switch (functionConstructionMode) {
     case FunctionConstructionMode::Function:
-        return JSFunction::create(vm, function, globalObject->globalScope(), subclassStructure);
+        return JSFunction::create(vm, function, globalObject->globalScope(), structure);
     case FunctionConstructionMode::Generator:
-        return JSGeneratorFunction::create(vm, function, globalObject->globalScope(), subclassStructure);
+        return JSGeneratorFunction::create(vm, function, globalObject->globalScope(), structure);
     case FunctionConstructionMode::Async:
-        return JSAsyncFunction::create(vm, function, globalObject->globalScope(), subclassStructure);
+        return JSAsyncFunction::create(vm, function, globalObject->globalScope(), structure);
     case FunctionConstructionMode::AsyncGenerator:
-        return JSAsyncGeneratorFunction::create(vm, function, globalObject->globalScope(), subclassStructure);
+        return JSAsyncGeneratorFunction::create(vm, function, globalObject->globalScope(), structure);
     }
 
     ASSERT_NOT_REACHED();
index 2a01020..542f730 100644 (file)
 #include "InternalFunction.h"
 
 #include "FunctionPrototype.h"
+#include "JSBoundFunction.h"
+#include "JSCInlines.h"
 #include "JSGlobalObject.h"
 #include "JSString.h"
-#include "JSCInlines.h"
+#include "ProxyObject.h"
 
 namespace JSC {
 
@@ -112,7 +114,7 @@ const String InternalFunction::calculatedDisplayName(VM& vm)
     return name();
 }
 
-Structure* InternalFunction::createSubclassStructureSlow(JSGlobalObject* globalObject, JSValue newTarget, Structure* baseClass)
+Structure* InternalFunction::createSubclassStructure(JSGlobalObject* globalObject, JSObject* newTarget, Structure* baseClass)
 {
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -135,7 +137,7 @@ Structure* InternalFunction::createSubclassStructureSlow(JSGlobalObject* globalO
         if (JSObject* prototype = jsDynamicCast<JSObject*>(vm, prototypeValue))
             return rareData->createInternalFunctionAllocationStructureFromBase(vm, baseGlobalObject, prototype, baseClass);
     } else {
-        JSValue prototypeValue = newTarget.get(globalObject, vm.propertyNames->prototype);
+        JSValue prototypeValue = newTarget->get(globalObject, vm.propertyNames->prototype);
         RETURN_IF_EXCEPTION(scope, nullptr);
         if (JSObject* prototype = jsDynamicCast<JSObject*>(vm, prototypeValue)) {
             // This only happens if someone Reflect.constructs our builtin constructor with another builtin constructor as the new.target.
@@ -147,5 +149,26 @@ Structure* InternalFunction::createSubclassStructureSlow(JSGlobalObject* globalO
     return baseClass;
 }
 
+// https://tc39.es/ecma262/#sec-getfunctionrealm
+JSGlobalObject* getFunctionRealm(VM& vm, JSObject* object)
+{
+    ASSERT(object->isFunction(vm));
+
+    if (object->inherits<JSBoundFunction>(vm))
+        return getFunctionRealm(vm, jsCast<JSBoundFunction*>(object)->targetFunction());
+
+    if (object->type() == ProxyObjectType) {
+        auto* proxy = jsCast<ProxyObject*>(object);
+        // Per step 4.a, a TypeError should be thrown for revoked Proxy, yet we skip it since:
+        // a) It is barely observable anyway: "prototype" lookup in createSubclassStructure() will throw for revoked Proxy.
+        // b) Throwing getFunctionRealm() will restrict calling it inline as an argument of createSubclassStructure().
+        // c) There is ongoing discussion on removing it: https://github.com/tc39/ecma262/issues/1798.
+        if (!proxy->isRevoked())
+            return getFunctionRealm(vm, proxy->target());
+    }
+
+    return object->globalObject(vm);
+}
+
 
 } // namespace JSC
index d33ac50..00db11e 100644 (file)
@@ -57,7 +57,7 @@ public:
         return Structure::create(vm, globalObject, proto, TypeInfo(InternalFunctionType, StructureFlags), info()); 
     }
 
-    static Structure* createSubclassStructure(JSGlobalObject*, JSObject* baseCallee, JSValue newTarget, Structure*);
+    JS_EXPORT_PRIVATE static Structure* createSubclassStructure(JSGlobalObject*, JSObject* newTarget, Structure*);
 
     TaggedNativeFunction nativeFunctionFor(CodeSpecializationKind kind)
     {
@@ -88,8 +88,6 @@ protected:
     enum class NameAdditionMode { WithStructureTransition, WithoutStructureTransition };
     JS_EXPORT_PRIVATE void finishCreation(VM&, const String& name, NameAdditionMode = NameAdditionMode::WithStructureTransition);
 
-    JS_EXPORT_PRIVATE static Structure* createSubclassStructureSlow(JSGlobalObject*, JSValue newTarget, Structure*);
-
     JS_EXPORT_PRIVATE static ConstructType getConstructData(JSCell*, ConstructData&);
     JS_EXPORT_PRIVATE static CallType getCallData(JSCell*, CallData&);
 
@@ -99,13 +97,6 @@ protected:
     WriteBarrier<JSGlobalObject> m_globalObject;
 };
 
-ALWAYS_INLINE Structure* InternalFunction::createSubclassStructure(JSGlobalObject* globalObject, JSObject* baseCallee, JSValue newTarget, Structure* baseClass)
-{
-    // We allow newTarget == JSValue() because the API needs to be able to create classes without having a real JS frame.
-    // Since we don't allow subclassing in the API we just treat newTarget == JSValue() as newTarget == callFrame->jsCallee()
-    if (newTarget && newTarget != baseCallee)
-        return createSubclassStructureSlow(globalObject, newTarget, baseClass);
-    return baseClass;
-}
+JS_EXPORT_PRIVATE JSGlobalObject* getFunctionRealm(VM&, JSObject*);
 
 } // namespace JSC
index f69d63d..01aaba1 100644 (file)
@@ -91,8 +91,12 @@ static EncodedJSValue JSC_HOST_CALL constructIntlCollator(JSGlobalObject* global
     // 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget.
     // 2. Let collator be OrdinaryCreateFromConstructor(newTarget, %CollatorPrototype%).
     // 3. ReturnIfAbrupt(collator).
-    Structure* structure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), jsCast<IntlCollatorConstructor*>(callFrame->jsCallee())->collatorStructure(vm));
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* structure = newTarget == callFrame->jsCallee()
+        ? globalObject->collatorStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->collatorStructure());
+    RETURN_IF_EXCEPTION(scope, { });
+
     IntlCollator* collator = IntlCollator::create(vm, structure);
     ASSERT(collator);
 
@@ -109,14 +113,12 @@ static EncodedJSValue JSC_HOST_CALL callIntlCollator(JSGlobalObject* globalObjec
     // NewTarget is always undefined when called as a function.
 
     VM& vm = globalObject->vm();
-    IntlCollatorConstructor* callee = jsCast<IntlCollatorConstructor*>(callFrame->jsCallee());
-
-    // FIXME: Collator does not get the workaround for ECMA-402 1.0 compatibility.
+    // Collator does not require the workaround for ECMA-402 1.0 compatibility.
     // https://bugs.webkit.org/show_bug.cgi?id=153679
 
     // 2. Let collator be OrdinaryCreateFromConstructor(newTarget, %CollatorPrototype%).
     // 3. ReturnIfAbrupt(collator).
-    IntlCollator* collator = IntlCollator::create(vm, callee->collatorStructure(vm));
+    IntlCollator* collator = IntlCollator::create(vm, globalObject->collatorStructure());
     ASSERT(collator);
 
     // 4. Return InitializeCollator(collator, locales, options).
index 7901b2f..7865285 100644 (file)
@@ -43,8 +43,6 @@ public:
 
     DECLARE_INFO;
 
-    Structure* collatorStructure(VM&) const { return globalObject()->collatorStructure(); }
-
 private:
     IntlCollatorConstructor(VM&, Structure*);
     void finishCreation(VM&, IntlCollatorPrototype*);
index d8e07d4..1831841 100644 (file)
@@ -91,8 +91,12 @@ static EncodedJSValue JSC_HOST_CALL constructIntlDateTimeFormat(JSGlobalObject*
     // 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget.
     // 2. Let dateTimeFormat be OrdinaryCreateFromConstructor(newTarget, %DateTimeFormatPrototype%).
     // 3. ReturnIfAbrupt(dateTimeFormat).
-    Structure* structure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), jsCast<IntlDateTimeFormatConstructor*>(callFrame->jsCallee())->dateTimeFormatStructure(vm));
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* structure = newTarget == callFrame->jsCallee()
+        ? globalObject->dateTimeFormatStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->dateTimeFormatStructure());
+    RETURN_IF_EXCEPTION(scope, { });
+
     IntlDateTimeFormat* dateTimeFormat = IntlDateTimeFormat::create(vm, structure);
     ASSERT(dateTimeFormat);
 
@@ -108,14 +112,12 @@ static EncodedJSValue JSC_HOST_CALL callIntlDateTimeFormat(JSGlobalObject* globa
     // 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget.
     // NewTarget is always undefined when called as a function.
 
-    IntlDateTimeFormatConstructor* callee = jsCast<IntlDateTimeFormatConstructor*>(callFrame->jsCallee());
-
     // FIXME: Workaround to provide compatibility with ECMA-402 1.0 call/apply patterns.
     // https://bugs.webkit.org/show_bug.cgi?id=153679
-    return JSValue::encode(constructIntlInstanceWithWorkaroundForLegacyIntlConstructor<IntlDateTimeFormat>(globalObject, callFrame->thisValue(), callee, [&] (VM& vm) {
+    return JSValue::encode(constructIntlInstanceWithWorkaroundForLegacyIntlConstructor<IntlDateTimeFormat>(globalObject, callFrame->thisValue(), callFrame->jsCallee(), [&] (VM& vm) {
         // 2. Let dateTimeFormat be OrdinaryCreateFromConstructor(newTarget, %DateTimeFormatPrototype%).
         // 3. ReturnIfAbrupt(dateTimeFormat).
-        IntlDateTimeFormat* dateTimeFormat = IntlDateTimeFormat::create(vm, callee->dateTimeFormatStructure(vm));
+        IntlDateTimeFormat* dateTimeFormat = IntlDateTimeFormat::create(vm, globalObject->dateTimeFormatStructure());
         ASSERT(dateTimeFormat);
 
         // 4. Return InitializeDateTimeFormat(dateTimeFormat, locales, options).
index 5500c3d..f974533 100644 (file)
@@ -43,8 +43,6 @@ public:
 
     DECLARE_INFO;
 
-    Structure* dateTimeFormatStructure(VM&) const { return globalObject()->dateTimeFormatStructure(); }
-
 private:
     IntlDateTimeFormatConstructor(VM&, Structure*);
     void finishCreation(VM&, IntlDateTimeFormatPrototype*);
index bf95b95..a10cb2e 100644 (file)
@@ -91,8 +91,12 @@ static EncodedJSValue JSC_HOST_CALL constructIntlNumberFormat(JSGlobalObject* gl
     // 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget.
     // 2. Let numberFormat be OrdinaryCreateFromConstructor(newTarget, %NumberFormatPrototype%).
     // 3. ReturnIfAbrupt(numberFormat).
-    Structure* structure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), jsCast<IntlNumberFormatConstructor*>(callFrame->jsCallee())->numberFormatStructure(vm));
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* structure = newTarget == callFrame->jsCallee()
+        ? globalObject->numberFormatStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->numberFormatStructure());
+    RETURN_IF_EXCEPTION(scope, { });
+
     IntlNumberFormat* numberFormat = IntlNumberFormat::create(vm, structure);
     ASSERT(numberFormat);
 
@@ -108,14 +112,12 @@ static EncodedJSValue JSC_HOST_CALL callIntlNumberFormat(JSGlobalObject* globalO
     // 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget.
     // NewTarget is always undefined when called as a function.
 
-    IntlNumberFormatConstructor* callee = jsCast<IntlNumberFormatConstructor*>(callFrame->jsCallee());
-
     // FIXME: Workaround to provide compatibility with ECMA-402 1.0 call/apply patterns.
     // https://bugs.webkit.org/show_bug.cgi?id=153679
-    return JSValue::encode(constructIntlInstanceWithWorkaroundForLegacyIntlConstructor<IntlNumberFormat>(globalObject, callFrame->thisValue(), callee, [&] (VM& vm) {
+    return JSValue::encode(constructIntlInstanceWithWorkaroundForLegacyIntlConstructor<IntlNumberFormat>(globalObject, callFrame->thisValue(), callFrame->jsCallee(), [&] (VM& vm) {
         // 2. Let numberFormat be OrdinaryCreateFromConstructor(newTarget, %NumberFormatPrototype%).
         // 3. ReturnIfAbrupt(numberFormat).
-        IntlNumberFormat* numberFormat = IntlNumberFormat::create(vm, callee->numberFormatStructure(vm));
+        IntlNumberFormat* numberFormat = IntlNumberFormat::create(vm, globalObject->numberFormatStructure());
         ASSERT(numberFormat);
 
         // 4. Return InitializeNumberFormat(numberFormat, locales, options).
index c9c005e..7e5c89e 100644 (file)
@@ -43,8 +43,6 @@ public:
 
     DECLARE_INFO;
 
-    Structure* numberFormatStructure(VM&) const { return globalObject()->numberFormatStructure(); }
-
 private:
     IntlNumberFormatConstructor(VM&, Structure*);
     void finishCreation(VM&, IntlNumberFormatPrototype*);
index f942f3f..f986cd2 100644 (file)
@@ -89,8 +89,12 @@ static EncodedJSValue JSC_HOST_CALL constructIntlPluralRules(JSGlobalObject* glo
 
     // 13.2.1 Intl.PluralRules ([ locales [ , options ] ])
     // https://tc39.github.io/ecma402/#sec-intl.pluralrules
-    Structure* structure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), jsCast<IntlPluralRulesConstructor*>(callFrame->jsCallee())->pluralRulesStructure(vm));
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* structure = newTarget == callFrame->jsCallee()
+        ? globalObject->pluralRulesStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->pluralRulesStructure());
+    RETURN_IF_EXCEPTION(scope, { });
+
     IntlPluralRules* pluralRules = IntlPluralRules::create(vm, structure);
     ASSERT(pluralRules);
 
index 7f3d03f..8bbc6cb 100644 (file)
@@ -43,8 +43,6 @@ public:
 
     DECLARE_INFO;
 
-    Structure* pluralRulesStructure(VM&) const { return globalObject()->pluralRulesStructure(); }
-
 private:
     IntlPluralRulesConstructor(VM&, Structure*);
     void finishCreation(VM&, IntlPluralRulesPrototype*);
index 8fa5d05..4b02f9a 100644 (file)
@@ -87,8 +87,12 @@ static EncodedJSValue JSC_HOST_CALL constructIntlRelativeTimeFormat(JSGlobalObje
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    Structure* structure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), jsCast<IntlRelativeTimeFormatConstructor*>(callFrame->jsCallee())->relativeTimeFormatStructure(vm));
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* structure = newTarget == callFrame->jsCallee()
+        ? globalObject->relativeTimeFormatStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->relativeTimeFormatStructure());
+    RETURN_IF_EXCEPTION(scope, { });
+
     IntlRelativeTimeFormat* relativeTimeFormat = IntlRelativeTimeFormat::create(vm, structure);
     ASSERT(relativeTimeFormat);
 
index 96ae75b..289e582 100644 (file)
@@ -42,8 +42,6 @@ public:
 
     DECLARE_INFO;
 
-    Structure* relativeTimeFormatStructure(VM&) const { return globalObject()->relativeTimeFormatStructure(); }
-
 private:
     IntlRelativeTimeFormatConstructor(VM&, Structure*);
     void finishCreation(VM&, IntlRelativeTimeFormatPrototype*);
index 3d39e49..145ed1e 100644 (file)
@@ -79,9 +79,10 @@ EncodedJSValue JSC_HOST_CALL JSGenericArrayBufferConstructor<sharingMode>::const
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    JSGenericArrayBufferConstructor* constructor = jsCast<JSGenericArrayBufferConstructor*>(callFrame->jsCallee());
-
-    Structure* arrayBufferStructure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), constructor->globalObject()->arrayBufferStructure(sharingMode));
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* arrayBufferStructure = newTarget == callFrame->jsCallee()
+        ? globalObject->arrayBufferStructure(sharingMode)
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->arrayBufferStructure(sharingMode));
     RETURN_IF_EXCEPTION(scope, { });
 
     unsigned length;
index 51903ca..af08b8a 100644 (file)
@@ -174,18 +174,17 @@ JSObject* JSFunction::prototypeForConstruction(VM& vm, JSGlobalObject* globalObj
     scope.releaseAssertNoException();
     if (LIKELY(prototype.isObject()))
         return asObject(prototype);
+    if (isHostOrBuiltinFunction())
+        return this->globalObject()->objectPrototype();
 
-    JSGlobalObject* thisGlobalObject = this->globalObject();
-    if (!isHostOrBuiltinFunction()) {
-        // https://tc39.github.io/ecma262/#sec-generator-function-definitions-runtime-semantics-evaluatebody
-        if (isGeneratorWrapperParseMode(jsExecutable()->parseMode()))
-            return thisGlobalObject->generatorPrototype();
-
-        // https://tc39.github.io/ecma262/#sec-asyncgenerator-definitions-evaluatebody
-        if (isAsyncGeneratorWrapperParseMode(jsExecutable()->parseMode()))
-            return thisGlobalObject->asyncGeneratorPrototype();
-    }
-    return thisGlobalObject->objectPrototype();
+    JSGlobalObject* scopeGlobalObject = this->scope()->globalObject();
+    // https://tc39.github.io/ecma262/#sec-generator-function-definitions-runtime-semantics-evaluatebody
+    if (isGeneratorWrapperParseMode(jsExecutable()->parseMode()))
+        return scopeGlobalObject->generatorPrototype();
+    // https://tc39.github.io/ecma262/#sec-asyncgenerator-definitions-evaluatebody
+    if (isAsyncGeneratorWrapperParseMode(jsExecutable()->parseMode()))
+        return scopeGlobalObject->asyncGeneratorPrototype();
+    return scopeGlobalObject->objectPrototype();
 }
 
 FunctionRareData* JSFunction::allocateAndInitializeRareData(JSGlobalObject* globalObject, size_t inlineCapacity)
@@ -460,16 +459,17 @@ bool JSFunction::getOwnPropertySlot(JSObject* object, JSGlobalObject* globalObje
         unsigned attributes;
         PropertyOffset offset = thisObject->getDirectOffset(vm, propertyName, attributes);
         if (!isValidOffset(offset)) {
+            JSGlobalObject* scopeGlobalObject = thisObject->scope()->globalObject();
             JSObject* prototype = nullptr;
             if (isGeneratorWrapperParseMode(thisObject->jsExecutable()->parseMode())) {
                 // Unlike function instances, the object that is the value of the a GeneratorFunction's prototype
                 // property does not have a constructor property whose value is the GeneratorFunction instance.
                 // https://tc39.github.io/ecma262/#sec-generatorfunction-instances-prototype
-                prototype = constructEmptyObject(globalObject, thisObject->globalObject()->generatorPrototype());
+                prototype = constructEmptyObject(globalObject, scopeGlobalObject->generatorPrototype());
             } else if (isAsyncGeneratorWrapperParseMode(thisObject->jsExecutable()->parseMode()))
-                prototype = constructEmptyObject(globalObject, thisObject->globalObject()->asyncGeneratorPrototype());
+                prototype = constructEmptyObject(globalObject, scopeGlobalObject->asyncGeneratorPrototype());
             else {
-                prototype = constructEmptyObject(globalObject);
+                prototype = constructEmptyObject(globalObject, scopeGlobalObject->objectPrototype());
                 prototype->putDirect(vm, vm.propertyNames->constructor, thisObject, static_cast<unsigned>(PropertyAttribute::DontEnum));
             }
 
index 5779963..f30ac02 100644 (file)
@@ -211,10 +211,11 @@ EncodedJSValue JSC_HOST_CALL constructGenericTypedArrayView(JSGlobalObject* glob
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    InternalFunction* function = jsCast<InternalFunction*>(callFrame->jsCallee());
-    Structure* parentStructure = function->globalObject()->typedArrayStructure(ViewClass::TypedArrayStorageType);
-    Structure* structure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), parentStructure);
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* structure = newTarget == callFrame->jsCallee()
+        ? globalObject->typedArrayStructure(ViewClass::TypedArrayStorageType)
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->typedArrayStructure(ViewClass::TypedArrayStorageType));
+    RETURN_IF_EXCEPTION(scope, { });
 
     size_t argCount = callFrame->argumentCount();
 
index aaaddf7..5f1f252 100644 (file)
@@ -101,7 +101,9 @@ ALWAYS_INLINE bool JSGlobalObject::isSetPrototypeAddFastAndNonObservable()
 
 ALWAYS_INLINE Structure* JSGlobalObject::arrayStructureForIndexingTypeDuringAllocation(JSGlobalObject* globalObject, IndexingType indexingType, JSValue newTarget) const
 {
-    return InternalFunction::createSubclassStructure(globalObject, globalObject->arrayConstructor(), newTarget, arrayStructureForIndexingTypeDuringAllocation(indexingType));
+    return !newTarget || newTarget == globalObject->arrayConstructor()
+        ? globalObject->arrayStructureForIndexingTypeDuringAllocation(indexingType)
+        : InternalFunction::createSubclassStructure(globalObject, asObject(newTarget), getFunctionRealm(globalObject->vm(), asObject(newTarget))->arrayStructureForIndexingTypeDuringAllocation(indexingType));
 }
 
 inline JSFunction* JSGlobalObject::throwTypeErrorFunction() const { return jsCast<JSFunction*>(linkTimeConstant(LinkTimeConstant::throwTypeErrorFunction)); }
index e41b411..ebad029 100644 (file)
@@ -67,8 +67,11 @@ static EncodedJSValue JSC_HOST_CALL constructMap(JSGlobalObject* globalObject, C
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    Structure* mapStructure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), globalObject->mapStructure());
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* mapStructure = newTarget == callFrame->jsCallee()
+        ? globalObject->mapStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->mapStructure());
+    RETURN_IF_EXCEPTION(scope, { });
 
     JSValue iterable = callFrame->argument(0);
     if (iterable.isUndefinedOrNull())
index 0e741da..71374e5 100644 (file)
@@ -55,18 +55,22 @@ EncodedJSValue JSC_HOST_CALL NativeErrorConstructor<errorType>::constructNativeE
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
     JSValue message = callFrame->argument(0);
-    Structure* errorStructure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), jsCast<NativeErrorConstructor*>(callFrame->jsCallee())->errorStructure(vm));
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* errorStructure = newTarget == callFrame->jsCallee()
+        ? globalObject->errorStructure(errorType)
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->errorStructure(errorType));
+    RETURN_IF_EXCEPTION(scope, { });
     ASSERT(errorStructure);
+
     RELEASE_AND_RETURN(scope, JSValue::encode(ErrorInstance::create(globalObject, errorStructure, message, nullptr, TypeNothing, false)));
 }
 
 template<ErrorType errorType>
 EncodedJSValue JSC_HOST_CALL NativeErrorConstructor<errorType>::callNativeErrorConstructor(JSGlobalObject* globalObject, CallFrame* callFrame)
 {
-    VM& vm = globalObject->vm();
     JSValue message = callFrame->argument(0);
-    Structure* errorStructure = jsCast<NativeErrorConstructor*>(callFrame->jsCallee())->errorStructure(vm);
+    Structure* errorStructure = globalObject->errorStructure(errorType);
     return JSValue::encode(ErrorInstance::create(globalObject, errorStructure, message, nullptr, TypeNothing, false));
 }
 
index bf33e69..493e111 100644 (file)
@@ -59,8 +59,6 @@ public:
         constructor->finishCreation(vm, prototype, errorType);
         return constructor;
     }
-
-    Structure* errorStructure(VM&) { return globalObject()->errorStructure(errorType); }
 private:
     static EncodedJSValue JSC_HOST_CALL callNativeErrorConstructor(JSGlobalObject*, CallFrame*);
     static EncodedJSValue JSC_HOST_CALL constructNativeErrorConstructor(JSGlobalObject*, CallFrame*);
index ba13da4..7861660 100644 (file)
@@ -92,8 +92,12 @@ static EncodedJSValue JSC_HOST_CALL constructNumberConstructor(JSGlobalObject* g
     auto scope = DECLARE_THROW_SCOPE(vm);
     double n = callFrame->argumentCount() ? callFrame->uncheckedArgument(0).toNumber(globalObject) : 0;
     RETURN_IF_EXCEPTION(scope, encodedJSValue());
-    Structure* structure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), globalObject->numberObjectStructure());
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* structure = newTarget == callFrame->jsCallee()
+        ? globalObject->numberObjectStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->numberObjectStructure());
+    RETURN_IF_EXCEPTION(scope, { });
 
     NumberObject* object = NumberObject::create(vm, structure);
     object->setInternalValue(vm, jsNumber(n));
index db5a708..009aeff 100644 (file)
@@ -126,7 +126,8 @@ static ALWAYS_INLINE JSObject* constructObjectWithNewTarget(JSGlobalObject* glob
     // 1. If NewTarget is neither undefined nor the active function, then
     if (newTarget && newTarget != objectConstructor) {
         // a. Return ? OrdinaryCreateFromConstructor(NewTarget, "%ObjectPrototype%").
-        Structure* objectStructure = InternalFunction::createSubclassStructure(globalObject, objectConstructor, newTarget, globalObject->objectStructureForObjectConstructor());
+        Structure* baseStructure = getFunctionRealm(vm, asObject(newTarget))->objectStructureForObjectConstructor();
+        Structure* objectStructure = InternalFunction::createSubclassStructure(globalObject, asObject(newTarget), baseStructure);
         RETURN_IF_EXCEPTION(scope, nullptr);
         return constructEmptyObject(vm, objectStructure);
     }
index 96a0936..1e8ca68 100644 (file)
@@ -172,10 +172,9 @@ bool setRegExpConstructorMultiline(JSGlobalObject* globalObject, EncodedJSValue
 
 inline Structure* getRegExpStructure(JSGlobalObject* globalObject, JSValue newTarget)
 {
-    Structure* structure = globalObject->regExpStructure();
-    if (newTarget != jsUndefined())
-        structure = InternalFunction::createSubclassStructure(globalObject, globalObject->regExpConstructor(), newTarget, structure);
-    return structure;
+    return !newTarget || newTarget == globalObject->regExpConstructor()
+        ? globalObject->regExpStructure()
+        : InternalFunction::createSubclassStructure(globalObject, asObject(newTarget), getFunctionRealm(globalObject->vm(), asObject(newTarget))->regExpStructure());
 }
 
 inline OptionSet<Yarr::Flags> toFlags(JSGlobalObject* globalObject, JSValue flags)
@@ -229,7 +228,7 @@ JSObject* constructRegExp(JSGlobalObject* globalObject, const ArgList& args,  JS
     bool constructAsRegexp = isRegExp(vm, globalObject, patternArg);
     RETURN_IF_EXCEPTION(scope, nullptr);
 
-    if (newTarget.isUndefined() && constructAsRegexp && flagsArg.isUndefined()) {
+    if (!newTarget && constructAsRegexp && flagsArg.isUndefined()) {
         JSValue constructor = patternArg.get(globalObject, vm.propertyNames->constructor);
         RETURN_IF_EXCEPTION(scope, nullptr);
         if (callee == constructor) {
@@ -274,7 +273,7 @@ EncodedJSValue JSC_HOST_CALL esSpecRegExpCreate(JSGlobalObject* globalObject, Ca
 {
     JSValue patternArg = callFrame->argument(0);
     JSValue flagsArg = callFrame->argument(1);
-    return JSValue::encode(regExpCreate(globalObject, jsUndefined(), patternArg, flagsArg));
+    return JSValue::encode(regExpCreate(globalObject, JSValue(), patternArg, flagsArg));
 }
 
 EncodedJSValue JSC_HOST_CALL esSpecIsRegExp(JSGlobalObject* globalObject, CallFrame* callFrame)
index ef79889..b2a6421 100644 (file)
@@ -55,7 +55,7 @@ private:
 };
 STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(RegExpConstructor, InternalFunction);
 
-JSObject* constructRegExp(JSGlobalObject*, const ArgList&, JSObject* callee = nullptr, JSValue newTarget = jsUndefined());
+JSObject* constructRegExp(JSGlobalObject*, const ArgList&, JSObject* callee = nullptr, JSValue newTarget = JSValue());
 
 ALWAYS_INLINE bool isRegExp(VM& vm, JSGlobalObject* globalObject, JSValue value)
 {
index 60b98d2..690998f 100644 (file)
@@ -67,8 +67,11 @@ static EncodedJSValue JSC_HOST_CALL constructSet(JSGlobalObject* globalObject, C
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    Structure* setStructure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), globalObject->setStructure());
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* setStructure = newTarget == callFrame->jsCallee()
+        ? globalObject->setStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->setStructure());
+    RETURN_IF_EXCEPTION(scope, { });
 
     JSValue iterable = callFrame->argument(0);
     if (iterable.isUndefinedOrNull()) 
index 6735beb..467cb6f 100644 (file)
@@ -144,8 +144,11 @@ static EncodedJSValue JSC_HOST_CALL constructWithStringConstructor(JSGlobalObjec
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    Structure* structure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), globalObject->stringObjectStructure());
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* structure = newTarget == callFrame->jsCallee()
+        ? globalObject->stringObjectStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->stringObjectStructure());
+    RETURN_IF_EXCEPTION(scope, { });
 
     if (!callFrame->argumentCount())
         return JSValue::encode(StringObject::create(vm, structure));
index e368946..f7dfa6b 100644 (file)
@@ -65,8 +65,12 @@ static EncodedJSValue JSC_HOST_CALL constructWeakMap(JSGlobalObject* globalObjec
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    Structure* weakMapStructure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), globalObject->weakMapStructure());
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* weakMapStructure = newTarget == callFrame->jsCallee()
+        ? globalObject->weakMapStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->weakMapStructure());
+    RETURN_IF_EXCEPTION(scope, { });
+
     JSWeakMap* weakMap = JSWeakMap::create(vm, weakMapStructure);
     JSValue iterable = callFrame->argument(0);
     if (iterable.isUndefinedOrNull())
index 077e2a9..6348d10 100644 (file)
@@ -68,9 +68,13 @@ static EncodedJSValue JSC_HOST_CALL constructWeakRef(JSGlobalObject* globalObjec
     if (!callFrame->argument(0).isObject())
         return throwVMTypeError(globalObject, scope, "First argument to WeakRef should be an object"_s);
 
-    Structure* WeakObjectRefStructure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), globalObject->weakObjectRefStructure());
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
-    RELEASE_AND_RETURN(scope, JSValue::encode(JSWeakObjectRef::create(vm, WeakObjectRefStructure, callFrame->uncheckedArgument(0).getObject())));
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* weakObjectRefStructure = newTarget == callFrame->jsCallee()
+        ? globalObject->weakObjectRefStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->weakObjectRefStructure());
+    RETURN_IF_EXCEPTION(scope, { });
+
+    RELEASE_AND_RETURN(scope, JSValue::encode(JSWeakObjectRef::create(vm, weakObjectRefStructure, callFrame->uncheckedArgument(0).getObject())));
 }
 
 }
index f904955..a7190f9 100644 (file)
@@ -65,8 +65,12 @@ static EncodedJSValue JSC_HOST_CALL constructWeakSet(JSGlobalObject* globalObjec
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    Structure* weakSetStructure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), globalObject->weakSetStructure());
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* weakSetStructure = newTarget == callFrame->jsCallee()
+        ? globalObject->weakSetStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->weakSetStructure());
+    RETURN_IF_EXCEPTION(scope, { });
+
     JSWeakSet* weakSet = JSWeakSet::create(vm, weakSetStructure);
     JSValue iterable = callFrame->argument(0);
     if (iterable.isUndefinedOrNull())
index 412b62b..24cde23 100644 (file)
@@ -49,8 +49,13 @@ static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyCompileError(JSGlobalO
     auto& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
     JSValue message = callFrame->argument(0);
-    auto* structure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), globalObject->webAssemblyCompileErrorStructure());
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* structure = newTarget == callFrame->jsCallee()
+        ? globalObject->webAssemblyCompileErrorStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->webAssemblyCompileErrorStructure());
+    RETURN_IF_EXCEPTION(scope, { });
+
     RELEASE_AND_RETURN(scope, JSValue::encode(JSWebAssemblyCompileError::create(globalObject, vm, structure, message)));
 }
 
index 8419c3a..d5b3576 100644 (file)
@@ -74,8 +74,11 @@ static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyInstance(JSGlobalObjec
     JSObject* importObject = importArgument.getObject();
     if (!importArgument.isUndefined() && !importObject)
         return JSValue::encode(throwException(globalObject, scope, createTypeError(globalObject, "second argument to WebAssembly.Instance must be undefined or an Object"_s, defaultSourceAppender, runtimeTypeForValue(vm, importArgument))));
-    
-    Structure* instanceStructure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), globalObject->webAssemblyInstanceStructure());
+
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* instanceStructure = newTarget == callFrame->jsCallee()
+        ? globalObject->webAssemblyInstanceStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->webAssemblyInstanceStructure());
     RETURN_IF_EXCEPTION(scope, { });
 
     JSWebAssemblyInstance* instance = JSWebAssemblyInstance::tryCreate(vm, globalObject, JSWebAssemblyInstance::createPrivateModuleKey(), module, importObject, instanceStructure, Ref<Wasm::Module>(module->module()), Wasm::CreationMode::FromJS);
index 5ec27a3..6169567 100644 (file)
@@ -49,8 +49,13 @@ static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyLinkError(JSGlobalObje
     auto& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
     JSValue message = callFrame->argument(0);
-    auto* structure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), globalObject->webAssemblyLinkErrorStructure());
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* structure = newTarget == callFrame->jsCallee()
+        ? globalObject->webAssemblyLinkErrorStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->webAssemblyLinkErrorStructure());
+    RETURN_IF_EXCEPTION(scope, { });
+
     RELEASE_AND_RETURN(scope, JSValue::encode(JSWebAssemblyLinkError::create(globalObject, vm, structure, message)));
 }
 
index 6ff9d96..3b4ed60 100644 (file)
@@ -181,7 +181,10 @@ JSWebAssemblyModule* WebAssemblyModuleConstructor::createModule(JSGlobalObject*
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    auto* structure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), globalObject->webAssemblyModuleStructure());
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* structure = newTarget == callFrame->jsCallee()
+        ? globalObject->webAssemblyModuleStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->webAssemblyModuleStructure());
     RETURN_IF_EXCEPTION(scope, nullptr);
 
     RELEASE_AND_RETURN(scope, JSWebAssemblyModule::createStub(vm, globalObject, structure, Wasm::Module::validateSync(&vm.wasmContext, WTFMove(buffer))));
index 85e3279..aa949d0 100644 (file)
@@ -51,8 +51,13 @@ static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyRuntimeError(JSGlobalO
     JSValue message = callFrame->argument(0);
     String messageString = message.isUndefined() ? String() : message.toWTFString(globalObject);
     RETURN_IF_EXCEPTION(scope, encodedJSValue());
-    auto* structure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), globalObject->webAssemblyRuntimeErrorStructure());
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+
+    JSObject* newTarget = asObject(callFrame->newTarget());
+    Structure* structure = newTarget == callFrame->jsCallee()
+        ? globalObject->webAssemblyRuntimeErrorStructure()
+        : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->webAssemblyRuntimeErrorStructure());
+    RETURN_IF_EXCEPTION(scope, { });
+
     return JSValue::encode(JSWebAssemblyRuntimeError::create(globalObject, vm, structure, WTFMove(messageString)));
 }
 
index 0026bcb..b4c6234 100644 (file)
@@ -1,3 +1,22 @@
+2020-04-26  Alexey Shvayka  <shvaikalesh@gmail.com>
+
+        InternalFunction::createSubclassStructure should use newTarget's globalObject
+        https://bugs.webkit.org/show_bug.cgi?id=202599
+
+        Reviewed by Yusuke Suzuki.
+
+        Accounts for InternalFunction::createSubclassStructure() signature change and
+        utilizes getFunctionRealm() helper to handle cross-realm JSBoundFunction and
+        ProxyObject instances as NewTarget value.
+
+        Tests: web-platform-tests/WebIDL/ecmascript-binding/constructors.html
+               web-platform-tests/custom-elements/htmlconstructor/newtarget.html
+
+        * bindings/js/JSDOMWrapperCache.h:
+        (WebCore::setSubclassStructureIfNeeded):
+        * bindings/js/JSHTMLElementCustom.cpp:
+        (WebCore::constructJSHTMLElement):
+
 2020-04-26  Yusuke Suzuki  <ysuzuki@apple.com>
 
         Use `static Lock` instead of `static NeverDestroyed<Lock>`
index b8e5929..ac697af 100644 (file)
@@ -213,9 +213,9 @@ template<typename DOMClass> inline void setSubclassStructureIfNeeded(JSC::JSGlob
     JSC::VM& vm = lexicalGlobalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    auto* newTargetGlobalObject = JSC::jsCast<JSDOMGlobalObject*>(newTarget->globalObject(vm));
+    auto* newTargetGlobalObject = JSC::jsCast<JSDOMGlobalObject*>(JSC::getFunctionRealm(vm, newTarget));
     auto* baseStructure = getDOMStructure<WrapperClass>(vm, *newTargetGlobalObject);
-    auto* subclassStructure = JSC::InternalFunction::createSubclassStructure(lexicalGlobalObject, constructor, newTarget, baseStructure);
+    auto* subclassStructure = JSC::InternalFunction::createSubclassStructure(lexicalGlobalObject, newTarget, baseStructure);
     RETURN_IF_EXCEPTION(scope, void());
     jsObject->setStructure(vm, subclassStructure);
 }
index 3c41199..ecef3ba 100644 (file)
@@ -54,11 +54,10 @@ EncodedJSValue constructJSHTMLElement(JSGlobalObject* lexicalGlobalObject, CallF
         return throwConstructorScriptExecutionContextUnavailableError(*lexicalGlobalObject, scope, "HTMLElement");
     ASSERT(context->isDocument());
 
-    JSValue newTargetValue = callFrame.thisValue();
-    auto* newTarget = newTargetValue.getObject();
-    auto* newTargetGlobalObject = jsCast<JSDOMGlobalObject*>(newTarget->globalObject(vm));
+    auto* newTarget = callFrame.newTarget().getObject();
+    auto* newTargetGlobalObject = jsCast<JSDOMGlobalObject*>(getFunctionRealm(vm, newTarget));
     JSValue htmlElementConstructorValue = JSHTMLElement::getConstructor(vm, newTargetGlobalObject);
-    if (newTargetValue == htmlElementConstructorValue)
+    if (newTarget == htmlElementConstructorValue)
         return throwVMTypeError(lexicalGlobalObject, scope, "new.target is not a valid custom element constructor"_s);
 
     auto& document = downcast<Document>(*context);
@@ -77,8 +76,8 @@ EncodedJSValue constructJSHTMLElement(JSGlobalObject* lexicalGlobalObject, CallF
 
     if (!elementInterface->isUpgradingElement()) {
         Structure* baseStructure = getDOMStructure<JSHTMLElement>(vm, *newTargetGlobalObject);
-        auto* newElementStructure = InternalFunction::createSubclassStructure(lexicalGlobalObject, jsConstructor, newTargetValue, baseStructure);
-        RETURN_IF_EXCEPTION(scope, encodedJSValue());
+        auto* newElementStructure = InternalFunction::createSubclassStructure(lexicalGlobalObject, newTarget, baseStructure);
+        RETURN_IF_EXCEPTION(scope, { });
 
         Ref<HTMLElement> element = HTMLElement::create(elementInterface->name(), document);
         element->setIsDefinedCustomElement(*elementInterface);