• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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