v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
builtins-shadow-realm.cc
Go to the documentation of this file.
1// Copyright 2021 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
9
10namespace v8 {
11namespace internal {
12
13// https://tc39.es/proposal-shadowrealm/#sec-shadowrealm-constructor
14BUILTIN(ShadowRealmConstructor) {
15 HandleScope scope(isolate);
16 // 1. If NewTarget is undefined, throw a TypeError exception.
17 if (IsUndefined(*args.new_target(), isolate)) { // [[Call]]
19 isolate, NewTypeError(MessageTemplate::kConstructorNotFunction,
20 isolate->factory()->ShadowRealm_string()));
21 }
22 // [[Construct]]
23 DirectHandle<JSFunction> target = args.target();
25
26 // 3. Let realmRec be CreateRealm().
27 // 5. Let context be a new execution context.
28 // 6. Set the Function of context to null.
29 // 7. Set the Realm of context to realmRec.
30 // 8. Set the ScriptOrModule of context to null.
31 // 10. Perform ? SetRealmGlobalObject(realmRec, undefined, undefined).
32 // 11. Perform ? SetDefaultGlobalBindings(O.[[ShadowRealm]]).
33 // 12. Perform ? HostInitializeShadowRealm(O.[[ShadowRealm]]).
34 // These steps are combined in
35 // Isolate::RunHostCreateShadowRealmContextCallback and Context::New.
36 // The host operation is hoisted for not creating a half-initialized
37 // ShadowRealm object, which can fail the heap verification.
40 isolate, native_context,
41 isolate->RunHostCreateShadowRealmContextCallback());
42
43 // 2. Let O be ? OrdinaryCreateFromConstructor(NewTarget,
44 // "%ShadowRealm.prototype%", « [[ShadowRealm]], [[ExecutionContext]] »).
47 JSObject::New(target, new_target, {}));
49
50 // 4. Set O.[[ShadowRealm]] to realmRec.
51 // 9. Set O.[[ExecutionContext]] to context.
52 O->set_native_context(*native_context);
53
54 // 13. Return O.
55 return *O;
56}
57
58namespace {
59
60// https://tc39.es/proposal-shadowrealm/#sec-getwrappedvalue
61MaybeDirectHandle<Object> GetWrappedValue(
62 Isolate* isolate, DirectHandle<NativeContext> creation_context,
63 Handle<Object> value) {
64 // 1. If Type(value) is Object, then
65 if (!IsJSReceiver(*value)) {
66 // 2. Return value.
67 return value;
68 }
69 // 1a. If IsCallable(value) is false, throw a TypeError exception.
70 if (!IsCallable(*value)) {
71 // The TypeError thrown is created with creation Realm's TypeError
72 // constructor instead of the executing Realm's.
74 isolate,
75 NewError(
76 direct_handle(creation_context->type_error_function(), isolate),
77 MessageTemplate::kNotCallable, value),
78 {});
79 }
80 // 1b. Return ? WrappedFunctionCreate(callerRealm, value).
81 return JSWrappedFunction::Create(isolate, creation_context,
82 Cast<JSReceiver>(value));
83}
84
85} // namespace
86
87// https://tc39.es/proposal-shadowrealm/#sec-shadowrealm.prototype.evaluate
88BUILTIN(ShadowRealmPrototypeEvaluate) {
89 HandleScope scope(isolate);
90
91 Handle<Object> source_text = args.atOrUndefined(isolate, 1);
92 // 1. Let O be this value.
94
95 Factory* factory = isolate->factory();
96
97 // 2. Perform ? ValidateShadowRealmObject(O).
98 if (!IsJSShadowRealm(*receiver)) {
100 isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver));
101 }
102 auto shadow_realm = Cast<JSShadowRealm>(receiver);
103
104 // 3. If Type(sourceText) is not String, throw a TypeError exception.
105 if (!IsString(*source_text)) {
107 isolate,
108 NewTypeError(MessageTemplate::kInvalidShadowRealmEvaluateSourceText));
109 }
110
111 // 4. Let callerRealm be the current Realm Record.
112 DirectHandle<NativeContext> caller_context = isolate->native_context();
113
114 // 5. Let evalRealm be O.[[ShadowRealm]].
115 DirectHandle<NativeContext> eval_context(shadow_realm->native_context(),
116 isolate);
117 // 6. Return ? PerformShadowRealmEval(sourceText, callerRealm, evalRealm).
118
119 // PerformShadowRealmEval
120 // https://tc39.es/proposal-shadowrealm/#sec-performshadowrealmeval
121 // 1. Perform ? HostEnsureCanCompileStrings(callerRealm, evalRealm).
122 // Run embedder pre-checks before executing the source code.
123 MaybeDirectHandle<String> validated_source;
124 bool unhandled_object;
125 std::tie(validated_source, unhandled_object) =
126 Compiler::ValidateDynamicCompilationSource(isolate, eval_context,
127 source_text);
128 if (unhandled_object) {
130 isolate,
131 NewTypeError(MessageTemplate::kInvalidShadowRealmEvaluateSourceText));
132 }
133
134 DirectHandle<JSObject> eval_global_proxy(eval_context->global_proxy(),
135 isolate);
137 bool is_parse_failed = false;
138 {
139 // 8. If runningContext is not already suspended, suspend runningContext.
140 // 9. Let evalContext be a new ECMAScript code execution context.
141 // 10. Set evalContext's Function to null.
142 // 11. Set evalContext's Realm to evalRealm.
143 // 12. Set evalContext's ScriptOrModule to null.
144 // 13. Set evalContext's VariableEnvironment to varEnv.
145 // 14. Set evalContext's LexicalEnvironment to lexEnv.
146 // 15. Set evalContext's PrivateEnvironment to null.
147 // 16. Push evalContext onto the execution context stack; evalContext is now
148 // the running execution context.
149 SaveAndSwitchContext save(isolate, *eval_context);
150
151 // 2. Perform the following substeps in an implementation-defined order,
152 // possibly interleaving parsing and error detection:
153 // 2a. Let script be ParseText(! StringToCodePoints(sourceText), Script).
154 // 2b. If script is a List of errors, throw a SyntaxError exception.
155 // 2c. If script Contains ScriptBody is false, return undefined.
156 // 2d. Let body be the ScriptBody of script.
157 // 2e. If body Contains NewTarget is true, throw a SyntaxError
158 // exception.
159 // 2f. If body Contains SuperProperty is true, throw a SyntaxError
160 // exception.
161 // 2g. If body Contains SuperCall is true, throw a SyntaxError exception.
162 // 3. Let strictEval be IsStrict of script.
163 // 4. Let runningContext be the running execution context.
164 // 5. Let lexEnv be NewDeclarativeEnvironment(evalRealm.[[GlobalEnv]]).
165 // 6. Let varEnv be evalRealm.[[GlobalEnv]].
166 // 7. If strictEval is true, set varEnv to lexEnv.
168 MaybeDirectHandle<JSFunction> maybe_function =
169 Compiler::GetFunctionFromValidatedString(eval_context, validated_source,
172 if (maybe_function.is_null()) {
173 is_parse_failed = true;
174 } else {
175 function = maybe_function.ToHandleChecked();
176
177 // 17. Let result be EvalDeclarationInstantiation(body, varEnv,
178 // lexEnv, null, strictEval).
179 // 18. If result.[[Type]] is normal, then
180 // 18a. a. Set result to Completion(Evaluation of body).
181 // 19. If result.[[Type]] is normal and result.[[Value]] is empty, then
182 // 19a. Set result to NormalCompletion(undefined).
183 result = Execution::Call(isolate, function, eval_global_proxy, {});
184
185 // 20. Suspend evalContext and remove it from the execution context stack.
186 // 21. Resume the context that is now on the top of the execution context
187 // stack as the running execution context. Done by the scope.
188 }
189 }
190
191 if (result.is_null()) {
192 DCHECK(isolate->has_exception());
193 Handle<Object> exception(isolate->exception(), isolate);
194 isolate->clear_internal_exception();
195 if (is_parse_failed) {
196 auto error_object = Cast<JSObject>(exception);
198 isolate, error_object, factory->message_string()));
199
200 return isolate->ReThrow(
201 *factory->NewError(isolate->syntax_error_function(), message));
202 }
203 // 22. If result.[[Type]] is not NORMAL, then
204 // 22a. Let copiedError be CreateTypeErrorCopy(callerRealm,
205 // result.[[Value]]). 22b. Return ThrowCompletion(copiedError).
206 DirectHandle<String> string =
207 Object::NoSideEffectsToString(isolate, exception);
209 isolate,
210 ShadowRealmNewTypeErrorCopy(
211 exception, MessageTemplate::kCallShadowRealmEvaluateThrew, string));
212 }
213 // 23. Return ? GetWrappedValue(callerRealm, result.[[Value]]).
214 DirectHandle<Object> wrapped_result;
216 isolate, wrapped_result,
217 GetWrappedValue(isolate, caller_context, result.ToHandleChecked()));
218 return *wrapped_result;
219}
220
221} // namespace internal
222} // namespace v8
#define BUILTIN(name)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSFunction > GetFunctionFromValidatedString(DirectHandle< NativeContext > context, MaybeDirectHandle< String > source, ParseRestriction restriction, int parameters_end_pos)
Definition compiler.cc:3470
static V8_WARN_UNUSED_RESULT std::pair< MaybeDirectHandle< String >, bool > ValidateDynamicCompilationSource(Isolate *isolate, DirectHandle< NativeContext > context, Handle< i::Object > source_object, bool is_code_like=false)
Definition compiler.cc:3427
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT MaybeHandle< Object > Call(Isolate *isolate, DirectHandle< Object > callable, DirectHandle< Object > receiver, base::Vector< const DirectHandle< Object > > args)
Definition execution.cc:523
Handle< JSObject > NewError(DirectHandle< JSFunction > constructor, DirectHandle< String > message, DirectHandle< Object > options={})
Definition factory.cc:2799
static V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT MaybeHandle< JSObject > New(DirectHandle< JSFunction > constructor, DirectHandle< JSReceiver > new_target, DirectHandle< AllocationSite > site, NewJSObjectType=NewJSObjectType::kNoAPIWrapper)
static Handle< Object > GetDataProperty(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Name > name)
static MaybeDirectHandle< Object > Create(Isolate *isolate, DirectHandle< NativeContext > creation_context, DirectHandle< JSReceiver > value)
V8_INLINE DirectHandle< T > ToHandleChecked() const
V8_INLINE bool is_null() const
static V8_EXPORT_PRIVATE DirectHandle< String > NoSideEffectsToString(Isolate *isolate, DirectHandle< Object > input)
Definition objects.cc:687
#define THROW_NEW_ERROR_RETURN_VALUE(isolate, call, value)
Definition isolate.h:300
#define ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, dst, call)
Definition isolate.h:284
#define THROW_NEW_ERROR_RETURN_FAILURE(isolate, call)
Definition isolate.h:294
base::Vector< const DirectHandle< Object > > args
Definition execution.cc:74
DirectHandle< Object > new_target
Definition execution.cc:75
TNode< Object > receiver
ZoneVector< RpoNumber > & result
constexpr int kNoSourcePosition
Definition globals.h:850
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
@ NO_PARSE_RESTRICTION
Definition globals.h:1654
return value
Definition map-inl.h:893
!IsContextMap !IsContextMap native_context
Definition map-inl.h:877
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
#define DCHECK(condition)
Definition logging.h:482