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.h"
8 #include "src/arguments-inl.h"
9 #include "src/ast/prettyprinter.h"
10 #include "src/bootstrapper.h"
11 #include "src/builtins/builtins.h"
12 #include "src/conversions.h"
13 #include "src/debug/debug.h"
14 #include "src/frames-inl.h"
15 #include "src/isolate-inl.h"
16 #include "src/messages.h"
17 #include "src/objects/js-array-inl.h"
18 #include "src/parsing/parse-info.h"
19 #include "src/parsing/parsing.h"
20 #include "src/runtime/runtime-utils.h"
21 #include "src/snapshot/snapshot.h"
22
23 namespace v8 {
24 namespace internal {
25
RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping)26 RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) {
27 SealHandleScope shs(isolate);
28 DCHECK_EQ(0, args.length());
29 CHECK(isolate->bootstrapper()->IsActive());
30 return ReadOnlyRoots(isolate).undefined_value();
31 }
32
RUNTIME_FUNCTION(Runtime_ExportFromRuntime)33 RUNTIME_FUNCTION(Runtime_ExportFromRuntime) {
34 HandleScope scope(isolate);
35 DCHECK_EQ(1, args.length());
36 CONVERT_ARG_HANDLE_CHECKED(JSObject, container, 0);
37 CHECK(isolate->bootstrapper()->IsActive());
38 JSObject::NormalizeProperties(container, KEEP_INOBJECT_PROPERTIES, 10,
39 "ExportFromRuntime");
40 Bootstrapper::ExportFromRuntime(isolate, container);
41 JSObject::MigrateSlowToFast(container, 0, "ExportFromRuntime");
42 return *container;
43 }
44
RUNTIME_FUNCTION(Runtime_InstallToContext)45 RUNTIME_FUNCTION(Runtime_InstallToContext) {
46 HandleScope scope(isolate);
47 DCHECK_EQ(1, args.length());
48 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
49 CHECK(array->HasFastElements());
50 CHECK(isolate->bootstrapper()->IsActive());
51 Handle<Context> native_context = isolate->native_context();
52 Handle<FixedArray> fixed_array(FixedArray::cast(array->elements()), isolate);
53 int length = Smi::ToInt(array->length());
54 for (int i = 0; i < length; i += 2) {
55 CHECK(fixed_array->get(i)->IsString());
56 Handle<String> name(String::cast(fixed_array->get(i)), isolate);
57 CHECK(fixed_array->get(i + 1)->IsJSObject());
58 Handle<JSObject> object(JSObject::cast(fixed_array->get(i + 1)), isolate);
59 int index = Context::ImportedFieldIndexForName(name);
60 if (index == Context::kNotFound) {
61 index = Context::IntrinsicIndexForName(name);
62 }
63 CHECK_NE(index, Context::kNotFound);
64 native_context->set(index, *object);
65 }
66 return ReadOnlyRoots(isolate).undefined_value();
67 }
68
RUNTIME_FUNCTION(Runtime_Throw)69 RUNTIME_FUNCTION(Runtime_Throw) {
70 HandleScope scope(isolate);
71 DCHECK_EQ(1, args.length());
72 return isolate->Throw(args[0]);
73 }
74
RUNTIME_FUNCTION(Runtime_ReThrow)75 RUNTIME_FUNCTION(Runtime_ReThrow) {
76 HandleScope scope(isolate);
77 DCHECK_EQ(1, args.length());
78 return isolate->ReThrow(args[0]);
79 }
80
RUNTIME_FUNCTION(Runtime_ThrowStackOverflow)81 RUNTIME_FUNCTION(Runtime_ThrowStackOverflow) {
82 SealHandleScope shs(isolate);
83 DCHECK_LE(0, args.length());
84 return isolate->StackOverflow();
85 }
86
RUNTIME_FUNCTION(Runtime_ThrowSymbolAsyncIteratorInvalid)87 RUNTIME_FUNCTION(Runtime_ThrowSymbolAsyncIteratorInvalid) {
88 HandleScope scope(isolate);
89 DCHECK_EQ(0, args.length());
90 THROW_NEW_ERROR_RETURN_FAILURE(
91 isolate, NewTypeError(MessageTemplate::kSymbolAsyncIteratorInvalid));
92 }
93
94 #define THROW_ERROR(isolate, args, call) \
95 HandleScope scope(isolate); \
96 DCHECK_LE(1, args.length()); \
97 CONVERT_SMI_ARG_CHECKED(message_id_smi, 0); \
98 \
99 Handle<Object> undefined = isolate->factory()->undefined_value(); \
100 Handle<Object> arg0 = (args.length() > 1) ? args.at(1) : undefined; \
101 Handle<Object> arg1 = (args.length() > 2) ? args.at(2) : undefined; \
102 Handle<Object> arg2 = (args.length() > 3) ? args.at(3) : undefined; \
103 \
104 MessageTemplate::Template message_id = \
105 static_cast<MessageTemplate::Template>(message_id_smi); \
106 \
107 THROW_NEW_ERROR_RETURN_FAILURE(isolate, call(message_id, arg0, arg1, arg2));
108
RUNTIME_FUNCTION(Runtime_ThrowRangeError)109 RUNTIME_FUNCTION(Runtime_ThrowRangeError) {
110 THROW_ERROR(isolate, args, NewRangeError);
111 }
112
RUNTIME_FUNCTION(Runtime_ThrowTypeError)113 RUNTIME_FUNCTION(Runtime_ThrowTypeError) {
114 THROW_ERROR(isolate, args, NewTypeError);
115 }
116
117 #undef THROW_ERROR
118
119 namespace {
120
ElementsKindToType(ElementsKind fixed_elements_kind)121 const char* ElementsKindToType(ElementsKind fixed_elements_kind) {
122 switch (fixed_elements_kind) {
123 #define ELEMENTS_KIND_CASE(Type, type, TYPE, ctype) \
124 case TYPE##_ELEMENTS: \
125 return #Type "Array";
126
127 TYPED_ARRAYS(ELEMENTS_KIND_CASE)
128 #undef ELEMENTS_KIND_CASE
129
130 default:
131 UNREACHABLE();
132 }
133 }
134
135 } // namespace
136
RUNTIME_FUNCTION(Runtime_ThrowInvalidTypedArrayAlignment)137 RUNTIME_FUNCTION(Runtime_ThrowInvalidTypedArrayAlignment) {
138 HandleScope scope(isolate);
139 DCHECK_EQ(2, args.length());
140 CONVERT_ARG_HANDLE_CHECKED(Map, map, 0);
141 CONVERT_ARG_HANDLE_CHECKED(String, problem_string, 1);
142
143 ElementsKind kind = map->elements_kind();
144
145 Handle<String> type =
146 isolate->factory()->NewStringFromAsciiChecked(ElementsKindToType(kind));
147
148 ExternalArrayType external_type;
149 size_t size;
150 Factory::TypeAndSizeForElementsKind(kind, &external_type, &size);
151 Handle<Object> element_size =
152 handle(Smi::FromInt(static_cast<int>(size)), isolate);
153
154 THROW_NEW_ERROR_RETURN_FAILURE(
155 isolate, NewRangeError(MessageTemplate::kInvalidTypedArrayAlignment,
156 problem_string, type, element_size));
157 }
158
RUNTIME_FUNCTION(Runtime_UnwindAndFindExceptionHandler)159 RUNTIME_FUNCTION(Runtime_UnwindAndFindExceptionHandler) {
160 SealHandleScope shs(isolate);
161 DCHECK_EQ(0, args.length());
162 return isolate->UnwindAndFindHandler();
163 }
164
RUNTIME_FUNCTION(Runtime_PromoteScheduledException)165 RUNTIME_FUNCTION(Runtime_PromoteScheduledException) {
166 SealHandleScope shs(isolate);
167 DCHECK_EQ(0, args.length());
168 return isolate->PromoteScheduledException();
169 }
170
RUNTIME_FUNCTION(Runtime_ThrowReferenceError)171 RUNTIME_FUNCTION(Runtime_ThrowReferenceError) {
172 HandleScope scope(isolate);
173 DCHECK_EQ(1, args.length());
174 CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
175 THROW_NEW_ERROR_RETURN_FAILURE(
176 isolate, NewReferenceError(MessageTemplate::kNotDefined, name));
177 }
178
RUNTIME_FUNCTION(Runtime_NewTypeError)179 RUNTIME_FUNCTION(Runtime_NewTypeError) {
180 HandleScope scope(isolate);
181 DCHECK_EQ(2, args.length());
182 CONVERT_INT32_ARG_CHECKED(template_index, 0);
183 CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 1);
184 auto message_template =
185 static_cast<MessageTemplate::Template>(template_index);
186 return *isolate->factory()->NewTypeError(message_template, arg0);
187 }
188
RUNTIME_FUNCTION(Runtime_NewReferenceError)189 RUNTIME_FUNCTION(Runtime_NewReferenceError) {
190 HandleScope scope(isolate);
191 DCHECK_EQ(2, args.length());
192 CONVERT_INT32_ARG_CHECKED(template_index, 0);
193 CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 1);
194 auto message_template =
195 static_cast<MessageTemplate::Template>(template_index);
196 return *isolate->factory()->NewReferenceError(message_template, arg0);
197 }
198
RUNTIME_FUNCTION(Runtime_NewSyntaxError)199 RUNTIME_FUNCTION(Runtime_NewSyntaxError) {
200 HandleScope scope(isolate);
201 DCHECK_EQ(2, args.length());
202 CONVERT_INT32_ARG_CHECKED(template_index, 0);
203 CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 1);
204 auto message_template =
205 static_cast<MessageTemplate::Template>(template_index);
206 return *isolate->factory()->NewSyntaxError(message_template, arg0);
207 }
208
RUNTIME_FUNCTION(Runtime_ThrowInvalidStringLength)209 RUNTIME_FUNCTION(Runtime_ThrowInvalidStringLength) {
210 HandleScope scope(isolate);
211 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
212 }
213
RUNTIME_FUNCTION(Runtime_ThrowIteratorResultNotAnObject)214 RUNTIME_FUNCTION(Runtime_ThrowIteratorResultNotAnObject) {
215 HandleScope scope(isolate);
216 DCHECK_EQ(1, args.length());
217 CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
218 THROW_NEW_ERROR_RETURN_FAILURE(
219 isolate,
220 NewTypeError(MessageTemplate::kIteratorResultNotAnObject, value));
221 }
222
RUNTIME_FUNCTION(Runtime_ThrowThrowMethodMissing)223 RUNTIME_FUNCTION(Runtime_ThrowThrowMethodMissing) {
224 HandleScope scope(isolate);
225 DCHECK_EQ(0, args.length());
226 THROW_NEW_ERROR_RETURN_FAILURE(
227 isolate, NewTypeError(MessageTemplate::kThrowMethodMissing));
228 }
229
RUNTIME_FUNCTION(Runtime_ThrowSymbolIteratorInvalid)230 RUNTIME_FUNCTION(Runtime_ThrowSymbolIteratorInvalid) {
231 HandleScope scope(isolate);
232 DCHECK_EQ(0, args.length());
233 THROW_NEW_ERROR_RETURN_FAILURE(
234 isolate, NewTypeError(MessageTemplate::kSymbolIteratorInvalid));
235 }
236
RUNTIME_FUNCTION(Runtime_ThrowNotConstructor)237 RUNTIME_FUNCTION(Runtime_ThrowNotConstructor) {
238 HandleScope scope(isolate);
239 DCHECK_EQ(1, args.length());
240 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
241 THROW_NEW_ERROR_RETURN_FAILURE(
242 isolate, NewTypeError(MessageTemplate::kNotConstructor, object));
243 }
244
RUNTIME_FUNCTION(Runtime_ThrowApplyNonFunction)245 RUNTIME_FUNCTION(Runtime_ThrowApplyNonFunction) {
246 HandleScope scope(isolate);
247 DCHECK_EQ(1, args.length());
248 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
249 Handle<String> type = Object::TypeOf(isolate, object);
250 THROW_NEW_ERROR_RETURN_FAILURE(
251 isolate, NewTypeError(MessageTemplate::kApplyNonFunction, object, type));
252 }
253
RUNTIME_FUNCTION(Runtime_StackGuard)254 RUNTIME_FUNCTION(Runtime_StackGuard) {
255 SealHandleScope shs(isolate);
256 DCHECK_EQ(0, args.length());
257
258 // First check if this is a real stack overflow.
259 StackLimitCheck check(isolate);
260 if (check.JsHasOverflowed()) {
261 return isolate->StackOverflow();
262 }
263
264 return isolate->stack_guard()->HandleInterrupts();
265 }
266
RUNTIME_FUNCTION(Runtime_Interrupt)267 RUNTIME_FUNCTION(Runtime_Interrupt) {
268 SealHandleScope shs(isolate);
269 DCHECK_EQ(0, args.length());
270 return isolate->stack_guard()->HandleInterrupts();
271 }
272
RUNTIME_FUNCTION(Runtime_AllocateInNewSpace)273 RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) {
274 HandleScope scope(isolate);
275 DCHECK_EQ(1, args.length());
276 CONVERT_SMI_ARG_CHECKED(size, 0);
277 CHECK(IsAligned(size, kPointerSize));
278 CHECK_GT(size, 0);
279 CHECK_LE(size, kMaxRegularHeapObjectSize);
280 return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE);
281 }
282
RUNTIME_FUNCTION(Runtime_AllocateInTargetSpace)283 RUNTIME_FUNCTION(Runtime_AllocateInTargetSpace) {
284 HandleScope scope(isolate);
285 DCHECK_EQ(2, args.length());
286 CONVERT_SMI_ARG_CHECKED(size, 0);
287 CONVERT_SMI_ARG_CHECKED(flags, 1);
288 CHECK(IsAligned(size, kPointerSize));
289 CHECK_GT(size, 0);
290 bool double_align = AllocateDoubleAlignFlag::decode(flags);
291 AllocationSpace space = AllocateTargetSpace::decode(flags);
292 CHECK(size <= kMaxRegularHeapObjectSize || space == LO_SPACE);
293 return *isolate->factory()->NewFillerObject(size, double_align, space);
294 }
295
RUNTIME_FUNCTION(Runtime_AllocateSeqOneByteString)296 RUNTIME_FUNCTION(Runtime_AllocateSeqOneByteString) {
297 HandleScope scope(isolate);
298 DCHECK_EQ(1, args.length());
299 CONVERT_SMI_ARG_CHECKED(length, 0);
300 if (length == 0) return ReadOnlyRoots(isolate).empty_string();
301 Handle<SeqOneByteString> result;
302 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
303 isolate, result, isolate->factory()->NewRawOneByteString(length));
304 return *result;
305 }
306
RUNTIME_FUNCTION(Runtime_AllocateSeqTwoByteString)307 RUNTIME_FUNCTION(Runtime_AllocateSeqTwoByteString) {
308 HandleScope scope(isolate);
309 DCHECK_EQ(1, args.length());
310 CONVERT_SMI_ARG_CHECKED(length, 0);
311 if (length == 0) return ReadOnlyRoots(isolate).empty_string();
312 Handle<SeqTwoByteString> result;
313 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
314 isolate, result, isolate->factory()->NewRawTwoByteString(length));
315 return *result;
316 }
317
RUNTIME_FUNCTION(Runtime_IS_VAR)318 RUNTIME_FUNCTION(Runtime_IS_VAR) {
319 UNREACHABLE(); // implemented as macro in the parser
320 }
321
322 namespace {
323
ComputeLocation(Isolate * isolate,MessageLocation * target)324 bool ComputeLocation(Isolate* isolate, MessageLocation* target) {
325 JavaScriptFrameIterator it(isolate);
326 if (!it.done()) {
327 // Compute the location from the function and the relocation info of the
328 // baseline code. For optimized code this will use the deoptimization
329 // information to get canonical location information.
330 std::vector<FrameSummary> frames;
331 it.frame()->Summarize(&frames);
332 auto& summary = frames.back().AsJavaScript();
333 Handle<SharedFunctionInfo> shared(summary.function()->shared(), isolate);
334 Handle<Object> script(shared->script(), isolate);
335 int pos = summary.abstract_code()->SourcePosition(summary.code_offset());
336 if (script->IsScript() &&
337 !(Handle<Script>::cast(script)->source()->IsUndefined(isolate))) {
338 Handle<Script> casted_script = Handle<Script>::cast(script);
339 *target = MessageLocation(casted_script, pos, pos + 1, shared);
340 return true;
341 }
342 }
343 return false;
344 }
345
RenderCallSite(Isolate * isolate,Handle<Object> object,CallPrinter::ErrorHint * hint)346 Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object,
347 CallPrinter::ErrorHint* hint) {
348 MessageLocation location;
349 if (ComputeLocation(isolate, &location)) {
350 ParseInfo info(isolate, location.shared());
351 if (parsing::ParseAny(&info, location.shared(), isolate)) {
352 info.ast_value_factory()->Internalize(isolate);
353 CallPrinter printer(isolate, location.shared()->IsUserJavaScript());
354 Handle<String> str = printer.Print(info.literal(), location.start_pos());
355 *hint = printer.GetErrorHint();
356 if (str->length() > 0) return str;
357 } else {
358 isolate->clear_pending_exception();
359 }
360 }
361 return Object::TypeOf(isolate, object);
362 }
363
UpdateErrorTemplate(CallPrinter::ErrorHint hint,MessageTemplate::Template default_id)364 MessageTemplate::Template UpdateErrorTemplate(
365 CallPrinter::ErrorHint hint, MessageTemplate::Template default_id) {
366 switch (hint) {
367 case CallPrinter::ErrorHint::kNormalIterator:
368 return MessageTemplate::kNotIterable;
369
370 case CallPrinter::ErrorHint::kCallAndNormalIterator:
371 return MessageTemplate::kNotCallableOrIterable;
372
373 case CallPrinter::ErrorHint::kAsyncIterator:
374 return MessageTemplate::kNotAsyncIterable;
375
376 case CallPrinter::ErrorHint::kCallAndAsyncIterator:
377 return MessageTemplate::kNotCallableOrAsyncIterable;
378
379 case CallPrinter::ErrorHint::kNone:
380 return default_id;
381 }
382 return default_id;
383 }
384
385 } // namespace
386
ThrowIteratorError(Isolate * isolate,Handle<Object> object)387 MaybeHandle<Object> Runtime::ThrowIteratorError(Isolate* isolate,
388 Handle<Object> object) {
389 CallPrinter::ErrorHint hint = CallPrinter::kNone;
390 Handle<String> callsite = RenderCallSite(isolate, object, &hint);
391 MessageTemplate::Template id = MessageTemplate::kNonObjectPropertyLoad;
392
393 if (hint == CallPrinter::kNone) {
394 Handle<Symbol> iterator_symbol = isolate->factory()->iterator_symbol();
395 THROW_NEW_ERROR(isolate, NewTypeError(id, iterator_symbol, callsite),
396 Object);
397 }
398
399 id = UpdateErrorTemplate(hint, id);
400 THROW_NEW_ERROR(isolate, NewTypeError(id, callsite), Object);
401 }
402
RUNTIME_FUNCTION(Runtime_ThrowCalledNonCallable)403 RUNTIME_FUNCTION(Runtime_ThrowCalledNonCallable) {
404 HandleScope scope(isolate);
405 DCHECK_EQ(1, args.length());
406 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
407 CallPrinter::ErrorHint hint = CallPrinter::kNone;
408 Handle<String> callsite = RenderCallSite(isolate, object, &hint);
409 MessageTemplate::Template id = MessageTemplate::kCalledNonCallable;
410 id = UpdateErrorTemplate(hint, id);
411 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(id, callsite));
412 }
413
RUNTIME_FUNCTION(Runtime_ThrowConstructedNonConstructable)414 RUNTIME_FUNCTION(Runtime_ThrowConstructedNonConstructable) {
415 HandleScope scope(isolate);
416 DCHECK_EQ(1, args.length());
417 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
418 CallPrinter::ErrorHint hint = CallPrinter::kNone;
419 Handle<String> callsite = RenderCallSite(isolate, object, &hint);
420 MessageTemplate::Template id = MessageTemplate::kNotConstructor;
421 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(id, callsite));
422 }
423
RUNTIME_FUNCTION(Runtime_ThrowConstructorReturnedNonObject)424 RUNTIME_FUNCTION(Runtime_ThrowConstructorReturnedNonObject) {
425 HandleScope scope(isolate);
426 DCHECK_EQ(0, args.length());
427
428 THROW_NEW_ERROR_RETURN_FAILURE(
429 isolate,
430 NewTypeError(MessageTemplate::kDerivedConstructorReturnedNonObject));
431 }
432
433 // ES6 section 7.3.17 CreateListFromArrayLike (obj)
RUNTIME_FUNCTION(Runtime_CreateListFromArrayLike)434 RUNTIME_FUNCTION(Runtime_CreateListFromArrayLike) {
435 HandleScope scope(isolate);
436 DCHECK_EQ(1, args.length());
437 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
438 RETURN_RESULT_OR_FAILURE(isolate, Object::CreateListFromArrayLike(
439 isolate, object, ElementTypes::kAll));
440 }
441
RUNTIME_FUNCTION(Runtime_DeserializeLazy)442 RUNTIME_FUNCTION(Runtime_DeserializeLazy) {
443 HandleScope scope(isolate);
444 DCHECK_EQ(1, args.length());
445 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
446
447 DCHECK(FLAG_lazy_deserialization);
448
449 Handle<SharedFunctionInfo> shared(function->shared(), isolate);
450
451 #ifdef DEBUG
452 int builtin_id = shared->builtin_id();
453 // At this point, the builtins table should definitely have DeserializeLazy
454 // set at the position of the target builtin.
455 CHECK_EQ(Builtins::kDeserializeLazy,
456 isolate->builtins()->builtin(builtin_id)->builtin_index());
457 // The DeserializeLazy builtin tail-calls the deserialized builtin. This only
458 // works with JS-linkage.
459 CHECK(Builtins::IsLazy(builtin_id));
460 CHECK_EQ(Builtins::TFJ, Builtins::KindOf(builtin_id));
461 #endif // DEBUG
462
463 Code* code = Snapshot::EnsureBuiltinIsDeserialized(isolate, shared);
464
465 function->set_code(code);
466 return code;
467 }
468
RUNTIME_FUNCTION(Runtime_IncrementUseCounter)469 RUNTIME_FUNCTION(Runtime_IncrementUseCounter) {
470 HandleScope scope(isolate);
471 DCHECK_EQ(1, args.length());
472 CONVERT_SMI_ARG_CHECKED(counter, 0);
473 isolate->CountUsage(static_cast<v8::Isolate::UseCounterFeature>(counter));
474 return ReadOnlyRoots(isolate).undefined_value();
475 }
476
RUNTIME_FUNCTION(Runtime_GetAndResetRuntimeCallStats)477 RUNTIME_FUNCTION(Runtime_GetAndResetRuntimeCallStats) {
478 HandleScope scope(isolate);
479 if (args.length() == 0) {
480 // Without arguments, the result is returned as a string.
481 DCHECK_EQ(0, args.length());
482 std::stringstream stats_stream;
483 isolate->counters()->runtime_call_stats()->Print(stats_stream);
484 Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(
485 stats_stream.str().c_str());
486 isolate->counters()->runtime_call_stats()->Reset();
487 return *result;
488 } else {
489 DCHECK_LE(args.length(), 2);
490 std::FILE* f;
491 if (args[0]->IsString()) {
492 // With a string argument, the results are appended to that file.
493 CONVERT_ARG_HANDLE_CHECKED(String, arg0, 0);
494 String::FlatContent flat = arg0->GetFlatContent();
495 const char* filename =
496 reinterpret_cast<const char*>(&(flat.ToOneByteVector()[0]));
497 f = std::fopen(filename, "a");
498 DCHECK_NOT_NULL(f);
499 } else {
500 // With an integer argument, the results are written to stdout/stderr.
501 CONVERT_SMI_ARG_CHECKED(fd, 0);
502 DCHECK(fd == 1 || fd == 2);
503 f = fd == 1 ? stdout : stderr;
504 }
505 // The second argument (if any) is a message header to be printed.
506 if (args.length() >= 2) {
507 CONVERT_ARG_HANDLE_CHECKED(String, arg1, 1);
508 arg1->PrintOn(f);
509 std::fputc('\n', f);
510 std::fflush(f);
511 }
512 OFStream stats_stream(f);
513 isolate->counters()->runtime_call_stats()->Print(stats_stream);
514 isolate->counters()->runtime_call_stats()->Reset();
515 if (args[0]->IsString())
516 std::fclose(f);
517 else
518 std::fflush(f);
519 return ReadOnlyRoots(isolate).undefined_value();
520 }
521 }
522
RUNTIME_FUNCTION(Runtime_OrdinaryHasInstance)523 RUNTIME_FUNCTION(Runtime_OrdinaryHasInstance) {
524 HandleScope scope(isolate);
525 DCHECK_EQ(2, args.length());
526 CONVERT_ARG_HANDLE_CHECKED(Object, callable, 0);
527 CONVERT_ARG_HANDLE_CHECKED(Object, object, 1);
528 RETURN_RESULT_OR_FAILURE(
529 isolate, Object::OrdinaryHasInstance(isolate, callable, object));
530 }
531
RUNTIME_FUNCTION(Runtime_Typeof)532 RUNTIME_FUNCTION(Runtime_Typeof) {
533 HandleScope scope(isolate);
534 DCHECK_EQ(1, args.length());
535 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
536 return *Object::TypeOf(isolate, object);
537 }
538
RUNTIME_FUNCTION(Runtime_AllowDynamicFunction)539 RUNTIME_FUNCTION(Runtime_AllowDynamicFunction) {
540 HandleScope scope(isolate);
541 DCHECK_EQ(1, args.length());
542 CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
543 Handle<JSObject> global_proxy(target->global_proxy(), isolate);
544 return *isolate->factory()->ToBoolean(
545 Builtins::AllowDynamicFunction(isolate, target, global_proxy));
546 }
547
RUNTIME_FUNCTION(Runtime_CreateAsyncFromSyncIterator)548 RUNTIME_FUNCTION(Runtime_CreateAsyncFromSyncIterator) {
549 HandleScope scope(isolate);
550 DCHECK_EQ(1, args.length());
551
552 CONVERT_ARG_HANDLE_CHECKED(Object, sync_iterator, 0);
553
554 if (!sync_iterator->IsJSReceiver()) {
555 THROW_NEW_ERROR_RETURN_FAILURE(
556 isolate, NewTypeError(MessageTemplate::kSymbolIteratorInvalid));
557 }
558
559 Handle<Object> next;
560 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
561 isolate, next,
562 Object::GetProperty(isolate, sync_iterator,
563 isolate->factory()->next_string()));
564
565 return *isolate->factory()->NewJSAsyncFromSyncIterator(
566 Handle<JSReceiver>::cast(sync_iterator), next);
567 }
568
RUNTIME_FUNCTION(Runtime_CreateTemplateObject)569 RUNTIME_FUNCTION(Runtime_CreateTemplateObject) {
570 HandleScope scope(isolate);
571 DCHECK_EQ(1, args.length());
572 CONVERT_ARG_HANDLE_CHECKED(TemplateObjectDescription, description, 0);
573
574 return *TemplateObjectDescription::CreateTemplateObject(isolate, description);
575 }
576
RUNTIME_FUNCTION(Runtime_ReportMessage)577 RUNTIME_FUNCTION(Runtime_ReportMessage) {
578 // Helper to report messages and continue JS execution. This is intended to
579 // behave similarly to reporting exceptions which reach the top-level in
580 // Execution.cc, but allow the JS code to continue. This is useful for
581 // implementing algorithms such as RunMicrotasks in JS.
582 HandleScope scope(isolate);
583 DCHECK_EQ(1, args.length());
584
585 CONVERT_ARG_HANDLE_CHECKED(Object, message_obj, 0);
586
587 DCHECK(!isolate->has_pending_exception());
588 isolate->set_pending_exception(*message_obj);
589 isolate->ReportPendingMessagesFromJavaScript();
590 isolate->clear_pending_exception();
591 return ReadOnlyRoots(isolate).undefined_value();
592 }
593
594 } // namespace internal
595 } // namespace v8
596