1 // Copyright 2014 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
5 #include <memory>
6
7 #include "src/api/api-inl.h"
8 #include "src/api/api.h"
9 #include "src/ast/ast-traversal-visitor.h"
10 #include "src/ast/prettyprinter.h"
11 #include "src/builtins/builtins.h"
12 #include "src/common/message-template.h"
13 #include "src/debug/debug.h"
14 #include "src/execution/arguments-inl.h"
15 #include "src/execution/frames-inl.h"
16 #include "src/execution/isolate-inl.h"
17 #include "src/execution/messages.h"
18 #include "src/execution/tiering-manager.h"
19 #include "src/handles/maybe-handles.h"
20 #include "src/init/bootstrapper.h"
21 #include "src/logging/counters.h"
22 #include "src/numbers/conversions.h"
23 #include "src/objects/feedback-vector-inl.h"
24 #include "src/objects/js-array-inl.h"
25 #include "src/objects/template-objects-inl.h"
26 #include "src/parsing/parse-info.h"
27 #include "src/parsing/parsing.h"
28 #include "src/runtime/runtime-utils.h"
29 #include "src/snapshot/snapshot.h"
30 #include "src/strings/string-builder-inl.h"
31 #include "src/utils/ostreams.h"
32
33 #if V8_ENABLE_WEBASSEMBLY
34 // TODO(jkummerow): Drop this when the "SaveAndClearThreadInWasmFlag"
35 // short-term mitigation is no longer needed.
36 #include "src/trap-handler/trap-handler.h"
37 #endif // V8_ENABLE_WEBASSEMBLY
38
39 namespace v8 {
40 namespace internal {
41
RUNTIME_FUNCTION(Runtime_AccessCheck)42 RUNTIME_FUNCTION(Runtime_AccessCheck) {
43 HandleScope scope(isolate);
44 DCHECK_EQ(1, args.length());
45 Handle<JSObject> object = args.at<JSObject>(0);
46 if (!isolate->MayAccess(handle(isolate->context(), isolate), object)) {
47 isolate->ReportFailedAccessCheck(object);
48 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
49 }
50 return ReadOnlyRoots(isolate).undefined_value();
51 }
52
RUNTIME_FUNCTION(Runtime_FatalProcessOutOfMemoryInAllocateRaw)53 RUNTIME_FUNCTION(Runtime_FatalProcessOutOfMemoryInAllocateRaw) {
54 HandleScope scope(isolate);
55 DCHECK_EQ(0, args.length());
56 isolate->heap()->FatalProcessOutOfMemory("CodeStubAssembler::AllocateRaw");
57 UNREACHABLE();
58 }
59
RUNTIME_FUNCTION(Runtime_FatalProcessOutOfMemoryInvalidArrayLength)60 RUNTIME_FUNCTION(Runtime_FatalProcessOutOfMemoryInvalidArrayLength) {
61 HandleScope scope(isolate);
62 DCHECK_EQ(0, args.length());
63 isolate->heap()->FatalProcessOutOfMemory("invalid array length");
64 UNREACHABLE();
65 }
66
RUNTIME_FUNCTION(Runtime_Throw)67 RUNTIME_FUNCTION(Runtime_Throw) {
68 HandleScope scope(isolate);
69 DCHECK_EQ(1, args.length());
70 return isolate->Throw(args[0]);
71 }
72
RUNTIME_FUNCTION(Runtime_ReThrow)73 RUNTIME_FUNCTION(Runtime_ReThrow) {
74 HandleScope scope(isolate);
75 DCHECK_EQ(1, args.length());
76 return isolate->ReThrow(args[0]);
77 }
78
RUNTIME_FUNCTION(Runtime_ReThrowWithMessage)79 RUNTIME_FUNCTION(Runtime_ReThrowWithMessage) {
80 HandleScope scope(isolate);
81 DCHECK_EQ(2, args.length());
82 return isolate->ReThrow(args[0], args[1]);
83 }
84
RUNTIME_FUNCTION(Runtime_ThrowStackOverflow)85 RUNTIME_FUNCTION(Runtime_ThrowStackOverflow) {
86 SealHandleScope shs(isolate);
87 DCHECK_LE(0, args.length());
88 return isolate->StackOverflow();
89 }
90
RUNTIME_FUNCTION(Runtime_ThrowSymbolAsyncIteratorInvalid)91 RUNTIME_FUNCTION(Runtime_ThrowSymbolAsyncIteratorInvalid) {
92 HandleScope scope(isolate);
93 DCHECK_EQ(0, args.length());
94 THROW_NEW_ERROR_RETURN_FAILURE(
95 isolate, NewTypeError(MessageTemplate::kSymbolAsyncIteratorInvalid));
96 }
97
98 #define THROW_ERROR(isolate, args, call) \
99 HandleScope scope(isolate); \
100 DCHECK_LE(1, args.length()); \
101 int message_id_smi = args.smi_value_at(0); \
102 \
103 Handle<Object> undefined = isolate->factory()->undefined_value(); \
104 Handle<Object> arg0 = (args.length() > 1) ? args.at(1) : undefined; \
105 Handle<Object> arg1 = (args.length() > 2) ? args.at(2) : undefined; \
106 Handle<Object> arg2 = (args.length() > 3) ? args.at(3) : undefined; \
107 \
108 MessageTemplate message_id = MessageTemplateFromInt(message_id_smi); \
109 \
110 THROW_NEW_ERROR_RETURN_FAILURE(isolate, call(message_id, arg0, arg1, arg2));
111
RUNTIME_FUNCTION(Runtime_ThrowRangeError)112 RUNTIME_FUNCTION(Runtime_ThrowRangeError) {
113 if (FLAG_correctness_fuzzer_suppressions) {
114 DCHECK_LE(1, args.length());
115 int message_id_smi = args.smi_value_at(0);
116
117 // If the result of a BigInt computation is truncated to 64 bit, Turbofan
118 // can sometimes truncate intermediate results already, which can prevent
119 // those from exceeding the maximum length, effectively preventing a
120 // RangeError from being thrown. As this is a performance optimization, this
121 // behavior is accepted. To prevent the correctness fuzzer from detecting
122 // this difference, we crash the program.
123 if (MessageTemplateFromInt(message_id_smi) ==
124 MessageTemplate::kBigIntTooBig) {
125 FATAL("Aborting on invalid BigInt length");
126 }
127 }
128
129 THROW_ERROR(isolate, args, NewRangeError);
130 }
131
RUNTIME_FUNCTION(Runtime_ThrowTypeError)132 RUNTIME_FUNCTION(Runtime_ThrowTypeError) {
133 THROW_ERROR(isolate, args, NewTypeError);
134 }
135
RUNTIME_FUNCTION(Runtime_ThrowTypeErrorIfStrict)136 RUNTIME_FUNCTION(Runtime_ThrowTypeErrorIfStrict) {
137 if (GetShouldThrow(isolate, Nothing<ShouldThrow>()) ==
138 ShouldThrow::kDontThrow)
139 return ReadOnlyRoots(isolate).undefined_value();
140 THROW_ERROR(isolate, args, NewTypeError);
141 }
142
143 #undef THROW_ERROR
144
145 namespace {
146
ElementsKindToType(ElementsKind fixed_elements_kind)147 const char* ElementsKindToType(ElementsKind fixed_elements_kind) {
148 switch (fixed_elements_kind) {
149 #define ELEMENTS_KIND_CASE(Type, type, TYPE, ctype) \
150 case TYPE##_ELEMENTS: \
151 return #Type "Array";
152
153 TYPED_ARRAYS(ELEMENTS_KIND_CASE)
154 RAB_GSAB_TYPED_ARRAYS_WITH_TYPED_ARRAY_TYPE(ELEMENTS_KIND_CASE)
155 #undef ELEMENTS_KIND_CASE
156
157 default:
158 UNREACHABLE();
159 }
160 }
161
162 } // namespace
163
RUNTIME_FUNCTION(Runtime_ThrowInvalidTypedArrayAlignment)164 RUNTIME_FUNCTION(Runtime_ThrowInvalidTypedArrayAlignment) {
165 HandleScope scope(isolate);
166 DCHECK_EQ(2, args.length());
167 Handle<Map> map = args.at<Map>(0);
168 Handle<String> problem_string = args.at<String>(1);
169
170 ElementsKind kind = map->elements_kind();
171
172 Handle<String> type =
173 isolate->factory()->NewStringFromAsciiChecked(ElementsKindToType(kind));
174
175 ExternalArrayType external_type;
176 size_t size;
177 Factory::TypeAndSizeForElementsKind(kind, &external_type, &size);
178 Handle<Object> element_size =
179 handle(Smi::FromInt(static_cast<int>(size)), isolate);
180
181 THROW_NEW_ERROR_RETURN_FAILURE(
182 isolate, NewRangeError(MessageTemplate::kInvalidTypedArrayAlignment,
183 problem_string, type, element_size));
184 }
185
RUNTIME_FUNCTION(Runtime_UnwindAndFindExceptionHandler)186 RUNTIME_FUNCTION(Runtime_UnwindAndFindExceptionHandler) {
187 SealHandleScope shs(isolate);
188 DCHECK_EQ(0, args.length());
189 return isolate->UnwindAndFindHandler();
190 }
191
RUNTIME_FUNCTION(Runtime_PromoteScheduledException)192 RUNTIME_FUNCTION(Runtime_PromoteScheduledException) {
193 SealHandleScope shs(isolate);
194 DCHECK_EQ(0, args.length());
195 return isolate->PromoteScheduledException();
196 }
197
RUNTIME_FUNCTION(Runtime_ThrowReferenceError)198 RUNTIME_FUNCTION(Runtime_ThrowReferenceError) {
199 HandleScope scope(isolate);
200 DCHECK_EQ(1, args.length());
201 Handle<Object> name = args.at(0);
202 THROW_NEW_ERROR_RETURN_FAILURE(
203 isolate, NewReferenceError(MessageTemplate::kNotDefined, name));
204 }
205
RUNTIME_FUNCTION(Runtime_ThrowAccessedUninitializedVariable)206 RUNTIME_FUNCTION(Runtime_ThrowAccessedUninitializedVariable) {
207 HandleScope scope(isolate);
208 DCHECK_EQ(1, args.length());
209 Handle<Object> name = args.at(0);
210 THROW_NEW_ERROR_RETURN_FAILURE(
211 isolate,
212 NewReferenceError(MessageTemplate::kAccessedUninitializedVariable, name));
213 }
214
RUNTIME_FUNCTION(Runtime_NewError)215 RUNTIME_FUNCTION(Runtime_NewError) {
216 HandleScope scope(isolate);
217 DCHECK_EQ(2, args.length());
218 int template_index = args.smi_value_at(0);
219 Handle<Object> arg0 = args.at(1);
220 MessageTemplate message_template = MessageTemplateFromInt(template_index);
221 return *isolate->factory()->NewError(message_template, arg0);
222 }
223
RUNTIME_FUNCTION(Runtime_NewForeign)224 RUNTIME_FUNCTION(Runtime_NewForeign) {
225 HandleScope scope(isolate);
226 DCHECK_EQ(0, args.length());
227 return *isolate->factory()->NewForeign(kNullAddress);
228 }
229
RUNTIME_FUNCTION(Runtime_NewTypeError)230 RUNTIME_FUNCTION(Runtime_NewTypeError) {
231 HandleScope scope(isolate);
232 DCHECK_LE(args.length(), 4);
233 DCHECK_GE(args.length(), 1);
234 int template_index = args.smi_value_at(0);
235 MessageTemplate message_template = MessageTemplateFromInt(template_index);
236
237 Handle<Object> arg0;
238 if (args.length() >= 2) {
239 arg0 = args.at<Object>(1);
240 }
241
242 Handle<Object> arg1;
243 if (args.length() >= 3) {
244 arg1 = args.at<Object>(2);
245 }
246 Handle<Object> arg2;
247 if (args.length() >= 4) {
248 arg2 = args.at<Object>(3);
249 }
250
251 return *isolate->factory()->NewTypeError(message_template, arg0, arg1, arg2);
252 }
253
RUNTIME_FUNCTION(Runtime_NewReferenceError)254 RUNTIME_FUNCTION(Runtime_NewReferenceError) {
255 HandleScope scope(isolate);
256 DCHECK_EQ(2, args.length());
257 int template_index = args.smi_value_at(0);
258 Handle<Object> arg0 = args.at(1);
259 MessageTemplate message_template = MessageTemplateFromInt(template_index);
260 return *isolate->factory()->NewReferenceError(message_template, arg0);
261 }
262
RUNTIME_FUNCTION(Runtime_NewSyntaxError)263 RUNTIME_FUNCTION(Runtime_NewSyntaxError) {
264 HandleScope scope(isolate);
265 DCHECK_EQ(2, args.length());
266 int template_index = args.smi_value_at(0);
267 Handle<Object> arg0 = args.at(1);
268 MessageTemplate message_template = MessageTemplateFromInt(template_index);
269 return *isolate->factory()->NewSyntaxError(message_template, arg0);
270 }
271
RUNTIME_FUNCTION(Runtime_ThrowInvalidStringLength)272 RUNTIME_FUNCTION(Runtime_ThrowInvalidStringLength) {
273 HandleScope scope(isolate);
274 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
275 }
276
RUNTIME_FUNCTION(Runtime_ThrowIteratorResultNotAnObject)277 RUNTIME_FUNCTION(Runtime_ThrowIteratorResultNotAnObject) {
278 HandleScope scope(isolate);
279 DCHECK_EQ(1, args.length());
280 Handle<Object> value = args.at(0);
281 THROW_NEW_ERROR_RETURN_FAILURE(
282 isolate,
283 NewTypeError(MessageTemplate::kIteratorResultNotAnObject, value));
284 }
285
RUNTIME_FUNCTION(Runtime_ThrowThrowMethodMissing)286 RUNTIME_FUNCTION(Runtime_ThrowThrowMethodMissing) {
287 HandleScope scope(isolate);
288 DCHECK_EQ(0, args.length());
289 THROW_NEW_ERROR_RETURN_FAILURE(
290 isolate, NewTypeError(MessageTemplate::kThrowMethodMissing));
291 }
292
RUNTIME_FUNCTION(Runtime_ThrowSymbolIteratorInvalid)293 RUNTIME_FUNCTION(Runtime_ThrowSymbolIteratorInvalid) {
294 HandleScope scope(isolate);
295 DCHECK_EQ(0, args.length());
296 THROW_NEW_ERROR_RETURN_FAILURE(
297 isolate, NewTypeError(MessageTemplate::kSymbolIteratorInvalid));
298 }
299
RUNTIME_FUNCTION(Runtime_ThrowNoAccess)300 RUNTIME_FUNCTION(Runtime_ThrowNoAccess) {
301 HandleScope scope(isolate);
302 DCHECK_EQ(0, args.length());
303
304 // TODO(verwaest): We would like to throw using the calling context instead
305 // of the entered context but we don't currently have access to that.
306 HandleScopeImplementer* impl = isolate->handle_scope_implementer();
307 SaveAndSwitchContext save(
308 isolate, impl->LastEnteredOrMicrotaskContext()->native_context());
309 THROW_NEW_ERROR_RETURN_FAILURE(isolate,
310 NewTypeError(MessageTemplate::kNoAccess));
311 }
312
RUNTIME_FUNCTION(Runtime_ThrowNotConstructor)313 RUNTIME_FUNCTION(Runtime_ThrowNotConstructor) {
314 HandleScope scope(isolate);
315 DCHECK_EQ(1, args.length());
316 Handle<Object> object = args.at(0);
317 THROW_NEW_ERROR_RETURN_FAILURE(
318 isolate, NewTypeError(MessageTemplate::kNotConstructor, object));
319 }
320
RUNTIME_FUNCTION(Runtime_ThrowApplyNonFunction)321 RUNTIME_FUNCTION(Runtime_ThrowApplyNonFunction) {
322 HandleScope scope(isolate);
323 DCHECK_EQ(1, args.length());
324 Handle<Object> object = args.at(0);
325 Handle<String> type = Object::TypeOf(isolate, object);
326 THROW_NEW_ERROR_RETURN_FAILURE(
327 isolate, NewTypeError(MessageTemplate::kApplyNonFunction, object, type));
328 }
329
RUNTIME_FUNCTION(Runtime_StackGuard)330 RUNTIME_FUNCTION(Runtime_StackGuard) {
331 SealHandleScope shs(isolate);
332 DCHECK_EQ(0, args.length());
333 TRACE_EVENT0("v8.execute", "V8.StackGuard");
334
335 // First check if this is a real stack overflow.
336 StackLimitCheck check(isolate);
337 if (check.JsHasOverflowed()) {
338 return isolate->StackOverflow();
339 }
340
341 return isolate->stack_guard()->HandleInterrupts();
342 }
343
RUNTIME_FUNCTION(Runtime_StackGuardWithGap)344 RUNTIME_FUNCTION(Runtime_StackGuardWithGap) {
345 SealHandleScope shs(isolate);
346 DCHECK_EQ(args.length(), 1);
347 uint32_t gap = args.positive_smi_value_at(0);
348 TRACE_EVENT0("v8.execute", "V8.StackGuard");
349
350 // First check if this is a real stack overflow.
351 StackLimitCheck check(isolate);
352 if (check.JsHasOverflowed(gap)) {
353 return isolate->StackOverflow();
354 }
355
356 return isolate->stack_guard()->HandleInterrupts();
357 }
358
RUNTIME_FUNCTION(Runtime_BytecodeBudgetInterruptWithStackCheck)359 RUNTIME_FUNCTION(Runtime_BytecodeBudgetInterruptWithStackCheck) {
360 HandleScope scope(isolate);
361 DCHECK_EQ(1, args.length());
362 Handle<JSFunction> function = args.at<JSFunction>(0);
363 TRACE_EVENT0("v8.execute", "V8.BytecodeBudgetInterruptWithStackCheck");
364
365 // Check for stack interrupts here so that we can fold the interrupt check
366 // into bytecode budget interrupts.
367 StackLimitCheck check(isolate);
368 if (check.JsHasOverflowed()) {
369 // We ideally wouldn't actually get StackOverflows here, since we stack
370 // check on bytecode entry, but it's possible that this check fires due to
371 // the runtime function call being what overflows the stack.
372 // if our function entry
373 return isolate->StackOverflow();
374 } else if (check.InterruptRequested()) {
375 Object return_value = isolate->stack_guard()->HandleInterrupts();
376 if (!return_value.IsUndefined(isolate)) {
377 return return_value;
378 }
379 }
380
381 isolate->tiering_manager()->OnInterruptTick(function);
382 return ReadOnlyRoots(isolate).undefined_value();
383 }
384
RUNTIME_FUNCTION(Runtime_BytecodeBudgetInterrupt)385 RUNTIME_FUNCTION(Runtime_BytecodeBudgetInterrupt) {
386 HandleScope scope(isolate);
387 DCHECK_EQ(1, args.length());
388 Handle<JSFunction> function = args.at<JSFunction>(0);
389 TRACE_EVENT0("v8.execute", "V8.BytecodeBudgetInterrupt");
390
391 isolate->tiering_manager()->OnInterruptTick(function);
392 return ReadOnlyRoots(isolate).undefined_value();
393 }
394
395 namespace {
396
397 #if V8_ENABLE_WEBASSEMBLY
398 class SaveAndClearThreadInWasmFlag {
399 public:
SaveAndClearThreadInWasmFlag()400 SaveAndClearThreadInWasmFlag() {
401 if (trap_handler::IsTrapHandlerEnabled()) {
402 if (trap_handler::IsThreadInWasm()) {
403 thread_was_in_wasm_ = true;
404 trap_handler::ClearThreadInWasm();
405 }
406 }
407 }
~SaveAndClearThreadInWasmFlag()408 ~SaveAndClearThreadInWasmFlag() {
409 if (thread_was_in_wasm_) {
410 trap_handler::SetThreadInWasm();
411 }
412 }
413
414 private:
415 bool thread_was_in_wasm_{false};
416 };
417 #else
418 class SaveAndClearThreadInWasmFlag {};
419 #endif // V8_ENABLE_WEBASSEMBLY
420
421 } // namespace
422
RUNTIME_FUNCTION(Runtime_AllocateInYoungGeneration)423 RUNTIME_FUNCTION(Runtime_AllocateInYoungGeneration) {
424 HandleScope scope(isolate);
425 DCHECK_EQ(2, args.length());
426 int size = args.smi_value_at(0);
427 int flags = args.smi_value_at(1);
428 AllocationAlignment alignment =
429 AllocateDoubleAlignFlag::decode(flags) ? kDoubleAligned : kTaggedAligned;
430 bool allow_large_object_allocation =
431 AllowLargeObjectAllocationFlag::decode(flags);
432 CHECK(IsAligned(size, kTaggedSize));
433 CHECK_GT(size, 0);
434 if (!allow_large_object_allocation) {
435 CHECK(size <= kMaxRegularHeapObjectSize);
436 }
437
438 #if V8_ENABLE_WEBASSEMBLY
439 // Short-term mitigation for crbug.com/1236668. When this is called from
440 // WasmGC code, clear the "thread in wasm" flag, which is important in case
441 // any GC needs to happen.
442 // TODO(jkummerow): Find a better fix, likely by replacing the global flag.
443 SaveAndClearThreadInWasmFlag clear_wasm_flag;
444 #endif // V8_ENABLE_WEBASSEMBLY
445
446 // TODO(v8:9472): Until double-aligned allocation is fixed for new-space
447 // allocations, don't request it.
448 alignment = kTaggedAligned;
449
450 return *isolate->factory()->NewFillerObject(size, alignment,
451 AllocationType::kYoung,
452 AllocationOrigin::kGeneratedCode);
453 }
454
RUNTIME_FUNCTION(Runtime_AllocateInOldGeneration)455 RUNTIME_FUNCTION(Runtime_AllocateInOldGeneration) {
456 HandleScope scope(isolate);
457 DCHECK_EQ(2, args.length());
458 int size = args.smi_value_at(0);
459 int flags = args.smi_value_at(1);
460 AllocationAlignment alignment =
461 AllocateDoubleAlignFlag::decode(flags) ? kDoubleAligned : kTaggedAligned;
462 bool allow_large_object_allocation =
463 AllowLargeObjectAllocationFlag::decode(flags);
464 CHECK(IsAligned(size, kTaggedSize));
465 CHECK_GT(size, 0);
466 if (!allow_large_object_allocation) {
467 CHECK(size <= kMaxRegularHeapObjectSize);
468 }
469 return *isolate->factory()->NewFillerObject(
470 size, alignment, AllocationType::kOld, AllocationOrigin::kGeneratedCode);
471 }
472
RUNTIME_FUNCTION(Runtime_AllocateByteArray)473 RUNTIME_FUNCTION(Runtime_AllocateByteArray) {
474 HandleScope scope(isolate);
475 DCHECK_EQ(1, args.length());
476 int length = args.smi_value_at(0);
477 DCHECK_LT(0, length);
478 return *isolate->factory()->NewByteArray(length);
479 }
480
RUNTIME_FUNCTION(Runtime_AllocateSeqOneByteString)481 RUNTIME_FUNCTION(Runtime_AllocateSeqOneByteString) {
482 HandleScope scope(isolate);
483 DCHECK_EQ(1, args.length());
484 int length = args.smi_value_at(0);
485 if (length == 0) return ReadOnlyRoots(isolate).empty_string();
486 Handle<SeqOneByteString> result;
487 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
488 isolate, result, isolate->factory()->NewRawOneByteString(length));
489 return *result;
490 }
491
RUNTIME_FUNCTION(Runtime_AllocateSeqTwoByteString)492 RUNTIME_FUNCTION(Runtime_AllocateSeqTwoByteString) {
493 HandleScope scope(isolate);
494 DCHECK_EQ(1, args.length());
495 int length = args.smi_value_at(0);
496 if (length == 0) return ReadOnlyRoots(isolate).empty_string();
497 Handle<SeqTwoByteString> result;
498 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
499 isolate, result, isolate->factory()->NewRawTwoByteString(length));
500 return *result;
501 }
502
RUNTIME_FUNCTION(Runtime_ThrowIteratorError)503 RUNTIME_FUNCTION(Runtime_ThrowIteratorError) {
504 HandleScope scope(isolate);
505 DCHECK_EQ(1, args.length());
506 Handle<Object> object = args.at(0);
507 return isolate->Throw(*ErrorUtils::NewIteratorError(isolate, object));
508 }
509
RUNTIME_FUNCTION(Runtime_ThrowSpreadArgError)510 RUNTIME_FUNCTION(Runtime_ThrowSpreadArgError) {
511 HandleScope scope(isolate);
512 DCHECK_EQ(2, args.length());
513 int message_id_smi = args.smi_value_at(0);
514 MessageTemplate message_id = MessageTemplateFromInt(message_id_smi);
515 Handle<Object> object = args.at(1);
516 return ErrorUtils::ThrowSpreadArgError(isolate, message_id, object);
517 }
518
RUNTIME_FUNCTION(Runtime_ThrowCalledNonCallable)519 RUNTIME_FUNCTION(Runtime_ThrowCalledNonCallable) {
520 HandleScope scope(isolate);
521 DCHECK_EQ(1, args.length());
522 Handle<Object> object = args.at(0);
523 return isolate->Throw(
524 *ErrorUtils::NewCalledNonCallableError(isolate, object));
525 }
526
RUNTIME_FUNCTION(Runtime_ThrowConstructedNonConstructable)527 RUNTIME_FUNCTION(Runtime_ThrowConstructedNonConstructable) {
528 HandleScope scope(isolate);
529 DCHECK_EQ(1, args.length());
530 Handle<Object> object = args.at(0);
531 return isolate->Throw(
532 *ErrorUtils::NewConstructedNonConstructable(isolate, object));
533 }
534
RUNTIME_FUNCTION(Runtime_ThrowPatternAssignmentNonCoercible)535 RUNTIME_FUNCTION(Runtime_ThrowPatternAssignmentNonCoercible) {
536 HandleScope scope(isolate);
537 DCHECK_EQ(1, args.length());
538 Handle<Object> object = args.at(0);
539 return ErrorUtils::ThrowLoadFromNullOrUndefined(isolate, object,
540 MaybeHandle<Object>());
541 }
542
RUNTIME_FUNCTION(Runtime_ThrowConstructorReturnedNonObject)543 RUNTIME_FUNCTION(Runtime_ThrowConstructorReturnedNonObject) {
544 HandleScope scope(isolate);
545 DCHECK_EQ(0, args.length());
546
547 THROW_NEW_ERROR_RETURN_FAILURE(
548 isolate,
549 NewTypeError(MessageTemplate::kDerivedConstructorReturnedNonObject));
550 }
551
552 // ES6 section 7.3.17 CreateListFromArrayLike (obj)
RUNTIME_FUNCTION(Runtime_CreateListFromArrayLike)553 RUNTIME_FUNCTION(Runtime_CreateListFromArrayLike) {
554 HandleScope scope(isolate);
555 DCHECK_EQ(1, args.length());
556 Handle<Object> object = args.at(0);
557 RETURN_RESULT_OR_FAILURE(isolate, Object::CreateListFromArrayLike(
558 isolate, object, ElementTypes::kAll));
559 }
560
RUNTIME_FUNCTION(Runtime_IncrementUseCounter)561 RUNTIME_FUNCTION(Runtime_IncrementUseCounter) {
562 HandleScope scope(isolate);
563 DCHECK_EQ(1, args.length());
564 int counter = args.smi_value_at(0);
565 isolate->CountUsage(static_cast<v8::Isolate::UseCounterFeature>(counter));
566 return ReadOnlyRoots(isolate).undefined_value();
567 }
568
RUNTIME_FUNCTION(Runtime_GetAndResetRuntimeCallStats)569 RUNTIME_FUNCTION(Runtime_GetAndResetRuntimeCallStats) {
570 HandleScope scope(isolate);
571 DCHECK_LE(args.length(), 2);
572 #ifdef V8_RUNTIME_CALL_STATS
573 // Append any worker thread runtime call stats to the main table before
574 // printing.
575 isolate->counters()->worker_thread_runtime_call_stats()->AddToMainTable(
576 isolate->counters()->runtime_call_stats());
577
578 if (args.length() == 0) {
579 // Without arguments, the result is returned as a string.
580 std::stringstream stats_stream;
581 isolate->counters()->runtime_call_stats()->Print(stats_stream);
582 Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(
583 stats_stream.str().c_str());
584 isolate->counters()->runtime_call_stats()->Reset();
585 return *result;
586 }
587
588 std::FILE* f;
589 if (args[0].IsString()) {
590 // With a string argument, the results are appended to that file.
591 Handle<String> filename = args.at<String>(0);
592 f = std::fopen(filename->ToCString().get(), "a");
593 DCHECK_NOT_NULL(f);
594 } else {
595 // With an integer argument, the results are written to stdout/stderr.
596 int fd = args.smi_value_at(0);
597 DCHECK(fd == 1 || fd == 2);
598 f = fd == 1 ? stdout : stderr;
599 }
600 // The second argument (if any) is a message header to be printed.
601 if (args.length() >= 2) {
602 Handle<String> message = args.at<String>(1);
603 message->PrintOn(f);
604 std::fputc('\n', f);
605 std::fflush(f);
606 }
607 OFStream stats_stream(f);
608 isolate->counters()->runtime_call_stats()->Print(stats_stream);
609 isolate->counters()->runtime_call_stats()->Reset();
610 if (args[0].IsString()) {
611 std::fclose(f);
612 } else {
613 std::fflush(f);
614 }
615 #endif // V8_RUNTIME_CALL_STATS
616 return ReadOnlyRoots(isolate).undefined_value();
617 }
618
RUNTIME_FUNCTION(Runtime_OrdinaryHasInstance)619 RUNTIME_FUNCTION(Runtime_OrdinaryHasInstance) {
620 HandleScope scope(isolate);
621 DCHECK_EQ(2, args.length());
622 Handle<Object> callable = args.at(0);
623 Handle<Object> object = args.at(1);
624 RETURN_RESULT_OR_FAILURE(
625 isolate, Object::OrdinaryHasInstance(isolate, callable, object));
626 }
627
RUNTIME_FUNCTION(Runtime_Typeof)628 RUNTIME_FUNCTION(Runtime_Typeof) {
629 HandleScope scope(isolate);
630 DCHECK_EQ(1, args.length());
631 Handle<Object> object = args.at(0);
632 return *Object::TypeOf(isolate, object);
633 }
634
RUNTIME_FUNCTION(Runtime_AllowDynamicFunction)635 RUNTIME_FUNCTION(Runtime_AllowDynamicFunction) {
636 HandleScope scope(isolate);
637 DCHECK_EQ(1, args.length());
638 Handle<JSFunction> target = args.at<JSFunction>(0);
639 Handle<JSObject> global_proxy(target->global_proxy(), isolate);
640 return *isolate->factory()->ToBoolean(
641 Builtins::AllowDynamicFunction(isolate, target, global_proxy));
642 }
643
RUNTIME_FUNCTION(Runtime_CreateAsyncFromSyncIterator)644 RUNTIME_FUNCTION(Runtime_CreateAsyncFromSyncIterator) {
645 HandleScope scope(isolate);
646 DCHECK_EQ(1, args.length());
647
648 Handle<Object> sync_iterator = args.at(0);
649
650 if (!sync_iterator->IsJSReceiver()) {
651 THROW_NEW_ERROR_RETURN_FAILURE(
652 isolate, NewTypeError(MessageTemplate::kSymbolIteratorInvalid));
653 }
654
655 Handle<Object> next;
656 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
657 isolate, next,
658 Object::GetProperty(isolate, sync_iterator,
659 isolate->factory()->next_string()));
660
661 return *isolate->factory()->NewJSAsyncFromSyncIterator(
662 Handle<JSReceiver>::cast(sync_iterator), next);
663 }
664
RUNTIME_FUNCTION(Runtime_GetTemplateObject)665 RUNTIME_FUNCTION(Runtime_GetTemplateObject) {
666 HandleScope scope(isolate);
667 DCHECK_EQ(3, args.length());
668 Handle<TemplateObjectDescription> description =
669 args.at<TemplateObjectDescription>(0);
670 Handle<SharedFunctionInfo> shared_info = args.at<SharedFunctionInfo>(1);
671 int slot_id = args.smi_value_at(2);
672
673 Handle<NativeContext> native_context(isolate->context().native_context(),
674 isolate);
675 return *TemplateObjectDescription::GetTemplateObject(
676 isolate, native_context, description, shared_info, slot_id);
677 }
678
RUNTIME_FUNCTION(Runtime_ReportMessageFromMicrotask)679 RUNTIME_FUNCTION(Runtime_ReportMessageFromMicrotask) {
680 // Helper to report messages and continue JS execution. This is intended to
681 // behave similarly to reporting exceptions which reach the top-level, but
682 // allow the JS code to continue.
683 HandleScope scope(isolate);
684 DCHECK_EQ(1, args.length());
685
686 Handle<Object> exception = args.at(0);
687
688 DCHECK(!isolate->has_pending_exception());
689 isolate->set_pending_exception(*exception);
690 MessageLocation* no_location = nullptr;
691 Handle<JSMessageObject> message =
692 isolate->CreateMessageOrAbort(exception, no_location);
693 MessageHandler::ReportMessage(isolate, no_location, message);
694 isolate->clear_pending_exception();
695 return ReadOnlyRoots(isolate).undefined_value();
696 }
697
RUNTIME_FUNCTION(Runtime_GetInitializerFunction)698 RUNTIME_FUNCTION(Runtime_GetInitializerFunction) {
699 HandleScope scope(isolate);
700 DCHECK_EQ(1, args.length());
701
702 Handle<JSReceiver> constructor = args.at<JSReceiver>(0);
703 Handle<Symbol> key = isolate->factory()->class_fields_symbol();
704 Handle<Object> initializer =
705 JSReceiver::GetDataProperty(isolate, constructor, key);
706 return *initializer;
707 }
708
RUNTIME_FUNCTION(Runtime_DoubleToStringWithRadix)709 RUNTIME_FUNCTION(Runtime_DoubleToStringWithRadix) {
710 HandleScope scope(isolate);
711 DCHECK_EQ(2, args.length());
712 double number = args.number_value_at(0);
713 int32_t radix = 0;
714 CHECK(args[1].ToInt32(&radix));
715
716 char* const str = DoubleToRadixCString(number, radix);
717 Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
718 DeleteArray(str);
719 return *result;
720 }
721
RUNTIME_FUNCTION(Runtime_SharedValueBarrierSlow)722 RUNTIME_FUNCTION(Runtime_SharedValueBarrierSlow) {
723 HandleScope scope(isolate);
724 DCHECK_EQ(1, args.length());
725 Handle<HeapObject> value = args.at<HeapObject>(0);
726 Handle<Object> shared_value;
727 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
728 isolate, shared_value, Object::ShareSlow(isolate, value, kThrowOnError));
729 return *shared_value;
730 }
731
732 } // namespace internal
733 } // namespace v8
734