Skip to content
Permalink
Browse files
[JSC] Fix ShadowRealm test262 failures
https://bugs.webkit.org/show_bug.cgi?id=244572

Reviewed by Ross Kirsling.

1. We should check exportName's type of importValue.
2. copyNameAndLength should perform GetOwnProperty, and if the slot is isTaintedByOpaqueObject (e.g. Proxy), we should do [[Get]] after that.

* JSTests/test262/expectations.yaml:
* Source/JavaScriptCore/builtins/ShadowRealmPrototype.js:
(linkTimeConstant.wrapRemoteValue):
(evaluate):
(linkTimeConstant.crossRealmThrow):
(importValue):
(linkTimeConstant.wrap): Deleted.
* Source/JavaScriptCore/runtime/JSRemoteFunction.cpp:
(JSC::JSRemoteFunction::copyNameAndLength):

Canonical link: https://commits.webkit.org/253977@main
  • Loading branch information
Constellation committed Aug 31, 2022
1 parent 482480f commit 9f1858ab127db7e2cf0f386203842deb795353a3
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 25 deletions.
@@ -207,7 +207,7 @@ f = realm.evaluate(`(() => {
let p = new Proxy(target, {
getOwnPropertyDescriptor(t, p) {
log(\`getOwnPropertyDescriptor \${p}\`);
return Reflect.getOwnProperty(...arguments);
return Reflect.getOwnPropertyDescriptor(...arguments);
},
get(t, p) {
log(\`get \${p}\`);
@@ -299,6 +299,7 @@ shouldHaveDescriptor(f, "name", {
configurable: true,
});
shouldBe(log(), [
"getOwnPropertyDescriptor length",
"get length",
"length getter",
"get name",
@@ -316,7 +317,7 @@ f = realm.evaluate(`(() => {
let p = new Proxy(target, {
getOwnPropertyDescriptor(t, p) {
log(\`getOwnPropertyDescriptor \${p}\`);
return Reflect.getOwnProperty(...arguments);
return Reflect.getOwnPropertyDescriptor(...arguments);
},
get(t, p) {
log(\`get \${p}\`);
@@ -394,6 +395,7 @@ shouldHaveDescriptor(f, "name", {
configurable: true,
});
shouldBe(log(), [
"getOwnPropertyDescriptor length",
"get length",
"get name",
"apply",
@@ -822,12 +822,6 @@ test/built-ins/RegExp/prototype/exec/u-lastindex-adv.js:
test/built-ins/RegExp/quantifier-integer-limit.js:
default: 'SyntaxError: Invalid regular expression: number too large in {} quantifier'
strict mode: 'SyntaxError: Invalid regular expression: number too large in {} quantifier'
test/built-ins/ShadowRealm/prototype/evaluate/throws-typeerror-wrap-throwing.js:
default: 'Test262Error: TypeError on wrapping a callable proxy with throwing getOwnPropertyDescriptor trap Expected a TypeError to be thrown but no exception was thrown at all'
strict mode: 'Test262Error: TypeError on wrapping a callable proxy with throwing getOwnPropertyDescriptor trap Expected a TypeError to be thrown but no exception was thrown at all'
test/built-ins/ShadowRealm/prototype/importValue/throws-if-exportname-not-string.js:
default: 'Test262Error: Expected a TypeError but got a Test262Error'
strict mode: 'Test262Error: Expected a TypeError but got a Test262Error'
test/built-ins/Temporal/Instant/prototype/since/largestunit.js:
default: 'Test262Error: does not include higher units than necessary (largest unit unspecified) nanoseconds result Expected SameValue(«40», «101») to be true'
strict mode: 'Test262Error: does not include higher units than necessary (largest unit unspecified) nanoseconds result Expected SameValue(«40», «101») to be true'
@@ -27,15 +27,16 @@
// if `fromShadowRealm` is false, we are wrapping an object from the incubating
// realm; if true, we are wrapping an object from the shadow realm
@linkTimeConstant
function wrap(fromShadowRealm, shadowRealm, target)
function wrapRemoteValue(fromShadowRealm, shadowRealm, target)
{
"use strict";

if (@isCallable(target)) {
if (@isCallable(target))
return @createRemoteFunction(target, fromShadowRealm ? null : shadowRealm);
} else if (@isObject(target)) {

if (@isObject(target))
@throwTypeError("value passing between realms must be callable or primitive");
}

return target;
}

@@ -49,8 +50,16 @@ function evaluate(sourceText)
if (typeof sourceText !== 'string')
@throwTypeError("`%ShadowRealm%.evaluate requires that the |sourceText| argument be a string");

var result = @evalInRealm(this, sourceText)
return @wrap(true, this, result);
return @wrapRemoteValue(true, this, @evalInRealm(this, sourceText));
}

@linkTimeConstant
function crossRealmThrow(error)
{
"use strict";

// re-throw because import issues raise errors using the realm's global object
@throwTypeError(@toString(error));
}

function importValue(specifier, exportName)
@@ -60,21 +69,18 @@ function importValue(specifier, exportName)
if (!@isShadowRealm(this))
@throwTypeError("`%ShadowRealm%.importValue requires that |this| be a ShadowRealm instance");

var exportNameString = @toString(exportName);
var specifierString = @toString(specifier);

if (typeof exportName !== 'string')
@throwTypeError("`%ShadowRealm%.importValue requires that the |exportName| argument be a string");

var lookupBinding = (module) => {
var lookup = module[exportNameString]
var lookup = module[exportName]
if (lookup === @undefined)
@throwTypeError("%ShadowRealm%.importValue requires |exportName| to exist in the |specifier|");

return @wrap(true, this, lookup);
};

var crossRealmThrow = (error) => {
// re-throw because import issues raise errors using the realm's global object
@throwTypeError(@toString(error));
return @wrapRemoteValue(true, this, lookup);
};

return @importInRealm(this, specifierString).@then(lookupBinding, crossRealmThrow);
return @importInRealm(this, specifierString).@then(lookupBinding, @crossRealmThrow);
}
@@ -207,12 +207,16 @@ void JSRemoteFunction::copyNameAndLength(JSGlobalObject* globalObject)
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

PropertySlot slot(m_targetFunction.get(), PropertySlot::InternalMethodType::Get);
PropertySlot slot(m_targetFunction.get(), PropertySlot::InternalMethodType::GetOwnProperty);
bool targetHasLength = m_targetFunction->getOwnPropertySlotInline(globalObject, vm.propertyNames->length, slot);
RETURN_IF_EXCEPTION(scope, void());

if (targetHasLength) {
JSValue targetLength = slot.getValue(globalObject, vm.propertyNames->length);
JSValue targetLength;
if (LIKELY(!slot.isTaintedByOpaqueObject()))
targetLength = slot.getValue(globalObject, vm.propertyNames->length);
else
targetLength = m_targetFunction->get(globalObject, vm.propertyNames->length);
RETURN_IF_EXCEPTION(scope, void());
double targetLengthAsInt = targetLength.toIntegerOrInfinity(globalObject);
RETURN_IF_EXCEPTION(scope, void());

0 comments on commit 9f1858a

Please sign in to comment.