v8/test/mjsunit/harmony/shadowrealm-importvalue.js
legendecas 9135859a91 [ShadowRealm] Implement ShadowRealm.prototype.importValue
As per https://tc39.es/ecma262/#sec-hostimportmoduledynamically defined,
referencingScriptOrModule in HostImportModuleDynamically can be a Script
Record, a Module Record, or null.
So to https://tc39.es/proposal-shadowrealm/#sec-shadowrealmimportvalue,
the HostImportModuleDynamicallyCallback is been invoked with a `null`
resource_name. This may not be considered a breaking change as the
parameter resource_name is defined as Local<Value>.

Updates d8's DoHostImportModuleDynamically to handle null resource_name,
and resolve the dynamically imported specifier relative to the executing
script's origin. In this way, we have to set ModuleEmbedderData.origin
even if the JavaScript source to be evaluated is Script. Also, a
ModuleEmbedderData is created for each ShadowRealm to separate their
module maps from the initiator context's.

Bug: v8:11989
Change-Id: If70fb140657da4f2dd92eedfcc4515211602aa46
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3522883
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Chengzhong Wu <legendecas@gmail.com>
Cr-Commit-Position: refs/heads/main@{#80118}
2022-04-22 15:04:26 +00:00

68 lines
2.4 KiB
JavaScript

// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-shadow-realm --allow-natives-syntax
var shadowRealm = new ShadowRealm();
globalThis.foobar = 'outer-scope';
{
const promise = shadowRealm.importValue('./shadowrealm-skip-1.mjs', 'func');
// Promise is created in caller realm.
assertInstanceof(promise, Promise);
assertPromiseResult(promise.then(func => {
// Check that side-effects in the ShadowRealm not propagated to the caller.
assertEquals(globalThis.foobar, 'outer-scope');
// Check that the func is created in the current Realm.
assertEquals(typeof func, 'function');
assertTrue(func instanceof Function);
// Should return the inner global value.
assertEquals(func(), 'inner-scope');
}));
}
{
const promise = shadowRealm.importValue('./shadowrealm-skip-1.mjs', 'foo');
// Promise is created in caller realm.
assertInstanceof(promise, Promise);
assertPromiseResult(promise.then(foo => {
assertEquals(foo, 'bar');
}));
}
{
const promise = shadowRealm.importValue('./shadowrealm-skip-1.mjs', 'obj');
// Promise is created in caller realm.
assertInstanceof(promise, Promise);
assertThrowsAsync(promise, TypeError, "[object Object] is not a function");
}
{
const promise = shadowRealm.importValue('./shadowrealm-skip-1.mjs', 'not_exists');
// Promise is created in caller realm.
assertInstanceof(promise, Promise);
assertThrowsAsync(promise, TypeError, "The requested module './shadowrealm-skip-1.mjs' does not provide an export named 'not_exists'");
}
{
const promise = shadowRealm.importValue('./shadowrealm-skip-not-found.mjs', 'foo');
// Promise is created in caller realm.
assertInstanceof(promise, Promise);
assertThrowsAsync(promise, TypeError, 'Cannot import in the ShadowRealm');
}
{
const promise = shadowRealm.importValue('./shadowrealm-skip-2-throw.mjs', 'foo');
// Promise is created in caller realm.
assertInstanceof(promise, Promise);
assertThrowsAsync(promise, TypeError, 'Cannot import in the ShadowRealm');
}
// Invalid args
assertThrows(() => ShadowRealm.prototype.importValue.call(1, '', ''), TypeError, 'Method ShadowRealm.prototype.importValue called on incompatible receiver 1')
assertThrows(() => ShadowRealm.prototype.importValue.call({}, '', ''), TypeError, 'Method ShadowRealm.prototype.importValue called on incompatible receiver #<Object>')