From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../ShadowRealm/WrappedFunction/browser.js | 0 .../WrappedFunction/length-throws-typeerror.js | 39 +++++++ .../ShadowRealm/WrappedFunction/length.js | 125 +++++++++++++++++++++ .../WrappedFunction/name-throws-typeerror.js | 39 +++++++ .../built-ins/ShadowRealm/WrappedFunction/name.js | 86 ++++++++++++++ .../built-ins/ShadowRealm/WrappedFunction/shell.js | 0 .../throws-typeerror-on-revoked-proxy.js | 43 +++++++ .../tests/test262/built-ins/ShadowRealm/browser.js | 0 .../test262/built-ins/ShadowRealm/constructor.js | 21 ++++ .../test262/built-ins/ShadowRealm/descriptor.js | 18 +++ .../test262/built-ins/ShadowRealm/extensibility.js | 18 +++ .../ShadowRealm/instance-extensibility.js | 46 ++++++++ .../test262/built-ins/ShadowRealm/instance.js | 36 ++++++ .../tests/test262/built-ins/ShadowRealm/length.js | 31 +++++ js/src/tests/test262/built-ins/ShadowRealm/name.js | 28 +++++ .../tests/test262/built-ins/ShadowRealm/proto.js | 18 +++ .../ShadowRealm/prototype/Symbol.toStringTag.js | 25 +++++ .../built-ins/ShadowRealm/prototype/browser.js | 0 .../ShadowRealm/prototype/evaluate/browser.js | 0 .../ShadowRealm/prototype/evaluate/descriptor.js | 18 +++ ...-the-other-realm-is-wrapped-into-a-typeerror.js | 29 +++++ .../evaluate/globalthis-available-properties.js | 117 +++++++++++++++++++ .../evaluate/globalthis-config-only-properties.js | 101 +++++++++++++++++ .../evaluate/globalthis-ordinary-object.js | 93 +++++++++++++++ .../ShadowRealm/prototype/evaluate/length.js | 31 +++++ .../ShadowRealm/prototype/evaluate/name.js | 28 +++++ .../prototype/evaluate/nested-realms.js | 40 +++++++ .../evaluate/no-conditional-strict-mode.js | 37 ++++++ .../prototype/evaluate/not-constructor.js | 37 ++++++ .../ShadowRealm/prototype/evaluate/proto.js | 18 +++ .../prototype/evaluate/returns-primitive-values.js | 31 +++++ .../evaluate/returns-proxy-callable-object.js | 28 +++++ .../prototype/evaluate/returns-symbol-values.js | 54 +++++++++ .../ShadowRealm/prototype/evaluate/shell.js | 0 .../evaluate/throws-error-from-ctor-realm.js | 35 ++++++ .../evaluate/throws-syntaxerror-on-bad-syntax.js | 33 ++++++ ...rror-if-evaluation-resolves-to-non-primitive.js | 30 +++++ .../evaluate/throws-typeerror-wrap-throwing.js | 73 ++++++++++++ .../throws-when-argument-is-not-a-string.js | 28 +++++ .../prototype/evaluate/validates-realm-object.js | 24 ++++ ...ts-are-wrapped-into-the-inner-realm-extended.js | 49 ++++++++ ...n-arguments-are-wrapped-into-the-inner-realm.js | 27 +++++ ...unction-from-return-values-share-no-identity.js | 75 +++++++++++++ ...ed-function-multiple-different-realms-nested.js | 58 ++++++++++ .../wrapped-function-multiple-different-realms.js | 51 +++++++++ .../wrapped-function-observing-their-scopes.js | 37 ++++++ .../wrapped-function-proto-from-caller-realm.js | 56 +++++++++ .../wrapped-function-proxied-observes-boundary.js | 44 ++++++++ ...-function-throws-typeerror-from-caller-realm.js | 42 +++++++ ...unction-throws-typeerror-on-exceptional-exit.js | 42 +++++++ ...-throws-typeerror-on-non-primitive-arguments.js | 36 ++++++ ...on-throws-typeerror-on-non-primitive-returns.js | 31 +++++ .../wrapped-functions-accepts-callable-objects.js | 27 +++++ ...apped-functions-can-resolve-callable-returns.js | 28 +++++ ...ed-functions-new-wrapping-on-each-evaluation.js | 32 ++++++ ...apped-functions-share-no-properties-extended.js | 70 ++++++++++++ .../wrapped-functions-share-no-properties.js | 31 +++++ .../ShadowRealm/prototype/importValue/browser.js | 0 .../prototype/importValue/descriptor.js | 18 +++ .../prototype/importValue/import-value.js | 24 ++++ .../prototype/importValue/import-value_FIXTURE.js | 5 + .../import-value_syntax_error_FIXTURE.js | 5 + .../importValue/import-value_throws_FIXTURE.js | 5 + .../ShadowRealm/prototype/importValue/length.js | 29 +++++ .../ShadowRealm/prototype/importValue/name.js | 30 +++++ .../prototype/importValue/not-constructor.js | 34 ++++++ .../ShadowRealm/prototype/importValue/proto.js | 18 +++ .../ShadowRealm/prototype/importValue/shell.js | 0 .../prototype/importValue/specifier-tostring.js | 76 +++++++++++++ .../importValue/throws-if-exportname-not-string.js | 33 ++++++ .../throws-if-import-value-does-not-exist.js | 59 ++++++++++ .../throws-typeerror-import-syntax-error.js | 35 ++++++ .../importValue/throws-typeerror-import-throws.js | 35 ++++++ .../importValue/validates-realm-object.js | 24 ++++ .../built-ins/ShadowRealm/prototype/proto.js | 18 +++ .../built-ins/ShadowRealm/prototype/shell.js | 0 .../tests/test262/built-ins/ShadowRealm/shell.js | 24 ++++ 77 files changed, 2666 insertions(+) create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/browser.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/length-throws-typeerror.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/length.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/name-throws-typeerror.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/name.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/shell.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/throws-typeerror-on-revoked-proxy.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/browser.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/constructor.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/descriptor.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/extensibility.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/instance-extensibility.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/instance.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/length.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/name.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/proto.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/Symbol.toStringTag.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/browser.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/browser.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/descriptor.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/errors-from-the-other-realm-is-wrapped-into-a-typeerror.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/globalthis-available-properties.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/globalthis-config-only-properties.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/globalthis-ordinary-object.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/length.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/name.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/nested-realms.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/no-conditional-strict-mode.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/not-constructor.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/proto.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/returns-primitive-values.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/returns-proxy-callable-object.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/returns-symbol-values.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/shell.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-error-from-ctor-realm.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-syntaxerror-on-bad-syntax.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-typeerror-if-evaluation-resolves-to-non-primitive.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-typeerror-wrap-throwing.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-when-argument-is-not-a-string.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/validates-realm-object.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-arguments-are-wrapped-into-the-inner-realm-extended.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-arguments-are-wrapped-into-the-inner-realm.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-from-return-values-share-no-identity.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-multiple-different-realms-nested.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-multiple-different-realms.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-observing-their-scopes.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-proto-from-caller-realm.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-proxied-observes-boundary.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-throws-typeerror-from-caller-realm.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-throws-typeerror-on-exceptional-exit.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-throws-typeerror-on-non-primitive-arguments.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-throws-typeerror-on-non-primitive-returns.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-accepts-callable-objects.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-can-resolve-callable-returns.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-new-wrapping-on-each-evaluation.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-share-no-properties-extended.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-share-no-properties.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/browser.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/descriptor.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/import-value.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/import-value_FIXTURE.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/import-value_syntax_error_FIXTURE.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/import-value_throws_FIXTURE.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/length.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/name.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/not-constructor.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/proto.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/shell.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/specifier-tostring.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-if-exportname-not-string.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-if-import-value-does-not-exist.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-typeerror-import-syntax-error.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-typeerror-import-throws.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/validates-realm-object.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/proto.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/prototype/shell.js create mode 100644 js/src/tests/test262/built-ins/ShadowRealm/shell.js (limited to 'js/src/tests/test262/built-ins/ShadowRealm') diff --git a/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/browser.js b/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/browser.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/length-throws-typeerror.js b/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/length-throws-typeerror.js new file mode 100644 index 0000000000..e6271daf3d --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/length-throws-typeerror.js @@ -0,0 +1,39 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2022 Chengzhong Wu. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-wrappedfunctioncreate +description: > + WrappedFunctionCreate throws a TypeError from its caller realm. +info: | + WrappedFunctionCreate ( callerRealm: a Realm Record, Target: a function object, ) + + ... + 7. Let result be CopyNameAndLength(wrapped, Target). + 8. If result is an Abrupt Completion, throw a TypeError exception. + ... + +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +assert.throws(TypeError, () => r.evaluate(` +function fn() {} +Object.defineProperty(fn, 'length', { + get: () => { + throw new Error('blah'); + }, + enumerable: false, + configurable: true, +}); +fn; +`), 'expect a TypeError on length getter throwing'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/length.js b/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/length.js new file mode 100644 index 0000000000..058375cd7b --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/length.js @@ -0,0 +1,125 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2022 Chengzhong Wu. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-wrappedfunctioncreate +description: > + The value of WrappedFunction.name is copied from the target function +info: | + WrappedFunctionCreate ( callerRealm: a Realm Record, Target: a function object, ) + + ... + 7. Let result be CopyNameAndLength(wrapped, Target). + ... + + CopyNameAndLength ( F: a function object, Target: a function object, prefix: a String, optional argCount: a Number, ) + + 1. If argCount is undefined, then set argCount to 0. + 2. Let L be 0. + 3. Let targetHasLength be ? HasOwnProperty(Target, "length"). + 4. If targetHasLength is true, then + a. Let targetLen be ? Get(Target, "length"). + b. If Type(targetLen) is Number, then + i. If targetLen is +∞𝔽, set L to +∞. + ii. Else if targetLen is -∞𝔽, set L to 0. + iii. Else, + 1. Let targetLenAsInt be ! ToIntegerOrInfinity(targetLen). + 2. Assert: targetLenAsInt is finite. + 3. Set L to max(targetLenAsInt - argCount, 0). + 5. Perform ! SetFunctionLength(F, L). + ... + + SetFunctionLength ( F, length ) + + ... + 2. Return ! DefinePropertyOrThrow(F, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }). + +includes: [propertyHelper.js] +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + + +let wrapped = r.evaluate(` +function fn(foo, bar) {} +fn; +`); +verifyProperty(wrapped, "length", { + value: 2, + enumerable: false, + writable: false, + configurable: true, +}); + + +wrapped = r.evaluate(` +function fn() {} +delete fn.length; +fn; +`); +verifyProperty(wrapped, "length", { + value: 0, + enumerable: false, + writable: false, + configurable: true, +}); + + +wrapped = r.evaluate(` +function fn() {} +Object.defineProperty(fn, 'length', { + get: () => Infinity, + enumerable: false, + configurable: true, +}); +fn; +`); +verifyProperty(wrapped, "length", { + value: Infinity, + enumerable: false, + writable: false, + configurable: true, +}); + + +wrapped = r.evaluate(` +function fn() {} +Object.defineProperty(fn, 'length', { + get: () => -Infinity, + enumerable: false, + configurable: true, +}); +fn; +`); +verifyProperty(wrapped, "length", { + value: 0, + enumerable: false, + writable: false, + configurable: true, +}); + + +wrapped = r.evaluate(` +function fn() {} +Object.defineProperty(fn, 'length', { + get: () => -1, + enumerable: false, + configurable: true, +}); +fn; +`); +verifyProperty(wrapped, "length", { + value: 0, + enumerable: false, + writable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/name-throws-typeerror.js b/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/name-throws-typeerror.js new file mode 100644 index 0000000000..b12e345513 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/name-throws-typeerror.js @@ -0,0 +1,39 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2022 Chengzhong Wu. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-wrappedfunctioncreate +description: > + WrappedFunctionCreate throws a TypeError from its caller realm. +info: | + WrappedFunctionCreate ( callerRealm: a Realm Record, Target: a function object, ) + + ... + 7. Let result be CopyNameAndLength(wrapped, Target). + 8. If result is an Abrupt Completion, throw a TypeError exception. + ... + +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +assert.throws(TypeError, () => r.evaluate(` +function fn() {} +Object.defineProperty(fn, 'name', { + get: () => { + throw new Error('blah'); + }, + enumerable: false, + configurable: true, +}); +fn; +`), 'expect a TypeError on name getter throwing'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/name.js b/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/name.js new file mode 100644 index 0000000000..c3ca6be91c --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/name.js @@ -0,0 +1,86 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2022 Chengzhong Wu. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-wrappedfunctioncreate +description: > + The value of WrappedFunction.name is copied from the target function +info: | + WrappedFunctionCreate ( callerRealm: a Realm Record, Target: a function object, ) + + ... + 7. Let result be CopyNameAndLength(wrapped, Target). + ... + + CopyNameAndLength ( F: a function object, Target: a function object, prefix: a String, optional argCount: a Number, ) + + ... + 6. Let targetName be ? Get(Target, "name"). + 7. If Type(targetName) is not String, set targetName to the empty String. + 8. Perform ! SetFunctionName(F, targetName, prefix). + + SetFunctionName ( F, name [ , prefix ] ) + + ... + 6. Return ! DefinePropertyOrThrow(F, "name", PropertyDescriptor { [[Value]]: name, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }). + +includes: [propertyHelper.js] +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +let wrapped = r.evaluate(` +function fn() {} +fn; +`); +verifyProperty(wrapped, "name", { + value: "fn", + enumerable: false, + writable: false, + configurable: true, +}); + +// The name property is an accessor. +wrapped = r.evaluate(` +function fn() {} +Object.defineProperty(fn, 'name', { + get: () => "bar", + enumerable: false, + configurable: true, +}); +fn; +`); +verifyProperty(wrapped, "name", { + value: "bar", + enumerable: false, + writable: false, + configurable: true, +}); + +// The value of fn.name is not a string. +for (const name of [null, undefined, 0, '1n', false, NaN, Infinity, 'Symbol()', '[]', '{}']) { + wrapped = r.evaluate(` +function fn() {} +Object.defineProperty(fn, 'name', { + value: ${String(name)}, + enumerable: false, + configurable: true, +}); +fn; +`); + verifyProperty(wrapped, "name", { + value: "", + enumerable: false, + writable: false, + configurable: true, + }); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/shell.js b/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/shell.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/throws-typeerror-on-revoked-proxy.js b/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/throws-typeerror-on-revoked-proxy.js new file mode 100644 index 0000000000..5517103de5 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/WrappedFunction/throws-typeerror-on-revoked-proxy.js @@ -0,0 +1,43 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2022 Chengzhong Wu. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-wrapped-function-exotic-objects-call-thisargument-argumentslist +description: > + WrappedFunctionCreate throws a TypeError the target is a revoked proxy. + +info: | + WrappedFunctionCreate ( callerRealm: a Realm Record, Target: a function object, ) + 1. Let target be F.[[WrappedTargetFunction]]. + 2. Assert: IsCallable(target) is true. + 3. Let callerRealm be F.[[Realm]]. + 4. NOTE: Any exception objects produced after this point are associated with callerRealm. + 5. Let targetRealm be ? GetFunctionRealm(target). + ... + + GetFunctionRealm ( obj ) + ... + 3. If obj is a Proxy exotic object, then + a. If obj.[[ProxyHandler]] is null, throw a TypeError exception. + ... + +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +const fn = r.evaluate(` +globalThis.revocable = Proxy.revocable(() => {}, {}); + +globalThis.revocable.proxy; +`); +r.evaluate('revocable.revoke()'); +assert.throws(TypeError, () => fn()); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/browser.js b/js/src/tests/test262/built-ins/ShadowRealm/browser.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/src/tests/test262/built-ins/ShadowRealm/constructor.js b/js/src/tests/test262/built-ins/ShadowRealm/constructor.js new file mode 100644 index 0000000000..6cca306314 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/constructor.js @@ -0,0 +1,21 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm-constructor +description: > + ShadowRealm is a constructor and has [[Construct]] internal method. +includes: [isConstructor.js] +features: [ShadowRealm, Reflect.construct] +---*/ +assert.sameValue( + typeof ShadowRealm, + 'function', + 'This test must fail if ShadowRealm is not a function' +); + +assert(isConstructor(ShadowRealm)); +assert.sameValue(Object.getPrototypeOf(ShadowRealm), Function.prototype); +new ShadowRealm(); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/descriptor.js b/js/src/tests/test262/built-ins/ShadowRealm/descriptor.js new file mode 100644 index 0000000000..df8f861046 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/descriptor.js @@ -0,0 +1,18 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm-constructor +description: > + The ShadowRealm constructor is the initial value of the "ShadowRealm" property of the global object. +includes: [propertyHelper.js] +features: [ShadowRealm] +---*/ + +verifyProperty(this, "ShadowRealm", { + enumerable: false, + writable: true, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/extensibility.js b/js/src/tests/test262/built-ins/ShadowRealm/extensibility.js new file mode 100644 index 0000000000..b5114a4d62 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/extensibility.js @@ -0,0 +1,18 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm-constructor +description: > + The ShadowRealm constructor is extensible +info: | + 17 ECMAScript Standard Built-in Objects + + Unless specified otherwise, the [[Extensible]] internal slot of a built-in + object initially has the value true. +features: [ShadowRealm] +---*/ + +assert.sameValue(Object.isExtensible(ShadowRealm), true); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/instance-extensibility.js b/js/src/tests/test262/built-ins/ShadowRealm/instance-extensibility.js new file mode 100644 index 0000000000..ae26c92a50 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/instance-extensibility.js @@ -0,0 +1,46 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-shadowrealm +description: > + The new instance is extensible +info: | + ShadowRealm ( ) + + ... + 2. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%ShadowRealm.prototype%", + « [[ShadowRealm]], [[ExecutionContext]] »). + ... + 13. Return O. + + OrdinaryCreateFromConstructor creates a new ordinary objects including the + internal slots [[Prototype]] and [[Extensible]]. The latter will have its + value set to true. +includes: [propertyHelper.js] +features: [ShadowRealm] +---*/ + +const realm = new ShadowRealm(); + +assert(Object.isExtensible(realm)); + +Object.defineProperty(realm, 'foo', { configurable: true }); +assert(realm.hasOwnProperty('foo'), 'confirms extensibility adding a new property'); + +Object.defineProperty(realm, 'foo', { + value: 'bar', + writable: true, + configurable: true, + enumerable: false, +}); + +verifyProperty(realm, 'foo', { + value: 'bar', + writable: true, + configurable: true, + enumerable: false, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/instance.js b/js/src/tests/test262/built-ins/ShadowRealm/instance.js new file mode 100644 index 0000000000..41e1783e00 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/instance.js @@ -0,0 +1,36 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm-constructor +description: > + new ShadowRealm() returns a shadow realm instance +info: | + ShadowRealm ( ) + + ... + 2. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%ShadowRealm.prototype%", + « [[ShadowRealm]], [[ExecutionContext]] »). + ... + 13. Return O. +features: [ShadowRealm] +---*/ +assert.sameValue( + typeof ShadowRealm, + 'function', + 'This test must fail if ShadowRealm is not a function' +); + +var realm = new ShadowRealm(); + +assert(realm instanceof ShadowRealm); +assert.sameValue( + Object.getPrototypeOf(realm), + ShadowRealm.prototype, + '[[Prototype]] is set to %ShadowRealm.prototype%' +); + +var otherRealm = new ShadowRealm(); +assert.notSameValue(realm, otherRealm, 'each instance is different'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/length.js b/js/src/tests/test262/built-ins/ShadowRealm/length.js new file mode 100644 index 0000000000..20d4573d48 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/length.js @@ -0,0 +1,31 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm-constructor +description: > + The value of ShadowRealm.length is 0 +info: | + ShadowRealm ( ) + + Every built-in function object, including constructors, has a "length" property + whose value is a non-negative integral Number. Unless otherwise specified, this value + is equal to the number of required parameters shown in the subclause heading for the + function description. Optional parameters and rest parameters are not included in + the parameter count. + + Unless otherwise specified, the "length" property of a built-in function object has + the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. + +includes: [propertyHelper.js] +features: [ShadowRealm] +---*/ + +verifyProperty(ShadowRealm, "length", { + value: 0, + enumerable: false, + writable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/name.js b/js/src/tests/test262/built-ins/ShadowRealm/name.js new file mode 100644 index 0000000000..a0e697e7b1 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/name.js @@ -0,0 +1,28 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-ecmascript-standard-built-in-objects +description: > + The value of ShadowRealm.name is 'ShadowRealm' +info: | + Every built-in function object, including constructors, has a "name" property + whose value is a String. Unless otherwise specified, this value is the name + that is given to the function in this specification. + + Unless otherwise specified, the "name" property of a built-in function + object has the attributes + { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. + +includes: [propertyHelper.js] +features: [ShadowRealm] +---*/ + +verifyProperty(ShadowRealm, "name", { + value: "ShadowRealm", + enumerable: false, + writable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/proto.js b/js/src/tests/test262/built-ins/ShadowRealm/proto.js new file mode 100644 index 0000000000..5f0412fd7e --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/proto.js @@ -0,0 +1,18 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-properties-of-the-shadowrealm-constructor +description: > + The [[Prototype]] of ShadowRealm is Function.Prototype. +info: | + Unless otherwise specified every built-in function and every built-in constructor + has the Function prototype object, which is the initial value of the expression + Function.prototype, as the value of its [[Prototype]] internal slot. + +features: [ShadowRealm] +---*/ + +assert.sameValue(Object.getPrototypeOf(ShadowRealm), Function.prototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/Symbol.toStringTag.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/Symbol.toStringTag.js new file mode 100644 index 0000000000..b9fa746fe2 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/Symbol.toStringTag.js @@ -0,0 +1,25 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype-@@tostringtag +description: > + `Symbol.toStringTag` property descriptor +info: | + The initial value of the @@toStringTag property is the String value + "ShadowRealm". + + This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [ShadowRealm, Symbol.toStringTag] +---*/ + +verifyProperty(ShadowRealm.prototype, Symbol.toStringTag, { + value: 'ShadowRealm', + enumerable: false, + writable: false, + configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/browser.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/browser.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/browser.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/browser.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/descriptor.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/descriptor.js new file mode 100644 index 0000000000..f97bb9a7fa --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/descriptor.js @@ -0,0 +1,18 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate is an ECMAScript Standard built-in object function. +includes: [propertyHelper.js] +features: [ShadowRealm] +---*/ + +verifyProperty(ShadowRealm.prototype, "evaluate", { + enumerable: false, + writable: true, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/errors-from-the-other-realm-is-wrapped-into-a-typeerror.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/errors-from-the-other-realm-is-wrapped-into-a-typeerror.js new file mode 100644 index 0000000000..c1d17b7f20 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/errors-from-the-other-realm-is-wrapped-into-a-typeerror.js @@ -0,0 +1,29 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate wraps errors from other realm into TypeErrors +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +assert.throws(SyntaxError, () => r.evaluate('...'), 'SyntaxError exposed to Parent'); +assert.throws(TypeError, () => r.evaluate('throw 42'), 'throw primitive => TypeError'); +assert.throws(TypeError, () => r.evaluate('throw new ReferenceError("aaa")'), 'custom ctor => TypeError'); +assert.throws(TypeError, () => r.evaluate('throw new TypeError("aaa")'), 'Child TypeError => Parent TypeError'); +assert.throws(TypeError, () => r.evaluate('eval("...");'), 'syntaxerror parsing coming after runtime evaluation'); +assert.throws(TypeError, () => r.evaluate(` + 'use strict'; + eval("var public = 1;"); +`), 'strict-mode only syntaxerror parsing coming after runtime evaluation'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/globalthis-available-properties.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/globalthis-available-properties.js new file mode 100644 index 0000000000..69462f10be --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/globalthis-available-properties.js @@ -0,0 +1,117 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + The ShadowRealm global must include ECMAScript global properties +info: | + ShadowRealm ( ) + + ... + 3. Let realmRec be CreateRealm(). + 4. Set O.[[ShadowRealm]] to realmRec. + ... + 10. Perform ? SetRealmGlobalObject(realmRec, undefined, undefined). + 11. Perform ? SetDefaultGlobalBindings(O.[[ShadowRealm]]). + 12. Perform ? HostInitializeShadowRealm(O.[[ShadowRealm]]). + + SetDefaultGlobalBindings ( realmRec ) + + 1. Let global be realmRec.[[GlobalObject]]. + 2. For each property of the Global Object specified in clause 19, do + a. Let name be the String value of the property name. + b. Let desc be the fully populated data Property Descriptor for the property, containing the specified attributes for the property. For properties listed in 19.2, 19.3, or 19.4 the value of the [[Value]] attribute is the corresponding intrinsic object from realmRec. + c. Perform ? DefinePropertyOrThrow(global, name, desc). + 3. Return global. +features: [ShadowRealm] +includes: [compareArray.js] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +let properties = [ + 'globalThis', + 'Infinity', + 'NaN', + 'undefined', + 'eval', + 'isFinite', + 'isNaN', + 'parseFloat', + 'parseInt', + 'decodeURI', + 'decodeURIComponent', + 'encodeURI', + 'encodeURIComponent', + 'AggregateError', + 'Array', + 'ArrayBuffer', + 'BigInt', + 'BigInt64Array', + 'BigUint64Array', + 'Boolean', + 'DataView', + 'Date', + 'Error', + 'EvalError', + 'FinalizationRegistry', + 'Float16Array', + 'Float32Array', + 'Float64Array', + 'Function', + 'Int8Array', + 'Int16Array', + 'Int32Array', + 'Map', + 'Number', + 'Object', + 'Promise', + 'Proxy', + 'RangeError', + 'ReferenceError', + 'RegExp', + 'Set', + 'SharedArrayBuffer', + 'String', + 'Symbol', + 'SyntaxError', + 'TypeError', + 'Uint8Array', + 'Uint8ClampedArray', + 'Uint16Array', + 'Uint32Array', + 'URIError', + 'WeakMap', + 'WeakRef', + 'WeakSet', + 'Atomics', + 'JSON', + 'Math', + 'Reflect', +]; + +// The intention of this test is to ensure that all built-in properties of the +// global object are also exposed on the ShadowRealm's global object, without +// penalizing implementations that don't have all of them implemented. Notably, +// SharedArrayBuffer may still not be (re-)enabled in all circumstances. +properties = properties.filter(name => { + return name in globalThis; +}); + +const available = properties.filter(name => { + // This test is intentionally not using wrapped functions. + // This test should not depend on wrapped functions. + return r.evaluate(`Object.prototype.hasOwnProperty.call(globalThis, '${name}')`); +}); + +// This comparison is intentional to list difference in names if the the assertion fails +assert.compareArray(properties, available); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/globalthis-config-only-properties.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/globalthis-config-only-properties.js new file mode 100644 index 0000000000..2690ef223a --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/globalthis-config-only-properties.js @@ -0,0 +1,101 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + Properties of globalThis must be configurable +info: | + ShadowRealm ( ) + + ... + 3. Let realmRec be CreateRealm(). + 4. Set O.[[ShadowRealm]] to realmRec. + ... + 10. Perform ? SetRealmGlobalObject(realmRec, undefined, undefined). + 11. Perform ? SetDefaultGlobalBindings(O.[[ShadowRealm]]). + 12. Perform ? HostInitializeShadowRealm(O.[[ShadowRealm]]). + + Runtime Semantics: HostInitializeShadowRealm ( realm ) + + HostInitializeShadowRealm is an implementation-defined abstract operation + used to inform the host of any newly created realms from the ShadowRealm + constructor. Its return value is not used, though it may throw an exception. + The idea of this hook is to initialize host data structures related to the + ShadowRealm, e.g., for module loading. + + The host may use this hook to add properties to the ShadowRealm's global + object. Those properties must be configurable. +features: [ShadowRealm, Array.prototype.includes] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +const anyMissed = r.evaluate(` + // These names are the only exception as non configurable values. + // Yet, they don't represent any object value. + const esNonConfigValues = [ + 'undefined', + 'Infinity', + 'NaN' + ]; + + const entries = Object.entries(Object.getOwnPropertyDescriptors(globalThis)); + + const missed = entries + .filter(entry => entry[1].configurable === false) + .map(([name]) => name) + .filter(name => !esNonConfigValues.includes(name)) + .join(', '); + + missed; +`); + +assert.sameValue(anyMissed, '', 'All globalThis properties must be configurable'); + +const result = r.evaluate(` + const ObjectKeys = Object.keys; + const hasOwn = Object.prototype.hasOwnProperty; + const savedGlobal = globalThis; + const names = Object.keys(Object.getOwnPropertyDescriptors(globalThis)); + + // These names are the only exception as non configurable values. + // Yet, they don't represent any object value. + const esNonConfigValues = [ + 'undefined', + 'Infinity', + 'NaN' + ]; + + // Delete every name except globalThis, for now + const remainingNames = names.filter(name => { + if (esNonConfigValues.includes(name)) { + return false; + } + + if (name !== 'globalThis') { + delete globalThis[name]; + return hasOwn.call(globalThis, name); + } + }); + + delete globalThis['globalThis']; + + if (hasOwn.call(savedGlobal, 'globalThis')) { + remainingNames.push('globalThis'); + } + + const failedDelete = remainingNames.join(', '); + + failedDelete; +`); + +assert.sameValue(result, '', 'deleting any globalThis property must be effective'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/globalthis-ordinary-object.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/globalthis-ordinary-object.js new file mode 100644 index 0000000000..6e57e16287 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/globalthis-ordinary-object.js @@ -0,0 +1,93 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + The globalThis must be an ordinary object from OrdinaryObjectCreate +info: | + ShadowRealm ( ) + + ... + 3. Let realmRec be CreateRealm(). + 4. Set O.[[ShadowRealm]] to realmRec. + ... + 10. Perform ? SetRealmGlobalObject(realmRec, undefined, undefined). + 11. Perform ? SetDefaultGlobalBindings(O.[[ShadowRealm]]). + 12. Perform ? HostInitializeShadowRealm(O.[[ShadowRealm]]). + + SetRealmGlobalObject ( realmRec, globalObj, thisValue ) + + 1. If globalObj is undefined, then + a. Let intrinsics be realmRec.[[Intrinsics]]. + b. Set globalObj to ! OrdinaryObjectCreate(intrinsics.[[%Object.prototype%]]). + 2. Assert: Type(globalObj) is Object. + 3. If thisValue is undefined, set thisValue to globalObj. + ... + + OrdinaryObjectCreate ( proto [ , additionalInternalSlotsList ] ) + + 1. Let internalSlotsList be « [[Prototype]], [[Extensible]] ». + 2. If additionalInternalSlotsList is present, append each of its elements to internalSlotsList. + 3. Let O be ! MakeBasicObject(internalSlotsList). + 4. Set O.[[Prototype]] to proto. + 5. Return O. + + MakeBasicObject ( internalSlotsList ) + + ... + 5. If internalSlotsList contains [[Extensible]], set obj.[[Extensible]] to true. +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +assert.sameValue( + r.evaluate('Object.getPrototypeOf(globalThis) === Object.prototype'), + true, + 'The [[Prototype]] of globalThis is Object.prototype' +); + +assert.sameValue( + r.evaluate('Object.isExtensible(globalThis)'), + true, + 'globalThis is extensible' +); + +assert.sameValue( + r.evaluate('globalThis.constructor === Object'), + true, + 'globalThis.constructor is Object' +); + +assert.sameValue( + r.evaluate(` + let result; + try { + globalThis.__proto__ = {x: 2}; + result = true; + } catch (e) { + result = false; + } + result; + `), + true, + 'Can assign to globalThis.__proto__ directly' +); + +assert.sameValue( + r.evaluate(` + Reflect.set(globalThis, '__proto__', {x: 1}) && + Reflect.setPrototypeOf(globalThis.__proto__, {x: 2}); + `), + true, + 'Can set an ordinary globalThis.__proto__' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/length.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/length.js new file mode 100644 index 0000000000..4306b57340 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/length.js @@ -0,0 +1,31 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + The value of ShadowRealm.prototype.evaluate.length is 1 +info: | + ShadowRealm.prototype.evaluate ( sourceText ) + + Every built-in function object, including constructors, has a "length" property + whose value is a non-negative integral Number. Unless otherwise specified, this value + is equal to the number of required parameters shown in the subclause heading for the + function description. Optional parameters and rest parameters are not included in + the parameter count. + + Unless otherwise specified, the "length" property of a built-in function object has + the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. + +includes: [propertyHelper.js] +features: [ShadowRealm] +---*/ + +verifyProperty(ShadowRealm.prototype.evaluate, "length", { + value: 1, + enumerable: false, + writable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/name.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/name.js new file mode 100644 index 0000000000..1b41c2a74a --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/name.js @@ -0,0 +1,28 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + The value of ShadowRealm.prototype.evaluate.name is 'evaluate' +info: | + Every built-in function object, including constructors, has a "name" property + whose value is a String. Unless otherwise specified, this value is the name + that is given to the function in this specification. + + Unless otherwise specified, the "name" property of a built-in function + object has the attributes + { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. + +includes: [propertyHelper.js] +features: [ShadowRealm] +---*/ + +verifyProperty(ShadowRealm.prototype.evaluate, "name", { + value: "evaluate", + enumerable: false, + writable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/nested-realms.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/nested-realms.js new file mode 100644 index 0000000000..7f0d1503f6 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/nested-realms.js @@ -0,0 +1,40 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm can create a nested ShadowRealm +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +globalThis.myValue = 'a'; +const realm1 = new ShadowRealm(); + +realm1.evaluate('globalThis.myValue = "b";'); + +const realm2Evaluate = realm1.evaluate(` + const realm2 = new ShadowRealm(); + + (str) => realm2.evaluate(str); +`); + +realm2Evaluate('globalThis.myValue = "c";'); + +assert.sameValue(globalThis.myValue, 'a'); +assert.sameValue(realm1.evaluate('globalThis.myValue'), 'b'); +assert.sameValue(realm2Evaluate('globalThis.myValue'), 'c'); + +realm1.evaluate('globalThis.myValue = "d"'); + +assert.sameValue(globalThis.myValue, 'a', 'no side effects'); +assert.sameValue(realm1.evaluate('globalThis.myValue'), 'd', 'no side effects'); +assert.sameValue(realm2Evaluate('globalThis.myValue'), 'c', 'no side effects'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/no-conditional-strict-mode.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/no-conditional-strict-mode.js new file mode 100644 index 0000000000..70030f0f93 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/no-conditional-strict-mode.js @@ -0,0 +1,37 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + The new realm has no conditional strict mode based on its outer realm +info: | + This test should always run with the outer realm in both strict and non + strict mode to verify the realm code starts in non-strict mode. +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +const res = r.evaluate(` + function lol() { + arguments = 42; // This would be a SyntaxError if in strict mode + + return arguments; + } + lol; +`); + +assert.sameValue(res(), 42); + +const res2 = r.evaluate('var public = 1; 42'); + +assert.sameValue(res2, 42); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/not-constructor.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/not-constructor.js new file mode 100644 index 0000000000..7530d84d93 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/not-constructor.js @@ -0,0 +1,37 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate is not a constructor. +includes: [isConstructor.js] +features: [ShadowRealm, Reflect.construct] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +assert.sameValue( + isConstructor(ShadowRealm.prototype.evaluate), + false, + 'isConstructor(ShadowRealm.prototype.evaluate) must return false' +); + +assert.throws(TypeError, () => { + new ShadowRealm.prototype.evaluate(""); +}, '`new ShadowRealm.prototype.evaluate("")` throws TypeError'); + +const r = new ShadowRealm(); +r.evaluate('globalThis.x = 0'); + +assert.throws(TypeError, () => { + new r.evaluate("globalThis.x += 1;"); +}, '`new r.evaluate("...")` throws TypeError'); + +assert.sameValue(r.evaluate('globalThis.x'), 0, 'No code evaluated in the new expression'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/proto.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/proto.js new file mode 100644 index 0000000000..15c64b1df4 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/proto.js @@ -0,0 +1,18 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + The [[Prototype]] of ShadowRealm.prototype.evaluate is Function.Prototype. + + Unless otherwise specified every built-in function and every built-in constructor + has the Function prototype object, which is the initial value of the expression + Function.prototype, as the value of its [[Prototype]] internal slot. + +features: [ShadowRealm] +---*/ + +assert.sameValue(Object.getPrototypeOf(ShadowRealm.prototype.evaluate), Function.prototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/returns-primitive-values.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/returns-primitive-values.js new file mode 100644 index 0000000000..fe6e1ee585 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/returns-primitive-values.js @@ -0,0 +1,31 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate returns primitive values +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +assert.sameValue(r.evaluate('1 + 1'), 2); +assert.sameValue(r.evaluate('null'), null); +assert.sameValue(r.evaluate(''), undefined, 'undefined from empty completion'); +assert.sameValue(r.evaluate('undefined'), undefined); +assert.sameValue(r.evaluate('true'), true); +assert.sameValue(r.evaluate('false'), false); +assert.sameValue(r.evaluate('function fn() {}'), undefined, 'fn declaration has empty completion'); +assert.sameValue(r.evaluate('{}'), undefined, 'Block has empty completion'); +assert.sameValue(r.evaluate('-0'), -0); +assert.sameValue(r.evaluate('"str"'), 'str'); +assert(Number.isNaN(r.evaluate('NaN'))); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/returns-proxy-callable-object.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/returns-proxy-callable-object.js new file mode 100644 index 0000000000..83e4f8c6ff --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/returns-proxy-callable-object.js @@ -0,0 +1,28 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate wrapped proxy callable object. +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +const proxyCallable = r.evaluate(` +function fn() { return 42; } +new Proxy(fn, {}); +`); + +assert.sameValue(typeof proxyCallable, 'function', 'wrapped proxy callable object is typeof function'); +assert.sameValue(proxyCallable(), 42, 'wrappedpfn() returns 42'); +assert.sameValue((new Proxy(proxyCallable, {}))(), 42, 'wrapped functions can be proxied'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/returns-symbol-values.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/returns-symbol-values.js new file mode 100644 index 0000000000..9573eb751b --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/returns-symbol-values.js @@ -0,0 +1,54 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate returns symbol values +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); +const s = r.evaluate('Symbol("foobar")'); + +assert.sameValue(typeof s, 'symbol'); +assert.sameValue(s.constructor, Symbol, 'primitive does not expose other ShadowRealm constructor'); +assert.sameValue(Object.getPrototypeOf(s), Symbol.prototype); +assert.sameValue(Symbol.prototype.toString.call(s), 'Symbol(foobar)'); + +const shadowX = r.evaluate('Symbol.for("my symbol name")'); +const myX = Symbol.for('my symbol name') + +assert.sameValue( + shadowX, + myX, + 'The shadow realms observes the symbol global registry used in Symbol.for' +); + +assert.sameValue( + Symbol.keyFor(shadowX), + 'my symbol name', + 'Symbol.keyFor observes the string key name of a symbol originally registered in the shadow realm' +); + +assert.sameValue( + Symbol.keyFor(s), + undefined, + 'Symbol.keyFor cannot find a key for a regular symbol created in the shadow realm' +); + +const { get: description } = Object.getOwnPropertyDescriptor(Symbol.prototype, 'description'); + +assert.sameValue( + description.call(s), + 'foobar', + 'get description for the symbol created in the shadow realm' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/shell.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/shell.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-error-from-ctor-realm.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-error-from-ctor-realm.js new file mode 100644 index 0000000000..e093ebd620 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-error-from-ctor-realm.js @@ -0,0 +1,35 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Chengzhong Wu. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate throws a TypeError from ShadowRealm's creation realm. +features: [ShadowRealm, cross-realm, Reflect] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +var other = $262.createRealm().global; +var OtherTypeError = other.TypeError; +var OtherSyntaxError = other.SyntaxError; +var OtherShadowRealm = other.ShadowRealm; + +var realm = Reflect.construct(OtherShadowRealm, []); + +assert.throws(OtherTypeError, () => realm.evaluate('globalThis'), 'throws a TypeError if return value can not be wrapped'); +assert.throws(OtherTypeError, () => realm.evaluate('throw new Error()'), 'throws a TypeError if completion is abrupt'); + +assert.throws(OtherTypeError, () => realm.evaluate(1), 'throws a TypeError if sourceText is not a string'); +assert.throws(OtherSyntaxError, () => realm.evaluate('...'), 'throws a SyntaxError if the sourceText is not valid'); + +const bogus = {}; +assert.throws(OtherTypeError, function() { + realm.evaluate.call(bogus, 'This is invalid code and should not be evaluated'); +}, 'throws a TypeError if this is not a ShadowRealm object'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-syntaxerror-on-bad-syntax.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-syntaxerror-on-bad-syntax.js new file mode 100644 index 0000000000..77ff286da1 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-syntaxerror-on-bad-syntax.js @@ -0,0 +1,33 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate throws a SyntaxError if the syntax can't be parsed +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +assert.throws(SyntaxError, () => r.evaluate('...'), 'SyntaxError exposed to Parent'); +assert.throws(SyntaxError, () => r.evaluate(` + "use strict"; + throw "do not evaluate"; + function lol(){ + arguments = 1; + } +`), 'Strict mode only SyntaxError, setting value to a fn arguments'); +assert.throws(SyntaxError, () => r.evaluate(` + "use strict"; + throw "do not evaluate"; + var public = 1; +`), 'Strict mode only SyntaxError, var public'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-typeerror-if-evaluation-resolves-to-non-primitive.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-typeerror-if-evaluation-resolves-to-non-primitive.js new file mode 100644 index 0000000000..d2017c9a44 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-typeerror-if-evaluation-resolves-to-non-primitive.js @@ -0,0 +1,30 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate throws a TypeError if evaluate resolves to non-primitive values +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +assert.throws(TypeError, () => r.evaluate('globalThis'), 'globalThis'); +assert.throws(TypeError, () => r.evaluate('[]'), 'array literal'); +assert.throws(TypeError, () => r.evaluate(` + ({ + [Symbol.toPrimitive]() { return 'string'; }, + toString() { return 'str'; }, + valueOf() { return 1; } + }); +`), 'object literal with immediate primitive coercion methods'); +assert.throws(TypeError, () => r.evaluate('Object.create(null)'), 'ordinary object with null __proto__'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-typeerror-wrap-throwing.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-typeerror-wrap-throwing.js new file mode 100644 index 0000000000..817b00a31f --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-typeerror-wrap-throwing.js @@ -0,0 +1,73 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2022 Chengzhong Wu. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-wrappedfunctioncreate +description: > + WrappedFunctionCreate throws a TypeError if the accessing target's property may throw. + +info: | + WrappedFunctionCreate ( callerRealm: a Realm Record, Target: a function object, ) + ... + 7. Let result be CopyNameAndLength(wrapped, Target). + ... + + CopyNameAndLength ( F: a function object, Target: a function object, optional prefix: a String, optional argCount: a Number, ) + ... + 3. Let targetHasLength be ? HasOwnProperty(Target, "length"). + 4. If targetHasLength is true, then + a. Let targetLen be ? Get(Target, "length"). + ... + 6. Let targetName be ? Get(Target, "name"). + +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +assert.throws(TypeError, () => r.evaluate(` +const revocable = Proxy.revocable(() => {}, {}); +revocable.revoke(); + +revocable.proxy; +`), 'TypeError on wrapping a revoked callable proxy'); + +assert.throws(TypeError, () => r.evaluate(` +const fn = () => {}; +Object.defineProperty(fn, 'name', { + get() { + throw new Error(); + }, +}); + +fn; +`), 'TypeError on wrapping a fn with throwing name accessor'); + +assert.throws(TypeError, () => r.evaluate(` +const fn = () => {}; +Object.defineProperty(fn, 'length', { + get() { + throw new Error(); + }, +}); + +fn; +`), 'TypeError on wrapping a fn with throwing length accessor'); + +assert.throws(TypeError, () => r.evaluate(` +const proxy = new Proxy(() => {}, { + getOwnPropertyDescriptor(target, key) { + throw new Error(); + }, +}); + +proxy; +`), 'TypeError on wrapping a callable proxy with throwing getOwnPropertyDescriptor trap'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-when-argument-is-not-a-string.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-when-argument-is-not-a-string.js new file mode 100644 index 0000000000..1d57638101 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/throws-when-argument-is-not-a-string.js @@ -0,0 +1,28 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate throws when argument is not a string. +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +assert.throws(TypeError, () => r.evaluate(['1+1'])); +assert.throws(TypeError, () => r.evaluate({ [Symbol.toPrimitive]() { return '1+1'; }})); +assert.throws(TypeError, () => r.evaluate(1)); +assert.throws(TypeError, () => r.evaluate(null)); +assert.throws(TypeError, () => r.evaluate(undefined)); +assert.throws(TypeError, () => r.evaluate(true)); +assert.throws(TypeError, () => r.evaluate(false)); +assert.throws(TypeError, () => r.evaluate(new String('nope'))); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/validates-realm-object.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/validates-realm-object.js new file mode 100644 index 0000000000..6c14e46dd2 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/validates-realm-object.js @@ -0,0 +1,24 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate validates realm object. +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); +const bogus = {}; + +assert.throws(TypeError, function() { + r.evaluate.call(bogus, 'This is invalid code and should not be evaluated'); +}, 'throws a TypeError if this is not a ShadowRealm object'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-arguments-are-wrapped-into-the-inner-realm-extended.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-arguments-are-wrapped-into-the-inner-realm-extended.js new file mode 100644 index 0000000000..08fab52be9 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-arguments-are-wrapped-into-the-inner-realm-extended.js @@ -0,0 +1,49 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate wrapped function arguments are wrapped into the inner realm, extended. +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); +const blueFn = (x, y) => x + y; + +const redWrappedFn = r.evaluate(` + function fn(wrapped1, wrapped2, wrapped3) { + if (wrapped1.x) { + return 1; + } + if (wrapped2.x) { + return 2; + } + if (wrapped3.x) { + // Not unwrapped + return 3; + } + if (wrapped1 === wrapped2) { + // Always a new wrapped function + return 4; + } + + // No unwrapping + if (wrapped3 === fn) { + return 5; + }; + + return true; + } + fn.x = 'secret'; + fn; +`); +assert.sameValue(redWrappedFn(blueFn, blueFn, redWrappedFn), true); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-arguments-are-wrapped-into-the-inner-realm.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-arguments-are-wrapped-into-the-inner-realm.js new file mode 100644 index 0000000000..e63b0413a8 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-arguments-are-wrapped-into-the-inner-realm.js @@ -0,0 +1,27 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate wrapped function arguments are wrapped into the inner realm +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); +const blueFn = (x, y) => x + y; + +const redWrappedFn = r.evaluate(` +0, (blueWrappedFn, a, b, c) => { + return blueWrappedFn(a, b) * c; +} +`); +assert.sameValue(redWrappedFn(blueFn, 2, 3, 4), 20); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-from-return-values-share-no-identity.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-from-return-values-share-no-identity.js new file mode 100644 index 0000000000..c5774de054 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-from-return-values-share-no-identity.js @@ -0,0 +1,75 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate wrapped function from return values share no identity. +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +r.evaluate(` +function fn() { return 42; } +globalThis.arrow = x => x * 2; +globalThis.pFn = new Proxy(fn, { + apply() { + pFn.used = 1; + return 39; + } +}); +async function aFn() { + return 1; +} + +function * genFn() { + return 1; +} + +fn.x = 'secrets'; +arrow.x = 'secrets'; +pFn.x = 'secrets'; +aFn.x = 'secrets'; +genFn.x = 'secrets'; +`) + +const wrappedOrdinary = r.evaluate('() => fn')(); +assert.sameValue(typeof wrappedOrdinary, 'function', 'ordinary function wrapped'); +assert.sameValue(wrappedOrdinary(), 42, 'ordinary, return'); +assert.sameValue(wrappedOrdinary.x, undefined, 'ordinary, no property shared'); +assert.sameValue(Object.prototype.hasOwnProperty.call(wrappedOrdinary, 'x'), false, 'ordinary, no own property shared'); + +const wrappedArrow = r.evaluate('() => arrow')(); +assert.sameValue(typeof wrappedArrow, 'function', 'arrow function wrapped'); +assert.sameValue(wrappedArrow(7), 14, 'arrow function, return'); +assert.sameValue(wrappedArrow.x, undefined, 'arrow function, no property'); +assert.sameValue(Object.prototype.hasOwnProperty.call(wrappedArrow, 'x'), false, 'arrow function, no own property shared'); + +const wrappedProxied = r.evaluate('() => pFn')(); +assert.sameValue(typeof wrappedProxied, 'function', 'proxied ordinary function wrapped'); +assert.sameValue(r.evaluate('pFn.used'), undefined, 'pFn not called yet'); +assert.sameValue(wrappedProxied(), 39, 'return of the proxied callable'); +assert.sameValue(r.evaluate('pFn.used'), 1, 'pfn called'); +assert.sameValue(wrappedProxied.x, undefined, 'proxy callable, no property'); +assert.sameValue(Object.prototype.hasOwnProperty.call(wrappedProxied, 'x'), false, 'proxy callable, no own property shared'); + +const wrappedAsync = r.evaluate('() => aFn')(); +assert.sameValue(typeof wrappedAsync, 'function', 'async function wrapped'); +assert.throws(TypeError, () => wrappedAsync(), 'wrapped function cannot return non callable object'); +assert.sameValue(wrappedAsync.x, undefined, 'async function, no property'); +assert.sameValue(Object.prototype.hasOwnProperty.call(wrappedAsync, 'x'), false, 'async function, no own property shared'); + +const wrappedGenerator = r.evaluate('() => genFn')(); +assert.sameValue(typeof wrappedGenerator, 'function', 'gen function wrapped'); +assert.throws(TypeError, () => wrappedGenerator(), 'wrapped function cannot return non callable object'); +assert.sameValue(wrappedGenerator.x, undefined, 'generator, no property'); +assert.sameValue(Object.prototype.hasOwnProperty.call(wrappedGenerator, 'x'), false, 'generator, no own property shared'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-multiple-different-realms-nested.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-multiple-different-realms-nested.js new file mode 100644 index 0000000000..ab39ff6033 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-multiple-different-realms-nested.js @@ -0,0 +1,58 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm can wrap a function to multiple nested realms. +features: [ShadowRealm] +---*/ +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +globalThis.count = 0; +const realm1 = new ShadowRealm(); + +const r1wrapped = realm1.evaluate(` + globalThis.count = 0; + () => globalThis.count += 1; +`); + +const realm2Evaluate = realm1.evaluate(` + const realm2 = new ShadowRealm(); + + (str) => realm2.evaluate(str); +`); + +const r2wrapper = realm2Evaluate(` + globalThis.wrapped = undefined; + globalThis.count = 0; // Bait + (fn) => globalThis.wrapped = fn; +`); + +const rewrapped = r2wrapper(r1wrapped); + +assert.notSameValue(rewrapped, r1wrapped, 'rewrapped !== r1wrapped'); + +const r2wrapped = realm2Evaluate('globalThis.wrapped'); + +assert.notSameValue(r2wrapped, r1wrapped, 'r2wrapped !== r1wrapped'); +assert.notSameValue(r2wrapped, rewrapped, 'r2wrapped !== rewrapped'); + +assert.sameValue(realm1.evaluate('globalThis.count'), 0, `getting wrapped function won't trigger a call`); + +assert.sameValue(r2wrapped(), 1, 'call from r2 wrapped (r2wrapped) cycles back to r1'); + +assert.sameValue(realm1.evaluate('globalThis.count'), 1, 'effects produced in a third realm, #1'); + +assert.sameValue(rewrapped(), 2, 'call from r2 wrapped (rewrapped) cycles back to r1'); + +assert.sameValue(realm1.evaluate('globalThis.count'), 2, 'effects produced in a third realm, #2'); + +assert.sameValue(realm2Evaluate('globalThis.count'), 0, 'no side effects produced in the wrong realm (realm2)'); +assert.sameValue(globalThis.count, 0, 'no side effects produced in the wrong realm (main realm)'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-multiple-different-realms.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-multiple-different-realms.js new file mode 100644 index 0000000000..943da521d7 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-multiple-different-realms.js @@ -0,0 +1,51 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm can wrap a function to multiple realms. +features: [ShadowRealm] +---*/ + +const realm1 = new ShadowRealm(); +const realm2 = new ShadowRealm(); + +globalThis.count = 0; + +assert.notSameValue(realm1, realm2); + +const r1wrapped = realm1.evaluate(` + globalThis.count = 0; + () => globalThis.count += 1; +`); + +const r2wrapper = realm2.evaluate(` + globalThis.wrapped = undefined; + globalThis.count = 0; // Bait + (fn) => globalThis.wrapped = fn; +`); + +const rewrapped = r2wrapper(r1wrapped); + +assert.notSameValue(rewrapped, r1wrapped, 'rewrapped !== r1wrapped'); + +const r2wrapped = realm2.evaluate('globalThis.wrapped'); + +assert.notSameValue(r2wrapped, r1wrapped, 'r2wrapped !== r1wrapped'); +assert.notSameValue(r2wrapped, rewrapped, 'r2wrapped !== rewrapped'); + +assert.sameValue(realm1.evaluate('globalThis.count'), 0, `getting wrapped function won't trigger a call`); + +assert.sameValue(r2wrapped(), 1, 'call from r2 wrapped (r2wrapped) cycles back to r1'); + +assert.sameValue(realm1.evaluate('globalThis.count'), 1, 'effects produced in a third realm, #1'); + +assert.sameValue(rewrapped(), 2, 'call from r2 wrapped (rewrapped) cycles back to r1'); + +assert.sameValue(realm1.evaluate('globalThis.count'), 2, 'effects produced in a third realm, #2'); + +assert.sameValue(realm2.evaluate('globalThis.count'), 0, 'no side effects produced in the wrong realm (realm2)'); +assert.sameValue(globalThis.count, 0, 'no side effects produced in the wrong realm (main realm)'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-observing-their-scopes.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-observing-their-scopes.js new file mode 100644 index 0000000000..a3aabb4612 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-observing-their-scopes.js @@ -0,0 +1,37 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate wrapped function observing their scopes +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); +let myValue; + +function blueFn(x) { + myValue = x; + return myValue; +} + +// cb is a new function in the red ShadowRealm that chains the call to the blueFn +const redFunction = r.evaluate(` + var myValue = 'red'; + 0, function(cb) { + cb(42); + return myValue; + }; +`); + +assert.sameValue(redFunction(blueFn), 'red'); +assert.sameValue(myValue, 42); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-proto-from-caller-realm.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-proto-from-caller-realm.js new file mode 100644 index 0000000000..541dbddf2f --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-proto-from-caller-realm.js @@ -0,0 +1,56 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Chengzhong Wu. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + WrappedFunctionCreate should create a function derived from the caller realm +info: | + ShadowRealm.prototype.evaluate ( sourceText ) + ... + 4. Let callerRealm be the current Realm Record. + 5. Let evalRealm be O.[[ShadowRealm]]. + 6. Return ? PerformRealmEval(sourceText, callerRealm, evalRealm). + + PerformRealmEval ( sourceText, callerRealm, evalRealm ) + ... + 25. Return ? GetWrappedValue(callerRealm, result). + + GetWrappedValue ( callerRealm, value ) + ... + 2.b. Return ? WrappedFunctionCreate(callerRealm, value). + + WrappedFunctionCreate ( callerRealm, targetFunction ) + ... + 5. Set obj.[[Prototype]] to callerRealm.[[Intrinsics]].[[%Function.prototype%]]. +features: [ShadowRealm, cross-realm, Reflect] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +var other = $262.createRealm().global; +var OtherShadowRealm = other.ShadowRealm; +var OtherFunctionPrototype = other.Function.prototype; + +var yetAnother = $262.createRealm().global; +var YetAnotherShadowRealm = yetAnother.ShadowRealm; +var YetAnotherFunctionPrototype = yetAnother.Function.prototype; + +var realm = Reflect.construct(OtherShadowRealm, []); + +var checkArgWrapperFn = realm.evaluate('(x) => { return Object.getPrototypeOf(x) === Function.prototype }') +assert.sameValue(checkArgWrapperFn(() => {}), true, 'callable arguments passed into WrappedFunction should be wrapped in target realm'); + +var fn = realm.evaluate('() => { return () => { return 1 } }'); +assert.sameValue(Object.getPrototypeOf(fn), OtherFunctionPrototype, 'WrappedFunction should be derived from the caller realm'); +assert.sameValue(Object.getPrototypeOf(fn()), OtherFunctionPrototype, 'callable results from WrappedFunction should be wrapped in caller realm'); + +var fn = YetAnotherShadowRealm.prototype.evaluate.call(realm, '() => { return () => { return 1 } }'); +assert.sameValue(Object.getPrototypeOf(fn), YetAnotherFunctionPrototype, 'WrappedFunction should be derived from the caller realm'); +assert.sameValue(Object.getPrototypeOf(fn()), YetAnotherFunctionPrototype, 'callable results from WrappedFunction should be wrapped in caller realm'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-proxied-observes-boundary.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-proxied-observes-boundary.js new file mode 100644 index 0000000000..aa4f03896a --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-proxied-observes-boundary.js @@ -0,0 +1,44 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + Proxying a wrapped function and invoking it still performs boundary checks +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +const wrapped = r.evaluate(`() => { return 1; };`); + +const secretObj = {x: 2}; + +let received; + +const proxiedWrapped = new Proxy(wrapped, { + apply(target, _, args) { + assert.sameValue(target, wrapped); + received = args; + + // Object can't be sent to the other Realm + return target({x: 1}); + } +}); + +assert.throws( + TypeError, + () => proxiedWrapped(secretObj), + 'Proxying a wrapped function and invoking it still performs boundary checks' +); + +assert.sameValue(received[0], secretObj, 'proxy still calls the handler trap'); +assert.sameValue(received.length, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-throws-typeerror-from-caller-realm.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-throws-typeerror-from-caller-realm.js new file mode 100644 index 0000000000..bb5ed49fac --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-throws-typeerror-from-caller-realm.js @@ -0,0 +1,42 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Chengzhong Wu. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-wrapped-function-exotic-objects-call-thisargument-argumentslist +description: > + WrappedFunction throws a TypeError from its creation realm. +features: [ShadowRealm, cross-realm, Reflect] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +var other = $262.createRealm().global; +var OtherTypeError = other.TypeError; +var OtherShadowRealm = other.ShadowRealm; + +var yetAnother = $262.createRealm().global; +var YetAnotherTypeError = yetAnother.TypeError; +var YetAnotherShadowRealm = yetAnother.ShadowRealm; + +var realm = Reflect.construct(OtherShadowRealm, []); + +{ + let wrappedFunction = realm.evaluate('() => {}'); + let wrappedFunction2 = realm.evaluate('() => globalThis'); + + assert.throws(OtherTypeError, () => wrappedFunction(1, globalThis), 'throws TypeError if arguments are not wrappable'); + assert.throws(OtherTypeError, () => wrappedFunction2(), 'throws TypeError if return value is not wrappable'); +} + +{ + let wrappedFunction = YetAnotherShadowRealm.prototype.evaluate.call(realm, '() => {}'); + let wrappedFunction2 = YetAnotherShadowRealm.prototype.evaluate.call(realm, '() => globalThis'); + assert.throws(YetAnotherTypeError, () => wrappedFunction(1, globalThis), 'throws TypeError if arguments are not wrappable'); + assert.throws(YetAnotherTypeError, () => wrappedFunction2(), 'throws TypeError if return value is not wrappable'); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-throws-typeerror-on-exceptional-exit.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-throws-typeerror-on-exceptional-exit.js new file mode 100644 index 0000000000..205d256278 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-throws-typeerror-on-exceptional-exit.js @@ -0,0 +1,42 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Igalia SL. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-wrapped-function-exotic-objects-call-thisargument-argumentslist +description: > + WrappedFunction throws a TypeError if the wrapped function throws. +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +assert.sameValue( + r.evaluate(`(f) => { + try { + f(); + } catch (e) { + if (e instanceof TypeError) { + return 'ok'; + } else { + return e.toString(); + } + } + return 'normal exit'; + }`)(() => { throw Error("ahh"); }), + 'ok', + 'WrappedFunction throws TypeError (from the calling realm) if the wrapped callable throws any exception' +); + +assert.throws( + TypeError, + () => r.evaluate('() => { throw new Error("ahh"); }')(), + 'WrappedFunction throws TypeError if the wrapped callable throws any exception' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-throws-typeerror-on-non-primitive-arguments.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-throws-typeerror-on-non-primitive-arguments.js new file mode 100644 index 0000000000..2f61961521 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-throws-typeerror-on-non-primitive-arguments.js @@ -0,0 +1,36 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Chengzhong Wu. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-wrapped-function-exotic-objects-call-thisargument-argumentslist +description: > + WrappedFunction throws a TypeError if any of the arguments are non-primitive +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); +const wrappedFunction = r.evaluate('() => {}'); + +assert.sameValue( + typeof wrappedFunction, + 'function', + 'This test must fail if wrappedFunction is not a function' +); + +assert.throws(TypeError, () => wrappedFunction(1, globalThis), 'globalThis'); +assert.throws(TypeError, () => wrappedFunction(1, []), 'array literal'); +assert.throws(TypeError, () => wrappedFunction(1, { + [Symbol.toPrimitive]() { return 'string'; }, + toString() { return 'str'; }, + valueOf() { return 1; } +}), 'object literal with immediate primitive coercion methods'); +assert.throws(TypeError, () => wrappedFunction(1, Object.create(null)), 'ordinary object with null __proto__'); +assert.throws(TypeError, () => wrappedFunction(1, new Proxy({}, { apply() {} })), 'non-callable proxy'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-throws-typeerror-on-non-primitive-returns.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-throws-typeerror-on-non-primitive-returns.js new file mode 100644 index 0000000000..13e1427641 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-throws-typeerror-on-non-primitive-returns.js @@ -0,0 +1,31 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Chengzhong Wu. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-wrapped-function-exotic-objects-call-thisargument-argumentslist +description: > + WrappedFunction throws a TypeError if it returns non-primitive values +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +assert.throws(TypeError, r.evaluate('() => globalThis'), 'globalThis'); +assert.throws(TypeError, r.evaluate('() => []'), 'array literal'); +assert.throws(TypeError, r.evaluate(` + () => ({ + [Symbol.toPrimitive]() { return 'string'; }, + toString() { return 'str'; }, + valueOf() { return 1; } + }); +`), 'object literal with immediate primitive coercion methods'); +assert.throws(TypeError, r.evaluate('() => Object.create(null)'), 'ordinary object with null __proto__'); +assert.throws(TypeError, r.evaluate('() => new Proxy({}, { apply() {} })'), 'non-callable proxy'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-accepts-callable-objects.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-accepts-callable-objects.js new file mode 100644 index 0000000000..2e03d9e218 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-accepts-callable-objects.js @@ -0,0 +1,27 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate accepts callable objects +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +assert.sameValue(typeof r.evaluate('function fn() {} fn'), 'function', 'value from a fn declaration'); +assert.sameValue(typeof r.evaluate('(function() {})'), 'function', 'function expression'); +assert.sameValue(typeof r.evaluate('(async function() {})'), 'function', 'async function expression'); +assert.sameValue(typeof r.evaluate('(function*() {})'), 'function', 'generator expression'); +assert.sameValue(typeof r.evaluate('(async function*() {})'), 'function', 'async generator expression'); +assert.sameValue(typeof r.evaluate('() => {}'), 'function', 'arrow function'); +assert.sameValue(typeof r.evaluate('new Proxy(() => {}, { apply() {} })'), 'function', 'callable proxy'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-can-resolve-callable-returns.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-can-resolve-callable-returns.js new file mode 100644 index 0000000000..ae3fa80d05 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-can-resolve-callable-returns.js @@ -0,0 +1,28 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate wrapped functions can resolve callable returns. +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +const wrapped = r.evaluate('x => y => x * y'); +const nestedWrapped = wrapped(2); +const otherNestedWrapped = wrapped(4); + +assert.sameValue(otherNestedWrapped(3), 12); +assert.sameValue(nestedWrapped(3), 6); + +assert.notSameValue(nestedWrapped, otherNestedWrapped, 'new wrapping for each return'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-new-wrapping-on-each-evaluation.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-new-wrapping-on-each-evaluation.js new file mode 100644 index 0000000000..982244c361 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-new-wrapping-on-each-evaluation.js @@ -0,0 +1,32 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate wrapped functions produce new wrapping on each evaluation. +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +r.evaluate(` +function fn() { + return 42; +} +`); + +const wrapped = r.evaluate('fn'); +const otherWrapped = r.evaluate('fn'); + +assert.notSameValue(wrapped, otherWrapped); +assert.sameValue(typeof wrapped, 'function'); +assert.sameValue(typeof otherWrapped, 'function'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-share-no-properties-extended.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-share-no-properties-extended.js new file mode 100644 index 0000000000..d326551db0 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-share-no-properties-extended.js @@ -0,0 +1,70 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate wrapped functions share no properties, extended +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +r.evaluate(` +function fn() { return 42; } +globalThis.arrow = x => x * 2; +globalThis.pFn = new Proxy(fn, { + apply() { + pFn.used = 1; + return 39; + } +}); +async function aFn() { + return 1; +} + +function * genFn() { + return 1; +} + +fn.x = 'secrets'; +arrow.x = 'secrets'; +pFn.x = 'secrets'; +aFn.x = 'secrets'; +genFn.x = 'secrets'; +`); + +const wrappedOrdinary = r.evaluate('fn'); +assert.sameValue(typeof wrappedOrdinary, 'function', 'ordinary function wrapped'); +assert.sameValue(wrappedOrdinary(), 42, 'ordinary, return'); +assert.sameValue(wrappedOrdinary.x, undefined, 'ordinary, no property shared'); + +const wrappedArrow = r.evaluate('arrow'); +assert.sameValue(typeof wrappedArrow, 'function', 'arrow function wrapped'); +assert.sameValue(wrappedArrow(7), 14, 'arrow function, return'); +assert.sameValue(wrappedArrow.x, undefined, 'arrow function, no property'); + +const wrappedProxied = r.evaluate('pFn'); +assert.sameValue(typeof wrappedProxied, 'function', 'proxied ordinary function wrapped'); +assert.sameValue(r.evaluate('pFn.used'), undefined, 'pFn not called yet'); +assert.sameValue(wrappedProxied(), 39, 'return of the proxied callable'); +assert.sameValue(r.evaluate('pFn.used'), 1, 'pfn called'); +assert.sameValue(wrappedProxied.x, undefined, 'proxy callable, no property'); + +const wrappedAsync = r.evaluate('aFn'); +assert.sameValue(typeof wrappedAsync, 'function', 'async function wrapped'); +assert.throws(TypeError, () => wrappedAsync(), 'wrapped function cannot return non callable object'); +assert.sameValue(wrappedAsync.x, undefined, 'async fn, no property'); + +const wrappedGenerator = r.evaluate('genFn'); +assert.sameValue(typeof wrappedGenerator, 'function', 'gen function wrapped'); +assert.throws(TypeError, () => wrappedGenerator(), 'wrapped function cannot return non callable object'); +assert.sameValue(wrappedGenerator.x, undefined, 'generator, no property'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-share-no-properties.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-share-no-properties.js new file mode 100644 index 0000000000..2f1744b1aa --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/evaluate/wrapped-functions-share-no-properties.js @@ -0,0 +1,31 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + ShadowRealm.prototype.evaluate wrapped functions share no properties +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +const wrapped = r.evaluate(` +function fn() { + return fn.secret; +} + +fn.secret = 'confidential'; +fn; +`); + +assert.sameValue(wrapped.secret, undefined); +assert.sameValue(wrapped(), 'confidential'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/browser.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/browser.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/descriptor.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/descriptor.js new file mode 100644 index 0000000000..edde58a6f5 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/descriptor.js @@ -0,0 +1,18 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.importvalue +description: > + ShadowRealm.prototype.importValue is an ECMAScript Standard built-in object function. +includes: [propertyHelper.js] +features: [ShadowRealm] +---*/ + +verifyProperty(ShadowRealm.prototype, "importValue", { + enumerable: false, + writable: true, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/import-value.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/import-value.js new file mode 100644 index 0000000000..1c5c00d42e --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/import-value.js @@ -0,0 +1,24 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) module async -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.importvalue +description: > + ShadowRealm.prototype.importValue can import a value. +flags: [async, module] +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.importValue, + 'function', + 'This test must fail if ShadowRealm.prototype.importValue is not a function' +); + +const r = new ShadowRealm(); + +r.importValue('./import-value_FIXTURE.js', 'x').then(x => { + + assert.sameValue(x, 1); + +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/import-value_FIXTURE.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/import-value_FIXTURE.js new file mode 100644 index 0000000000..aae6bd73cd --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/import-value_FIXTURE.js @@ -0,0 +1,5 @@ +// |reftest| skip -- not a test file +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +export var x = 1; diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/import-value_syntax_error_FIXTURE.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/import-value_syntax_error_FIXTURE.js new file mode 100644 index 0000000000..7e0b9c2e84 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/import-value_syntax_error_FIXTURE.js @@ -0,0 +1,5 @@ +// |reftest| skip -- not a test file +// Copyright (C) 2021 Chengzhong Wu. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +This is an invalid JavaScript Module file. diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/import-value_throws_FIXTURE.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/import-value_throws_FIXTURE.js new file mode 100644 index 0000000000..152521f5ae --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/import-value_throws_FIXTURE.js @@ -0,0 +1,5 @@ +// |reftest| skip -- not a test file +// Copyright (C) 2021 Chengzhong Wu. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +throw new Error('foobar'); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/length.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/length.js new file mode 100644 index 0000000000..8c8222d16f --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/length.js @@ -0,0 +1,29 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.importvalue +description: > + The value of ShadowRealm.prototype.importValue.length is 2 +info: | + Every built-in function object, including constructors, has a "length" property + whose value is a non-negative integral Number. Unless otherwise specified, this value + is equal to the number of required parameters shown in the subclause heading for the + function description. Optional parameters and rest parameters are not included in + the parameter count. + + Unless otherwise specified, the "length" property of a built-in function object has + the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. + +includes: [propertyHelper.js] +features: [ShadowRealm] +---*/ + +verifyProperty(ShadowRealm.prototype.importValue, "length", { + value: 2, + enumerable: false, + writable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/name.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/name.js new file mode 100644 index 0000000000..990b7a469b --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/name.js @@ -0,0 +1,30 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.importValue +description: > + The value of ShadowRealm.prototype.importValue.name is 'importValue' +info: | + ShadowRealm.prototype.importValue + + Every built-in function object, including constructors, has a "name" property + whose value is a String. Unless otherwise specified, this value is the name + that is given to the function in this specification. + + Unless otherwise specified, the "name" property of a built-in function + object has the attributes + { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. + +includes: [propertyHelper.js] +features: [ShadowRealm] +---*/ + +verifyProperty(ShadowRealm.prototype.importValue, "name", { + value: "importValue", + enumerable: false, + writable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/not-constructor.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/not-constructor.js new file mode 100644 index 0000000000..3699c2f85f --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/not-constructor.js @@ -0,0 +1,34 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.importvalue +description: > + ShadowRealm.prototype.importValue is not a constructor. +includes: [isConstructor.js] +features: [ShadowRealm, Reflect.construct] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.importValue, + 'function', + 'This test must fail if ShadowRealm.prototype.importValue is not a function' +); + +assert.sameValue( + isConstructor(ShadowRealm.prototype.importValue), + false, + 'isConstructor(ShadowRealm.prototype.importValue) must return false' +); + +assert.throws(TypeError, () => { + new ShadowRealm.prototype.importValue("", "name"); +}, '`new ShadowRealm.prototype.importValue("")` throws TypeError'); + +const r = new ShadowRealm(); + +assert.throws(TypeError, () => { + new r.importValue("./import-value_FIXTURE.js", "x"); +}, '`new r.importValue("...")` throws TypeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/proto.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/proto.js new file mode 100644 index 0000000000..7f804e4b08 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/proto.js @@ -0,0 +1,18 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.importvalue +description: > + The [[Prototype]] of ShadowRealm.prototype.importValue is AsyncFunction.Prototype. +info: | + Unless otherwise specified every built-in function and every built-in constructor + has the Function prototype object, which is the initial value of the expression + Function.prototype, as the value of its [[Prototype]] internal slot. + +features: [ShadowRealm] +---*/ + +assert.sameValue(Object.getPrototypeOf(ShadowRealm.prototype.importValue), Function.prototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/shell.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/shell.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/specifier-tostring.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/specifier-tostring.js new file mode 100644 index 0000000000..ec3e17ccd5 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/specifier-tostring.js @@ -0,0 +1,76 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.importvalue +description: > + ShadowRealm.prototype.importValue coerces specifier to string. +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.importValue, + 'function', + 'This test must fail if ShadowRealm.prototype.importValue is not a function' +); + +const r = new ShadowRealm(); +let count = 0; + +const specifier = Object.create(null); + +// A - valueOF + +specifier.valueOf = function() { + count += 1; + throw new Test262Error(); +}; + +assert.throws(Test262Error, () => { + r.importValue(specifier); +}, 'ToString(specifier) returns abrupt from valueOf'); + +assert.sameValue(count, 1, 'ToString calls the valueOf method'); + + +// B - toString + +count = 0; + +specifier.valueOf = function() { + count += 1000; + throw new Error('valueOf is not reached if toString is present'); +}; + +specifier.toString = function() { + count += 1; + throw new Test262Error(); +}; + +assert.throws(Test262Error, () => { + r.importValue(specifier); +}, 'ToString(specifier) returns abrupt from toString'); + +assert.sameValue(count, 1, 'ToString calls the toString method'); + +// C - @@toPrimitive + +count = 0; + +specifier[Symbol.toPrimitive] = function() { + count += 1; + throw new Test262Error(); +}; + +specifier.toString = function() { + count += 1000; + throw new Error('toString is not reached if @@toPrimitive is present'); +}; + +assert.throws(Test262Error, () => { + r.importValue(specifier); +}, 'ToString(specifier) returns abrupt from @@toPrimitive'); + +assert.sameValue(count, 1, 'ToString calls the @@toPrimitive method'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-if-exportname-not-string.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-if-exportname-not-string.js new file mode 100644 index 0000000000..19afa8e502 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-if-exportname-not-string.js @@ -0,0 +1,33 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.importvalue +description: > + ShadowRealm.prototype.importValue throws if exportName is not a string. +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.importValue, + 'function', + 'This test must fail if ShadowRealm.prototype.importValue is not a function' +); + +const r = new ShadowRealm(); +let count = 0; + +const exportName = { + toString() { + count += 1; + throw new Test262Error(); + } +}; + +assert.throws(TypeError, () => { + r.importValue('', exportName); +}); + +assert.sameValue(count, 0); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-if-import-value-does-not-exist.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-if-import-value-does-not-exist.js new file mode 100644 index 0000000000..314c206808 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-if-import-value-does-not-exist.js @@ -0,0 +1,59 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) module async -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-realmimportvalue +description: > + ShadowRealm.prototype.importValue rejects when export name does not exist +info: | + RealmImportValue ( specifierString, exportNameString, callerRealm, evalRealm, evalContext ) + + Assert: Type(specifierString) is String. + Assert: Type(exportNameString) is String. + Assert: callerRealm is a ShadowRealm Record. + Assert: evalRealm is a ShadowRealm Record. + Assert: evalContext is an execution context associated to a ShadowRealm instance's [[ExecutionContext]]. + Let innerCapability be ! NewPromiseCapability(%Promise%). + Let runningContext be the running execution context. + If runningContext is not already suspended, suspend runningContext. + Push evalContext onto the execution context stack; evalContext is now the running execution context. + Perform ! HostImportModuleDynamically(null, specifierString, innerCapability). + Suspend evalContext and remove it from the execution context stack. + Resume the context that is now on the top of the execution context stack as the running + execution context. + Let steps be the steps of an ExportGetter function as described below. + + An ExportGetter function is an anonymous built-in function with a [[ExportNameString]] + internal slot. When an ExportGetter function is called with argument exports, + it performs the following steps: + + Assert: exports is a module namespace exotic object. + Let f be the active function object. + Let string be f.[[ExportNameString]]. + Assert: Type(string) is String. + Let hasOwn be ? HasOwnProperty(exports, string). + If hasOwn is false, throw a TypeError exception. + ... + +flags: [async, module] +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.importValue, + 'function', + 'This test must fail if ShadowRealm.prototype.importValue is not a function' +); + +const r = new ShadowRealm(); + +r.importValue('./import-value_FIXTURE.js', 'y') + .then( + () => { + throw new Test262Error("Expected rejection"); + }, + err => { + assert.sameValue(Object.getPrototypeOf(err), TypeError.prototype, 'should be rejected with TypeError'); + } + ) + .then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-typeerror-import-syntax-error.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-typeerror-import-syntax-error.js new file mode 100644 index 0000000000..d47d884993 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-typeerror-import-syntax-error.js @@ -0,0 +1,35 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) module async -- requires shell-options +// Copyright (C) 2021 Chengzhong Wu. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-realmimportvalue +description: > + ShadowRealm.prototype.importValue rejects with TypeError when the imported script unable to be parsed. +info: | + RealmImportValue ( specifierString, exportNameString, callerRealm, evalRealm, evalContext ) + + ... + 17. Return ! PerformPromiseThen(innerCapability.[[Promise]], onFulfilled, callerRealm.[[Intrinsics]].[[%ThrowTypeError%]], promiseCapability). + +flags: [async, module] +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.importValue, + 'function', + 'This test must fail if ShadowRealm.prototype.importValue is not a function' +); + +const r = new ShadowRealm(); + +r.importValue('./import-value_syntax_error_FIXTURE.js', 'y') + .then( + () => { + throw new Test262Error("unreachable"); + }, + err => { + assert.sameValue(Object.getPrototypeOf(err), TypeError.prototype, 'should be rejected with TypeError'); + } + ) + .then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-typeerror-import-throws.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-typeerror-import-throws.js new file mode 100644 index 0000000000..ea48b0a00a --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/throws-typeerror-import-throws.js @@ -0,0 +1,35 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) module async -- requires shell-options +// Copyright (C) 2021 Chengzhong Wu. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-realmimportvalue +description: > + ShadowRealm.prototype.importValue rejects with TypeError when the imported script throws. +info: | + RealmImportValue ( specifierString, exportNameString, callerRealm, evalRealm, evalContext ) + + ... + 17. Return ! PerformPromiseThen(innerCapability.[[Promise]], onFulfilled, callerRealm.[[Intrinsics]].[[%ThrowTypeError%]], promiseCapability). + +flags: [async, module] +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.importValue, + 'function', + 'This test must fail if ShadowRealm.prototype.importValue is not a function' +); + +const r = new ShadowRealm(); + +r.importValue('./import-value_throws_FIXTURE.js', 'y') + .then( + () => { + throw new Test262Error("unreachable"); + }, + err => { + assert.sameValue(Object.getPrototypeOf(err), TypeError.prototype, 'should be rejected with TypeError'); + } + ) + .then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/validates-realm-object.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/validates-realm-object.js new file mode 100644 index 0000000000..dffc3a1682 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/importValue/validates-realm-object.js @@ -0,0 +1,24 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.importvalue +description: > + ShadowRealm.prototype.importValue validates realm object. +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.importValue, + 'function', + 'This test must fail if ShadowRealm.prototype.importValue is not a function' +); + +const r = new ShadowRealm(); +const bogus = {}; + +assert.throws(TypeError, function() { + r.importValue.call(bogus, "specifier", "name"); +}, 'throws a TypeError if this is not a ShadowRealm object'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/proto.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/proto.js new file mode 100644 index 0000000000..c071e06ab5 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/prototype/proto.js @@ -0,0 +1,18 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) -- requires shell-options +// Copyright (C) 2021 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-properties-of-the-realm-prototype-object +description: > + The [[Prototype]] of ShadowRealm.prototype is Object.Prototype. +info: | + Unless otherwise specified every built-in prototype object has the Object prototype + object, which is the initial value of the expression Object.prototype, as the value + of its [[Prototype]] internal slot, except the Object prototype object itself. + +features: [ShadowRealm] +---*/ + +assert.sameValue(Object.getPrototypeOf(ShadowRealm.prototype), Object.prototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/ShadowRealm/prototype/shell.js b/js/src/tests/test262/built-ins/ShadowRealm/prototype/shell.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/src/tests/test262/built-ins/ShadowRealm/shell.js b/js/src/tests/test262/built-ins/ShadowRealm/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/ShadowRealm/shell.js @@ -0,0 +1,24 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} -- cgit v1.2.3