Changeset 286069 in webkit
- Timestamp:
- Nov 19, 2021, 11:17:04 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/stress/shadow-realm-evaluate.js (modified) (4 diffs)
-
JSTests/test262/expectations.yaml (modified) (1 diff)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/builtins/BuiltinNames.h (modified) (1 diff)
-
Source/JavaScriptCore/builtins/ShadowRealmPrototype.js (modified) (4 diffs)
-
Source/JavaScriptCore/bytecode/LinkTimeConstant.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSGlobalObject.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/ShadowRealmPrototype.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/ShadowRealmPrototype.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r286060 r286069 1 2021-11-19 Joseph Griego <jgriego@igalia.com> 2 3 [JSC] Shadow realms: set correct Function prototype on wrapped functions 4 https://bugs.webkit.org/show_bug.cgi?id=233143 5 6 Reviewed by Yusuke Suzuki. 7 8 At present, the Function prototype set on each of the returned wrapped 9 functions will be the Function object from the realm the shadow realm 10 builtin is from--to comply with the latest draft of the shadow realms 11 spec [1], wrapped function objects should have the Function prototype 12 from the realm the wrapper object is destined for, instead. 13 14 At present, this requires tracking both the calling (destination) and 15 target (source) realm and switching between the two as function 16 arguments are wrapped (when the notion of source and destination realm 17 also flips) 18 19 Adds a simple builtin (moveFunctionToRealm) that can switch the Function 20 prototype given only the Shadow Realm object corresponding to the 21 correct global object. 22 23 Also marks the corresponding part of test262 as passing. 24 25 * test262/expectations.yaml: 26 1 27 2021-11-19 Angelos Oikonomopoulos <angelos@igalia.com> 2 28 -
trunk/JSTests/stress/shadow-realm-evaluate.js
r284435 r286069 78 78 shouldBe(wrappedInvokeAndAdd(() => { return 1 }, () => { return 2 }), 3); 79 79 shouldBe($.globalObjectFor(wrappedInvokeAndAdd), globalThis); 80 shouldBe(Object.getPrototypeOf(wrappedInvokeAndAdd), Function.prototype); 80 81 81 82 // name and length properties from wrapped function are absent … … 123 124 shouldBe($.globalObjectFor(f), globalThis); 124 125 shouldBe(f(() => { return 41; }), 42); 126 shouldBe(Object.getPrototypeOf(f), Function.prototype); 125 127 } 126 128 // (potential) inlining of wrapped function uses correct global object … … 129 131 shouldBe($.globalObjectFor(f), globalThis); 130 132 shouldBe(f(() => { return 41; }), 42); 133 shouldBe(Object.getPrototypeOf(f), Function.prototype); 131 134 } 132 135 // (potential) inlining inside a realm uses correct global object … … 152 155 shouldBe(evaluateLength.configurable, true); 153 156 } 157 158 // Enclosing realm is hidden from shaodw realm even when playing Function prototype tricks 159 { 160 let realm = new ShadowRealm(); 161 foo = 42; 162 163 realm.evaluate("foo = false"); 164 165 let realmFn = realm.evaluate(`(f) => { 166 let ourFn = Object.getPrototypeOf(f).constructor; 167 return (new ourFn("return this"))().foo 168 }`); 169 170 let retrievedFoo = realmFn(() => {}); 171 let aFunction = Object.getPrototypeOf(realmFn).constructor; 172 let anotherFoo = (new aFunction("return this"))().foo; 173 174 shouldBe(retrievedFoo, false); 175 shouldBe(anotherFoo, 42); 176 } -
trunk/JSTests/test262/expectations.yaml
r285760 r286069 1138 1138 default: 'SyntaxError: Invalid regular expression: number too large in {} quantifier' 1139 1139 strict mode: 'SyntaxError: Invalid regular expression: number too large in {} quantifier' 1140 test/built-ins/ShadowRealm/prototype/evaluate/wrapped-function-proto-from-caller-realm.js:1141 default: 'Test262Error: callable arguments passed into WrappedFunction should be wrapped in target realm Expected SameValue(«false», «true») to be true'1142 strict mode: 'Test262Error: callable arguments passed into WrappedFunction should be wrapped in target realm Expected SameValue(«false», «true») to be true'1143 1140 test/built-ins/Temporal/Instant/prototype/toString/timezone-offset.js: 1144 1141 default: 'Test262Error: offset of UTC is +00:00 Expected SameValue(«1970-01-01T00:00:00Z», «1970-01-01T00:00:00+00:00») to be true' -
trunk/Source/JavaScriptCore/ChangeLog
r286053 r286069 1 2021-11-19 Joseph Griego <jgriego@igalia.com> 2 3 [JSC] Shadow realms: set correct Function prototype on wrapped functions 4 https://bugs.webkit.org/show_bug.cgi?id=233143 5 6 Reviewed by Yusuke Suzuki. 7 8 At present, the Function prototype set on each of the returned wrapped 9 functions will be the Function object from the realm the shadow realm 10 builtin is from--to comply with the latest draft of the shadow realms 11 spec [1], wrapped function objects should have the Function prototype 12 from the realm the wrapper object is destined for, instead. 13 14 At present, this requires tracking both the calling (destination) and 15 target (source) realm and switching between the two as function 16 arguments are wrapped (when the notion of source and destination realm 17 also flips) 18 19 Adds a simple builtin (moveFunctionToRealm) that can switch the Function 20 prototype given only the Shadow Realm object corresponding to the 21 correct global object. 22 23 Also marks the corresponding part of test262 as passing. 24 25 [1] https://tc39.es/proposal-shadowrealm/ sections 2.1, 2.2 26 27 28 29 * builtins/BuiltinNames.h: 30 * builtins/ShadowRealmPrototype.js: 31 (wrapped): 32 (globalPrivate.wrap): 33 (evaluate): 34 (importValue): 35 (globalPrivate.wrap.wrapped): Deleted. 36 * bytecode/LinkTimeConstant.h: 37 * runtime/JSGlobalObject.cpp: 38 (JSC::JSGlobalObject::init): 39 * runtime/ShadowRealmPrototype.cpp: 40 (JSC::JSC_DEFINE_HOST_FUNCTION): 41 * runtime/ShadowRealmPrototype.h: 42 1 43 2021-11-19 Robin Morisset <rmorisset@apple.com> 2 44 -
trunk/Source/JavaScriptCore/builtins/BuiltinNames.h
r284435 r286069 119 119 macro(importInRealm) \ 120 120 macro(evalInRealm) \ 121 macro(moveFunctionToRealm) \ 121 122 macro(thisTimeValue) \ 122 123 macro(newTargetLocal) \ -
trunk/Source/JavaScriptCore/builtins/ShadowRealmPrototype.js
r284435 r286069 24 24 */ 25 25 26 // Wrap a value at the boundary between the incubating realm and `shadowRealm`: 27 // if `fromShadowRealm` is false, we are wrapping an object from the incubating 28 // realm; if true, we are wrapping an object from the shadow realm 26 29 @globalPrivate 27 function wrap( target)30 function wrap(fromShadowRealm, shadowRealm, target) 28 31 { 29 32 "use strict"; … … 34 37 var wrappedArgs = @newArrayWithSize(length); 35 38 for (var index = 0; index < length; ++index) 36 @putByValDirect(wrappedArgs, index, @wrap(arguments[index])); 39 // Note that for arguments, we flip `fromShadowRealm` since to 40 // wrap a function from realm A to work in realm B, we need to 41 // wrap the arguments (from realm B) to work in realm A before 42 // calling the wrapped function 43 @putByValDirect(wrappedArgs, index, @wrap(!fromShadowRealm, shadowRealm, arguments[index])); 37 44 38 45 var result = target.@apply(@undefined, wrappedArgs); 39 return @wrap( result);46 return @wrap(fromShadowRealm, shadowRealm, result); 40 47 }; 41 48 delete wrapped['name']; 42 49 delete wrapped['length']; 50 51 // Because this function (wrap) will run with the incubating realm 52 // active, we only need to fix the prototype on `wrapped` if we are 53 // moving the function from the incubating realm to the shadow realm 54 if (!fromShadowRealm) 55 @moveFunctionToRealm(wrapped, shadowRealm); 43 56 return wrapped; 44 57 } else if (@isObject(target)) { … … 59 72 60 73 var result = @evalInRealm(this, sourceText) 61 return @wrap( result);74 return @wrap(true, this, result); 62 75 } 63 76 … … 77 90 @throwTypeError("%ShadowRealm%.importValue requires |exportName| to exist in the |specifier|"); 78 91 79 return @wrap( lookup);92 return @wrap(true, this, lookup); 80 93 }; 81 94 -
trunk/Source/JavaScriptCore/bytecode/LinkTimeConstant.h
r284435 r286069 81 81 v(importInRealm, nullptr) \ 82 82 v(evalInRealm, nullptr) \ 83 v(moveFunctionToRealm, nullptr) \ 83 84 v(isConstructor, nullptr) \ 84 85 v(sameValue, nullptr) \ -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r285730 r286069 1461 1461 init.set(JSFunction::create(init.vm, jsCast<JSGlobalObject*>(init.owner), 0, String(), evalInRealm)); 1462 1462 }); 1463 m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::moveFunctionToRealm)].initLater([] (const Initializer<JSCell>& init) { 1464 init.set(JSFunction::create(init.vm, jsCast<JSGlobalObject*>(init.owner), 0, String(), moveFunctionToRealm)); 1465 }); 1463 1466 m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::thisTimeValue)].initLater([] (const Initializer<JSCell>& init) { 1464 1467 init.set(JSFunction::create(init.vm, jsCast<JSGlobalObject*>(init.owner), 0, String(), dateProtoFuncGetTime, DatePrototypeGetTimeIntrinsic)); -
trunk/Source/JavaScriptCore/runtime/ShadowRealmPrototype.cpp
r285195 r286069 125 125 } 126 126 127 JSC_DEFINE_HOST_FUNCTION(moveFunctionToRealm, (JSGlobalObject* globalObject, CallFrame* callFrame)) 128 { 129 VM& vm = globalObject->vm(); 130 auto scope = DECLARE_THROW_SCOPE(vm); 131 132 JSValue wrappedFnArg = callFrame->argument(0); 133 JSFunction* wrappedFn = jsDynamicCast<JSFunction*>(vm, wrappedFnArg); 134 JSValue targetRealmArg = callFrame->argument(1); 135 ShadowRealmObject* targetRealm = jsDynamicCast<ShadowRealmObject*>(vm, targetRealmArg); 136 ASSERT(targetRealm); 137 RETURN_IF_EXCEPTION(scope, { }); 138 139 bool isBuiltin = false; 140 JSGlobalObject* targetGlobalObj = targetRealm->globalObject(); 141 wrappedFn->setPrototype(vm, targetGlobalObj, targetGlobalObj->strictFunctionStructure(isBuiltin)->storedPrototype()); 142 RELEASE_AND_RETURN(scope, JSValue::encode(jsUndefined())); 143 } 144 127 145 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/ShadowRealmPrototype.h
r285730 r286069 64 64 JSC_DECLARE_HOST_FUNCTION(importInRealm); 65 65 JSC_DECLARE_HOST_FUNCTION(evalInRealm); 66 JSC_DECLARE_HOST_FUNCTION(moveFunctionToRealm); 66 67 67 68 } // namespace JSC
Note:
See TracChangeset
for help on using the changeset viewer.