Commit 9135859a authored by legendecas's avatar legendecas Committed by V8 LUCI CQ

[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/+/3522883Reviewed-by: 's avatarShu-yu Guo <syg@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Chengzhong Wu <legendecas@gmail.com>
Cr-Commit-Position: refs/heads/main@{#80118}
parent 9ad39743
......@@ -872,7 +872,11 @@ namespace internal {
CPP(ShadowRealmConstructor) \
TFS(ShadowRealmGetWrappedValue, kCreationContext, kTargetContext, kValue) \
CPP(ShadowRealmPrototypeEvaluate) \
CPP(ShadowRealmPrototypeImportValue) \
TFJ(ShadowRealmPrototypeImportValue, kJSArgcReceiverSlots + 2, kReceiver, \
kSpecifier, kExportName) \
TFJ(ShadowRealmImportValueFulfilled, kJSArgcReceiverSlots + 1, kReceiver, \
kExports) \
TFJ(ShadowRealmImportValueRejected, kDontAdaptArgumentsSentinel) \
\
/* SharedArrayBuffer */ \
CPP(SharedArrayBufferPrototypeGetByteLength) \
......
......@@ -216,11 +216,5 @@ BUILTIN(ShadowRealmPrototypeEvaluate) {
return *wrapped_result;
}
// https://tc39.es/proposal-shadowrealm/#sec-shadowrealm.prototype.importvalue
BUILTIN(ShadowRealmPrototypeImportValue) {
HandleScope scope(isolate);
return ReadOnlyRoots(isolate).undefined_value();
}
} // namespace internal
} // namespace v8
......@@ -6,6 +6,8 @@
#include "src/builtins/builtins.h"
#include "src/codegen/code-stub-assembler.h"
#include "src/objects/descriptor-array.h"
#include "src/objects/js-shadow-realms.h"
#include "src/objects/module.h"
namespace v8 {
namespace internal {
......@@ -15,11 +17,27 @@ class ShadowRealmBuiltinsAssembler : public CodeStubAssembler {
explicit ShadowRealmBuiltinsAssembler(compiler::CodeAssemblerState* state)
: CodeStubAssembler(state) {}
enum ImportValueFulfilledFunctionContextSlot {
kEvalContextSlot = Context::MIN_CONTEXT_SLOTS,
kSpecifierSlot,
kExportNameSlot,
kContextLength,
};
protected:
TNode<JSObject> AllocateJSWrappedFunction(TNode<Context> context,
TNode<Object> target);
void CheckAccessor(TNode<DescriptorArray> array, TNode<IntPtrT> index,
TNode<Name> name, Label* bailout);
TNode<Object> ImportValue(TNode<NativeContext> caller_context,
TNode<NativeContext> eval_context,
TNode<String> specifier, TNode<String> export_name);
TNode<Context> CreateImportValueFulfilledFunctionContext(
TNode<NativeContext> caller_context, TNode<NativeContext> eval_context,
TNode<String> specifier, TNode<String> export_name);
TNode<JSFunction> AllocateImportValueFulfilledFunction(
TNode<NativeContext> caller_context, TNode<NativeContext> eval_context,
TNode<String> specifier, TNode<String> export_name);
};
TNode<JSObject> ShadowRealmBuiltinsAssembler::AllocateJSWrappedFunction(
......@@ -35,6 +53,40 @@ TNode<JSObject> ShadowRealmBuiltinsAssembler::AllocateJSWrappedFunction(
return wrapped;
}
TNode<Context>
ShadowRealmBuiltinsAssembler::CreateImportValueFulfilledFunctionContext(
TNode<NativeContext> caller_context, TNode<NativeContext> eval_context,
TNode<String> specifier, TNode<String> export_name) {
const TNode<Context> context = AllocateSyntheticFunctionContext(
caller_context, ImportValueFulfilledFunctionContextSlot::kContextLength);
StoreContextElementNoWriteBarrier(
context, ImportValueFulfilledFunctionContextSlot::kEvalContextSlot,
eval_context);
StoreContextElementNoWriteBarrier(
context, ImportValueFulfilledFunctionContextSlot::kSpecifierSlot,
specifier);
StoreContextElementNoWriteBarrier(
context, ImportValueFulfilledFunctionContextSlot::kExportNameSlot,
export_name);
return context;
}
TNode<JSFunction>
ShadowRealmBuiltinsAssembler::AllocateImportValueFulfilledFunction(
TNode<NativeContext> caller_context, TNode<NativeContext> eval_context,
TNode<String> specifier, TNode<String> export_name) {
const TNode<Context> function_context =
CreateImportValueFulfilledFunctionContext(caller_context, eval_context,
specifier, export_name);
const TNode<Map> function_map = CAST(LoadContextElement(
caller_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX));
const TNode<SharedFunctionInfo> info =
ShadowRealmImportValueFulfilledSFIConstant();
return AllocateFunctionWithMapAndContext(function_map, info,
function_context);
}
void ShadowRealmBuiltinsAssembler::CheckAccessor(TNode<DescriptorArray> array,
TNode<IntPtrT> index,
TNode<Name> name,
......@@ -244,5 +296,131 @@ TF_BUILTIN(CallWrappedFunction, ShadowRealmBuiltinsAssembler) {
Unreachable();
}
// https://tc39.es/proposal-shadowrealm/#sec-shadowrealm.prototype.importvalue
TF_BUILTIN(ShadowRealmPrototypeImportValue, ShadowRealmBuiltinsAssembler) {
const char* const kMethodName = "ShadowRealm.prototype.importValue";
TNode<Context> context = Parameter<Context>(Descriptor::kContext);
// 1. Let O be this value.
TNode<Object> O = Parameter<Object>(Descriptor::kReceiver);
// 2. Perform ? ValidateShadowRealmObject(O).
ThrowIfNotInstanceType(context, O, JS_SHADOW_REALM_TYPE, kMethodName);
// 3. Let specifierString be ? ToString(specifier).
TNode<Object> specifier = Parameter<Object>(Descriptor::kSpecifier);
TNode<String> specifier_string = ToString_Inline(context, specifier);
// 4. Let exportNameString be ? ToString(exportName).
TNode<Object> export_name = Parameter<Object>(Descriptor::kExportName);
TNode<String> export_name_string = ToString_Inline(context, export_name);
// 5. Let callerRealm be the current Realm Record.
TNode<NativeContext> caller_context = LoadNativeContext(context);
// 6. Let evalRealm be O.[[ShadowRealm]].
// 7. Let evalContext be O.[[ExecutionContext]].
TNode<NativeContext> eval_context =
CAST(LoadObjectField(CAST(O), JSShadowRealm::kNativeContextOffset));
// 8. Return ? ShadowRealmImportValue(specifierString, exportNameString,
// callerRealm, evalRealm, evalContext).
TNode<Object> result = ImportValue(caller_context, eval_context,
specifier_string, export_name_string);
Return(result);
}
// https://tc39.es/proposal-shadowrealm/#sec-shadowrealmimportvalue
TNode<Object> ShadowRealmBuiltinsAssembler::ImportValue(
TNode<NativeContext> caller_context, TNode<NativeContext> eval_context,
TNode<String> specifier, TNode<String> export_name) {
// 1. Assert: evalContext is an execution context associated to a ShadowRealm
// instance's [[ExecutionContext]].
// 2. Let innerCapability be ! NewPromiseCapability(%Promise%).
// 3. Let runningContext be the running execution context.
// 4. If runningContext is not already suspended, suspend runningContext.
// 5. Push evalContext onto the execution context stack; evalContext is now
// the running execution context.
// 6. Perform ! HostImportModuleDynamically(null, specifierString,
// innerCapability).
// 7. Suspend evalContext and remove it from the execution context stack.
// 8. Resume the context that is now on the top of the execution context stack
// as the running execution context.
TNode<Object> inner_capability =
CallRuntime(Runtime::kShadowRealmImportValue, eval_context, specifier);
// 9. Let steps be the steps of an ExportGetter function as described below.
// 10. Let onFulfilled be ! CreateBuiltinFunction(steps, 1, "", «
// [[ExportNameString]] », callerRealm).
// 11. Set onFulfilled.[[ExportNameString]] to exportNameString.
TNode<JSFunction> on_fulfilled = AllocateImportValueFulfilledFunction(
caller_context, eval_context, specifier, export_name);
TNode<JSFunction> on_rejected = CAST(LoadContextElement(
caller_context, Context::SHADOW_REALM_IMPORT_VALUE_REJECTED_INDEX));
// 12. Let promiseCapability be ! NewPromiseCapability(%Promise%).
TNode<JSPromise> promise = NewJSPromise(caller_context);
// 13. Return ! PerformPromiseThen(innerCapability.[[Promise]], onFulfilled,
// callerRealm.[[Intrinsics]].[[%ThrowTypeError%]], promiseCapability).
return CallBuiltin(Builtin::kPerformPromiseThen, caller_context,
inner_capability, on_fulfilled, on_rejected, promise);
}
// ExportGetter of
// https://tc39.es/proposal-shadowrealm/#sec-shadowrealmimportvalue
TF_BUILTIN(ShadowRealmImportValueFulfilled, ShadowRealmBuiltinsAssembler) {
// 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:
// 8. Let realm be f.[[Realm]].
TNode<Context> context = Parameter<Context>(Descriptor::kContext);
TNode<Context> eval_context = CAST(LoadContextElement(
context, ImportValueFulfilledFunctionContextSlot::kEvalContextSlot));
Label get_export_exception(this, Label::kDeferred);
// 2. Let f be the active function object.
// 3. Let string be f.[[ExportNameString]].
// 4. Assert: Type(string) is String.
TNode<String> export_name_string = CAST(LoadContextElement(
context, ImportValueFulfilledFunctionContextSlot::kExportNameSlot));
// 1. Assert: exports is a module namespace exotic object.
TNode<JSModuleNamespace> exports =
Parameter<JSModuleNamespace>(Descriptor::kExports);
// 5. Let hasOwn be ? HasOwnProperty(exports, string).
// 6. If hasOwn is false, throw a TypeError exception.
// 7. Let value be ? Get(exports, string).
// The only exceptions thrown by Runtime::kGetModuleNamespaceExport are
// either the export is not found or the module is not initialized.
TVARIABLE(Object, var_exception);
TNode<Object> value;
{
compiler::ScopedExceptionHandler handler(this, &get_export_exception,
&var_exception);
value = CallRuntime(Runtime::kGetModuleNamespaceExport, eval_context,
exports, export_name_string);
}
// 9. Return ? GetWrappedValue(realm, value).
TNode<NativeContext> caller_context = LoadNativeContext(context);
TNode<Object> wrapped_result =
CallBuiltin(Builtin::kShadowRealmGetWrappedValue, caller_context,
caller_context, eval_context, value);
Return(wrapped_result);
BIND(&get_export_exception);
{
TNode<String> specifier_string = CAST(LoadContextElement(
context, ImportValueFulfilledFunctionContextSlot::kSpecifierSlot));
ThrowTypeError(context, MessageTemplate::kUnresolvableExport,
specifier_string, export_name_string);
}
}
TF_BUILTIN(ShadowRealmImportValueRejected, ShadowRealmBuiltinsAssembler) {
TNode<Context> context = Parameter<Context>(Descriptor::kContext);
// TODO(v8:11989): provide a non-observable inspection on the
// pending_exception to the newly created TypeError.
// https://github.com/tc39/proposal-shadowrealm/issues/353
ThrowTypeError(context, MessageTemplate::kImportShadowRealmRejected);
}
} // namespace internal
} // namespace v8
......@@ -6520,6 +6520,10 @@ TNode<BoolT> CodeStubAssembler::IsJSStringIterator(TNode<HeapObject> object) {
return HasInstanceType(object, JS_STRING_ITERATOR_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsJSShadowRealm(TNode<HeapObject> object) {
return HasInstanceType(object, JS_SHADOW_REALM_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsJSRegExpStringIterator(
TNode<HeapObject> object) {
return HasInstanceType(object, JS_REG_EXP_STRING_ITERATOR_TYPE);
......
......@@ -111,6 +111,9 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
V(ProxyRevokeSharedFun, proxy_revoke_shared_fun, ProxyRevokeSharedFun) \
V(RegExpSpeciesProtector, regexp_species_protector, RegExpSpeciesProtector) \
V(SetIteratorProtector, set_iterator_protector, SetIteratorProtector) \
V(ShadowRealmImportValueFulfilledSFI, \
shadow_realm_import_value_fulfilled_sfi, \
ShadowRealmImportValueFulfilledSFI) \
V(SingleCharacterStringCache, single_character_string_cache, \
SingleCharacterStringCache) \
V(StringIteratorProtector, string_iterator_protector, \
......@@ -2582,6 +2585,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> IsJSPromise(TNode<HeapObject> object);
TNode<BoolT> IsJSProxy(TNode<HeapObject> object);
TNode<BoolT> IsJSStringIterator(TNode<HeapObject> object);
TNode<BoolT> IsJSShadowRealm(TNode<HeapObject> object);
TNode<BoolT> IsJSRegExpStringIterator(TNode<HeapObject> object);
TNode<BoolT> IsJSReceiverInstanceType(TNode<Int32T> instance_type);
TNode<BoolT> IsJSReceiverMap(TNode<Map> map);
......
......@@ -105,6 +105,7 @@ namespace internal {
T(ImportOutsideModule, "Cannot use import statement outside a module") \
T(ImportMetaOutsideModule, "Cannot use 'import.meta' outside a module") \
T(ImportMissingSpecifier, "import() requires a specifier") \
T(ImportShadowRealmRejected, "Cannot import in the ShadowRealm") \
T(IncompatibleMethodReceiver, "Method % called on incompatible receiver %") \
T(InstanceofNonobjectProto, \
"Function has non-object prototype '%' in instanceof check") \
......
This diff is collapsed.
......@@ -4655,7 +4655,7 @@ MaybeHandle<JSPromise> NewRejectedPromise(Isolate* isolate,
} // namespace
MaybeHandle<JSPromise> Isolate::RunHostImportModuleDynamicallyCallback(
Handle<Script> referrer, Handle<Object> specifier,
MaybeHandle<Script> maybe_referrer, Handle<Object> specifier,
MaybeHandle<Object> maybe_import_assertions_argument) {
v8::Local<v8::Context> api_context =
v8::Utils::ToLocal(Handle<Context>::cast(native_context()));
......@@ -4684,13 +4684,23 @@ MaybeHandle<JSPromise> Isolate::RunHostImportModuleDynamicallyCallback(
clear_pending_exception();
return NewRejectedPromise(this, api_context, exception);
}
Handle<FixedArray> host_defined_options;
Handle<Object> resource_name;
if (maybe_referrer.is_null()) {
host_defined_options = factory()->empty_fixed_array();
resource_name = factory()->null_value();
} else {
Handle<Script> referrer = maybe_referrer.ToHandleChecked();
host_defined_options = handle(referrer->host_defined_options(), this);
resource_name = handle(referrer->name(), this);
}
if (host_import_module_dynamically_callback_) {
ASSIGN_RETURN_ON_SCHEDULED_EXCEPTION_VALUE(
this, promise,
host_import_module_dynamically_callback_(
api_context,
v8::Utils::ToLocal(handle(referrer->host_defined_options(), this)),
v8::Utils::ToLocal(handle(referrer->name(), this)),
api_context, v8::Utils::ToLocal(host_defined_options),
v8::Utils::ToLocal(resource_name),
v8::Utils::ToLocal(specifier_str),
ToApiHandle<v8::FixedArray>(import_assertions_array)),
MaybeHandle<JSPromise>());
......@@ -4698,9 +4708,8 @@ MaybeHandle<JSPromise> Isolate::RunHostImportModuleDynamicallyCallback(
// TODO(cbruni, v8:12302): Avoid creating tempory ScriptOrModule objects.
auto script_or_module = i::Handle<i::ScriptOrModule>::cast(
this->factory()->NewStruct(i::SCRIPT_OR_MODULE_TYPE));
script_or_module->set_resource_name(referrer->name());
script_or_module->set_host_defined_options(
referrer->host_defined_options());
script_or_module->set_resource_name(*resource_name);
script_or_module->set_host_defined_options(*host_defined_options);
ASSIGN_RETURN_ON_SCHEDULED_EXCEPTION_VALUE(
this, promise,
host_import_module_dynamically_with_import_assertions_callback_(
......
......@@ -1762,7 +1762,7 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
void SetHostImportModuleDynamicallyCallback(
HostImportModuleDynamicallyCallback callback);
MaybeHandle<JSPromise> RunHostImportModuleDynamicallyCallback(
Handle<Script> referrer, Handle<Object> specifier,
MaybeHandle<Script> maybe_referrer, Handle<Object> specifier,
MaybeHandle<Object> maybe_import_assertions_argument);
void SetHostInitializeImportMetaObjectCallback(
......
......@@ -1067,6 +1067,13 @@ void Heap::CreateInitialObjects() {
CreateSharedFunctionInfo(isolate_, Builtin::kProxyRevoke, 0);
set_proxy_revoke_shared_fun(*info);
}
// ShadowRealm:
{
Handle<SharedFunctionInfo> info = CreateSharedFunctionInfo(
isolate_, Builtin::kShadowRealmImportValueFulfilled, 0);
set_shadow_realm_import_value_fulfilled_sfi(*info);
}
}
void Heap::CreateInternalAccessorInfoObjects() {
......
......@@ -4554,6 +4554,17 @@ void Genesis::InitializeGlobal_harmony_shadow_realm() {
native_context()->set_wrapped_function_map(*map);
}
// Internal steps of ShadowRealmImportValue
{
Handle<JSFunction> shadow_realm_import_value_rejected =
SimpleCreateFunction(isolate(), factory->empty_string(),
Builtin::kShadowRealmImportValueRejected, 1,
false);
shadow_realm_import_value_rejected->shared().set_native(false);
native_context()->set_shadow_realm_import_value_rejected(
*shadow_realm_import_value_rejected);
}
}
void Genesis::InitializeGlobal_harmony_struct() {
......
......@@ -353,6 +353,8 @@ enum ContextLookupFlags {
V(SET_ADD_INDEX, JSFunction, set_add) \
V(SET_DELETE_INDEX, JSFunction, set_delete) \
V(SET_HAS_INDEX, JSFunction, set_has) \
V(SHADOW_REALM_IMPORT_VALUE_REJECTED_INDEX, JSFunction, \
shadow_realm_import_value_rejected) \
V(SYNTAX_ERROR_FUNCTION_INDEX, JSFunction, syntax_error_function) \
V(TYPE_ERROR_FUNCTION_INDEX, JSFunction, type_error_function) \
V(URI_ERROR_FUNCTION_INDEX, JSFunction, uri_error_function) \
......
......@@ -367,6 +367,11 @@ Handle<JSModuleNamespace> Module::GetModuleNamespace(Isolate* isolate,
return ns;
}
bool JSModuleNamespace::HasExport(Isolate* isolate, Handle<String> name) {
Handle<Object> object(module().exports().Lookup(name), isolate);
return !object->IsTheHole(isolate);
}
MaybeHandle<Object> JSModuleNamespace::GetExport(Isolate* isolate,
Handle<String> name) {
Handle<Object> object(module().exports().Lookup(name), isolate);
......
......@@ -147,6 +147,8 @@ class JSModuleNamespace
V8_WARN_UNUSED_RESULT MaybeHandle<Object> GetExport(Isolate* isolate,
Handle<String> name);
bool HasExport(Isolate* isolate, Handle<String> name);
// Return the (constant) property attributes for the referenced property,
// which is assumed to correspond to an export. If the export is
// uninitialized, schedule an exception and return Nothing.
......
......@@ -292,7 +292,9 @@ class Symbol;
PromiseThrowerFinallySharedFun) \
V(SharedFunctionInfo, promise_value_thunk_finally_shared_fun, \
PromiseValueThunkFinallySharedFun) \
V(SharedFunctionInfo, proxy_revoke_shared_fun, ProxyRevokeSharedFun)
V(SharedFunctionInfo, proxy_revoke_shared_fun, ProxyRevokeSharedFun) \
V(SharedFunctionInfo, shadow_realm_import_value_fulfilled_sfi, \
ShadowRealmImportValueFulfilledSFI)
// These root references can be updated by the mutator.
#define STRONG_MUTABLE_MOVABLE_ROOT_LIST(V) \
......
......@@ -59,5 +59,17 @@ RUNTIME_FUNCTION(Runtime_GetImportMetaObject) {
SourceTextModule::GetImportMeta(isolate, module));
}
RUNTIME_FUNCTION(Runtime_GetModuleNamespaceExport) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
Handle<JSModuleNamespace> module_namespace = args.at<JSModuleNamespace>(0);
Handle<String> name = args.at<String>(1);
if (!module_namespace->HasExport(isolate, name)) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewReferenceError(MessageTemplate::kNotDefined, name));
}
RETURN_RESULT_OR_FAILURE(isolate, module_namespace->GetExport(isolate, name));
}
} // namespace internal
} // namespace v8
......@@ -18,5 +18,27 @@ RUNTIME_FUNCTION(Runtime_ShadowRealmWrappedFunctionCreate) {
isolate, JSWrappedFunction::Create(isolate, native_context, value));
}
// https://tc39.es/proposal-shadowrealm/#sec-shadowrealm.prototype.importvalue
RUNTIME_FUNCTION(Runtime_ShadowRealmImportValue) {
DCHECK_EQ(1, args.length());
HandleScope scope(isolate);
Handle<String> specifier = args.at<String>(0);
Handle<JSPromise> inner_capability;
MaybeHandle<Object> import_assertions;
MaybeHandle<Script> referrer;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, inner_capability,
isolate->RunHostImportModuleDynamicallyCallback(referrer, specifier,
import_assertions));
// Check that the promise is created in the eval_context.
DCHECK(
inner_capability->GetCreationContext().ToHandleChecked().is_identical_to(
isolate->native_context()));
return *inner_capability;
}
} // namespace internal
} // namespace v8
......@@ -277,7 +277,8 @@ namespace internal {
#define FOR_EACH_INTRINSIC_MODULE(F, I) \
F(DynamicImportCall, -1 /* [2, 3] */, 1) \
I(GetImportMetaObject, 0, 1) \
F(GetModuleNamespace, 1, 1)
F(GetModuleNamespace, 1, 1) \
F(GetModuleNamespaceExport, 2, 1)
#define FOR_EACH_INTRINSIC_NUMBERS(F, I) \
F(ArrayBufferMaxByteLength, 0, 1) \
......@@ -440,7 +441,8 @@ namespace internal {
F(ThrowConstAssignError, 0, 1)
#define FOR_EACH_INTRINSIC_SHADOW_REALM(F, I) \
F(ShadowRealmWrappedFunctionCreate, 2, 1)
F(ShadowRealmWrappedFunctionCreate, 2, 1) \
F(ShadowRealmImportValue, 1, 1)
#define FOR_EACH_INTRINSIC_STRINGS(F, I) \
F(FlattenString, 1, 1) \
......
......@@ -83,7 +83,7 @@ bytecodes: [
/* 48 E> */ B(DefineKeyedOwnProperty), R(this), R(0), U8(0),
/* 53 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 58 E> */ B(GetKeyedProperty), R(this), U8(2),
B(Wide), B(LdaSmi), I16(297),
B(Wide), B(LdaSmi), I16(298),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
......@@ -115,7 +115,7 @@ bytecodes: [
/* 41 E> */ B(DefineKeyedOwnProperty), R(this), R(0), U8(0),
/* 46 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 51 E> */ B(GetKeyedProperty), R(this), U8(2),
B(Wide), B(LdaSmi), I16(296),
B(Wide), B(LdaSmi), I16(297),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
......@@ -149,7 +149,7 @@ bytecodes: [
B(Star2),
B(LdaImmutableCurrentContextSlot), U8(3),
/* 58 E> */ B(GetKeyedProperty), R(this), U8(2),
B(Wide), B(LdaSmi), I16(297),
B(Wide), B(LdaSmi), I16(298),
B(Star3),
B(LdaConstant), U8(0),
B(Star4),
......@@ -181,7 +181,7 @@ bytecodes: [
/* 41 E> */ B(DefineKeyedOwnProperty), R(this), R(0), U8(0),
/* 46 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 51 E> */ B(GetKeyedProperty), R(this), U8(2),
B(Wide), B(LdaSmi), I16(296),
B(Wide), B(LdaSmi), I16(297),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
......
......@@ -58,7 +58,7 @@ bytecodes: [
B(Star2),
B(LdaImmutableCurrentContextSlot), U8(3),
/* 54 E> */ B(GetKeyedProperty), R(this), U8(2),
B(Wide), B(LdaSmi), I16(295),
B(Wide), B(LdaSmi), I16(296),
B(Star3),
B(LdaConstant), U8(0),
B(Star4),
......@@ -91,7 +91,7 @@ bytecodes: [
/* 44 E> */ B(DefineKeyedOwnProperty), R(this), R(0), U8(0),
/* 49 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 54 E> */ B(GetKeyedProperty), R(this), U8(2),
B(Wide), B(LdaSmi), I16(295),
B(Wide), B(LdaSmi), I16(296),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
......
......@@ -24,7 +24,7 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(1),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(289),
B(Wide), B(LdaSmi), I16(290),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
......@@ -61,13 +61,13 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(289),
B(Wide), B(LdaSmi), I16(290),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
/* 61 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2),
B(Throw),
B(Wide), B(LdaSmi), I16(295),
B(Wide), B(LdaSmi), I16(296),
B(Star2),
B(LdaConstant), U8(1),
B(Star3),
......@@ -99,13 +99,13 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(289),
B(Wide), B(LdaSmi), I16(290),
B(Star1),
B(LdaConstant), U8(0),
B(Star2),
/* 61 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2),
B(Throw),
B(Wide), B(LdaSmi), I16(295),
B(Wide), B(LdaSmi), I16(296),
B(Star1),
B(LdaConstant), U8(1),
B(Star2),
......@@ -145,7 +145,7 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(289),
B(Wide), B(LdaSmi), I16(290),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
......@@ -167,7 +167,7 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(289),
B(Wide), B(LdaSmi), I16(290),
B(Star3),
B(LdaConstant), U8(0),
B(Star4),
......@@ -182,7 +182,7 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(289),
B(Wide), B(LdaSmi), I16(290),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
......@@ -216,13 +216,13 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(289),
B(Wide), B(LdaSmi), I16(290),
B(Star1),
B(LdaConstant), U8(0),
B(Star2),
/* 65 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2),
B(Throw),
B(Wide), B(LdaSmi), I16(297),
B(Wide), B(LdaSmi), I16(298),
B(Star1),
B(LdaConstant), U8(1),
B(Star2),
......@@ -253,13 +253,13 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(289),
B(Wide), B(LdaSmi), I16(290),
B(Star1),
B(LdaConstant), U8(0),
B(Star2),
/* 58 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2),
B(Throw),
B(Wide), B(LdaSmi), I16(296),
B(Wide), B(LdaSmi), I16(297),
B(Star1),
B(LdaConstant), U8(1),
B(Star2),
......@@ -292,13 +292,13 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(289),
B(Wide), B(LdaSmi), I16(290),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
/* 65 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2),
B(Throw),
B(Wide), B(LdaSmi), I16(297),
B(Wide), B(LdaSmi), I16(298),
B(Star2),
B(LdaConstant), U8(1),
B(Star3),
......@@ -327,7 +327,7 @@ bytecode array length: 19
bytecodes: [
/* 46 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 51 E> */ B(GetKeyedProperty), R(this), U8(0),
B(Wide), B(LdaSmi), I16(296),
B(Wide), B(LdaSmi), I16(297),
B(Star1),
B(LdaConstant), U8(0),
B(Star2),
......
// 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>')
export const foo = 'bar';
export const obj = {};
export const func = function () {
return globalThis.foobar;
};
// Generates side-effects to the globalThis.
globalThis.foobar = 'inner-scope';
export const foo = 'bar';
throw new Error('foobar');
......@@ -31,6 +31,7 @@
# tested standalone.
'modules-skip*': [SKIP],
'harmony/modules-skip*': [SKIP],
'harmony/shadowrealm-skip*': [SKIP],
'regress/modules-skip*': [SKIP],
'wasm/exceptions-utils': [SKIP],
'wasm/wasm-module-builder': [SKIP],
......
......@@ -2985,13 +2985,6 @@
# https://bugs.chromium.org/p/v8/issues/detail?id=11989
'built-ins/ShadowRealm/prototype/evaluate/globalthis-ordinary-object': [FAIL],
'built-ins/ShadowRealm/prototype/importValue/exportName-tostring': [FAIL],
'built-ins/ShadowRealm/prototype/importValue/import-value': [FAIL],
'built-ins/ShadowRealm/prototype/importValue/specifier-tostring': [FAIL],
'built-ins/ShadowRealm/prototype/importValue/throws-if-import-value-does-not-exist': [FAIL],
'built-ins/ShadowRealm/prototype/importValue/throws-typeerror-import-syntax-error': [FAIL],
'built-ins/ShadowRealm/prototype/importValue/throws-typeerror-import-throws': [FAIL],
'built-ins/ShadowRealm/prototype/importValue/validates-realm-object': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=12085
'language/statements/class/subclass/derived-class-return-override-catch-finally': [FAIL],
......
......@@ -538,27 +538,28 @@ KNOWN_OBJECTS = {
("old_space", 0x04b39): "StringSplitCache",
("old_space", 0x04f41): "RegExpMultipleCache",
("old_space", 0x05349): "BuiltinsConstantsTable",
("old_space", 0x05775): "AsyncFunctionAwaitRejectSharedFun",
("old_space", 0x05799): "AsyncFunctionAwaitResolveSharedFun",
("old_space", 0x057bd): "AsyncGeneratorAwaitRejectSharedFun",
("old_space", 0x057e1): "AsyncGeneratorAwaitResolveSharedFun",
("old_space", 0x05805): "AsyncGeneratorYieldResolveSharedFun",
("old_space", 0x05829): "AsyncGeneratorReturnResolveSharedFun",
("old_space", 0x0584d): "AsyncGeneratorReturnClosedRejectSharedFun",
("old_space", 0x05871): "AsyncGeneratorReturnClosedResolveSharedFun",
("old_space", 0x05895): "AsyncIteratorValueUnwrapSharedFun",
("old_space", 0x058b9): "PromiseAllResolveElementSharedFun",
("old_space", 0x058dd): "PromiseAllSettledResolveElementSharedFun",
("old_space", 0x05901): "PromiseAllSettledRejectElementSharedFun",
("old_space", 0x05925): "PromiseAnyRejectElementSharedFun",
("old_space", 0x05949): "PromiseCapabilityDefaultRejectSharedFun",
("old_space", 0x0596d): "PromiseCapabilityDefaultResolveSharedFun",
("old_space", 0x05991): "PromiseCatchFinallySharedFun",
("old_space", 0x059b5): "PromiseGetCapabilitiesExecutorSharedFun",
("old_space", 0x059d9): "PromiseThenFinallySharedFun",
("old_space", 0x059fd): "PromiseThrowerFinallySharedFun",
("old_space", 0x05a21): "PromiseValueThunkFinallySharedFun",
("old_space", 0x05a45): "ProxyRevokeSharedFun",
("old_space", 0x05779): "AsyncFunctionAwaitRejectSharedFun",
("old_space", 0x0579d): "AsyncFunctionAwaitResolveSharedFun",
("old_space", 0x057c1): "AsyncGeneratorAwaitRejectSharedFun",
("old_space", 0x057e5): "AsyncGeneratorAwaitResolveSharedFun",
("old_space", 0x05809): "AsyncGeneratorYieldResolveSharedFun",
("old_space", 0x0582d): "AsyncGeneratorReturnResolveSharedFun",
("old_space", 0x05851): "AsyncGeneratorReturnClosedRejectSharedFun",
("old_space", 0x05875): "AsyncGeneratorReturnClosedResolveSharedFun",
("old_space", 0x05899): "AsyncIteratorValueUnwrapSharedFun",
("old_space", 0x058bd): "PromiseAllResolveElementSharedFun",
("old_space", 0x058e1): "PromiseAllSettledResolveElementSharedFun",
("old_space", 0x05905): "PromiseAllSettledRejectElementSharedFun",
("old_space", 0x05929): "PromiseAnyRejectElementSharedFun",
("old_space", 0x0594d): "PromiseCapabilityDefaultRejectSharedFun",
("old_space", 0x05971): "PromiseCapabilityDefaultResolveSharedFun",
("old_space", 0x05995): "PromiseCatchFinallySharedFun",
("old_space", 0x059b9): "PromiseGetCapabilitiesExecutorSharedFun",
("old_space", 0x059dd): "PromiseThenFinallySharedFun",
("old_space", 0x05a01): "PromiseThrowerFinallySharedFun",
("old_space", 0x05a25): "PromiseValueThunkFinallySharedFun",
("old_space", 0x05a49): "ProxyRevokeSharedFun",
("old_space", 0x05a6d): "ShadowRealmImportValueFulfilledSFI",
}
# Lower 32 bits of first page addresses for various heap spaces.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment