runtime-internal.cc 21.8 KB
Newer Older
1 2 3 4
// Copyright 2014 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.

5 6
#include <memory>

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/message-template.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
#include "src/string-builder-inl.h"
23 24 25 26 27 28

namespace v8 {
namespace internal {

RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) {
  SealHandleScope shs(isolate);
29
  DCHECK_EQ(0, args.length());
30
  CHECK(isolate->bootstrapper()->IsActive());
31
  return ReadOnlyRoots(isolate).undefined_value();
32 33
}

34
RUNTIME_FUNCTION(Runtime_ExportFromRuntime) {
35
  HandleScope scope(isolate);
36
  DCHECK_EQ(1, args.length());
37
  CONVERT_ARG_HANDLE_CHECKED(JSObject, container, 0);
38
  CHECK(isolate->bootstrapper()->IsActive());
39
  JSObject::NormalizeProperties(container, KEEP_INOBJECT_PROPERTIES, 10,
40 41 42
                                "ExportFromRuntime");
  Bootstrapper::ExportFromRuntime(isolate, container);
  JSObject::MigrateSlowToFast(container, 0, "ExportFromRuntime");
43 44 45
  return *container;
}

46
RUNTIME_FUNCTION(Runtime_InstallToContext) {
47
  HandleScope scope(isolate);
48
  DCHECK_EQ(1, args.length());
49
  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
50 51
  CHECK(array->HasFastElements());
  CHECK(isolate->bootstrapper()->IsActive());
52
  Handle<Context> native_context = isolate->native_context();
53
  Handle<FixedArray> fixed_array(FixedArray::cast(array->elements()), isolate);
jgruber's avatar
jgruber committed
54
  int length = Smi::ToInt(array->length());
55
  for (int i = 0; i < length; i += 2) {
56
    CHECK(fixed_array->get(i)->IsString());
57
    Handle<String> name(String::cast(fixed_array->get(i)), isolate);
58
    CHECK(fixed_array->get(i + 1)->IsJSObject());
59
    Handle<JSObject> object(JSObject::cast(fixed_array->get(i + 1)), isolate);
60 61 62 63
    int index = Context::ImportedFieldIndexForName(name);
    if (index == Context::kNotFound) {
      index = Context::IntrinsicIndexForName(name);
    }
64
    CHECK_NE(index, Context::kNotFound);
65 66
    native_context->set(index, *object);
  }
67
  return ReadOnlyRoots(isolate).undefined_value();
68 69
}

70 71
RUNTIME_FUNCTION(Runtime_Throw) {
  HandleScope scope(isolate);
72
  DCHECK_EQ(1, args.length());
73 74 75 76 77
  return isolate->Throw(args[0]);
}

RUNTIME_FUNCTION(Runtime_ReThrow) {
  HandleScope scope(isolate);
78
  DCHECK_EQ(1, args.length());
79 80 81
  return isolate->ReThrow(args[0]);
}

82 83
RUNTIME_FUNCTION(Runtime_ThrowStackOverflow) {
  SealHandleScope shs(isolate);
84
  DCHECK_LE(0, args.length());
85 86 87
  return isolate->StackOverflow();
}

88 89 90 91 92 93 94
RUNTIME_FUNCTION(Runtime_ThrowSymbolAsyncIteratorInvalid) {
  HandleScope scope(isolate);
  DCHECK_EQ(0, args.length());
  THROW_NEW_ERROR_RETURN_FAILURE(
      isolate, NewTypeError(MessageTemplate::kSymbolAsyncIteratorInvalid));
}

95 96 97 98 99 100 101 102 103 104 105 106
#define THROW_ERROR(isolate, args, call)                               \
  HandleScope scope(isolate);                                          \
  DCHECK_LE(1, args.length());                                         \
  CONVERT_SMI_ARG_CHECKED(message_id_smi, 0);                          \
                                                                       \
  Handle<Object> undefined = isolate->factory()->undefined_value();    \
  Handle<Object> arg0 = (args.length() > 1) ? args.at(1) : undefined;  \
  Handle<Object> arg1 = (args.length() > 2) ? args.at(2) : undefined;  \
  Handle<Object> arg2 = (args.length() > 3) ? args.at(3) : undefined;  \
                                                                       \
  MessageTemplate message_id = MessageTemplateFromInt(message_id_smi); \
                                                                       \
107 108 109 110 111
  THROW_NEW_ERROR_RETURN_FAILURE(isolate, call(message_id, arg0, arg1, arg2));

RUNTIME_FUNCTION(Runtime_ThrowRangeError) {
  THROW_ERROR(isolate, args, NewRangeError);
}
112

113 114
RUNTIME_FUNCTION(Runtime_ThrowTypeError) {
  THROW_ERROR(isolate, args, NewTypeError);
115 116
}

117 118
#undef THROW_ERROR

119 120 121 122
namespace {

const char* ElementsKindToType(ElementsKind fixed_elements_kind) {
  switch (fixed_elements_kind) {
123 124
#define ELEMENTS_KIND_CASE(Type, type, TYPE, ctype) \
  case TYPE##_ELEMENTS:                             \
125 126 127 128 129 130 131 132 133 134 135 136
    return #Type "Array";

    TYPED_ARRAYS(ELEMENTS_KIND_CASE)
#undef ELEMENTS_KIND_CASE

    default:
      UNREACHABLE();
  }
}

}  // namespace

137 138 139 140 141 142 143 144
RUNTIME_FUNCTION(Runtime_ThrowInvalidTypedArrayAlignment) {
  HandleScope scope(isolate);
  DCHECK_EQ(2, args.length());
  CONVERT_ARG_HANDLE_CHECKED(Map, map, 0);
  CONVERT_ARG_HANDLE_CHECKED(String, problem_string, 1);

  ElementsKind kind = map->elements_kind();

145 146
  Handle<String> type =
      isolate->factory()->NewStringFromAsciiChecked(ElementsKindToType(kind));
147

148 149 150
  ExternalArrayType external_type;
  size_t size;
  Factory::TypeAndSizeForElementsKind(kind, &external_type, &size);
151 152 153 154 155 156 157 158
  Handle<Object> element_size =
      handle(Smi::FromInt(static_cast<int>(size)), isolate);

  THROW_NEW_ERROR_RETURN_FAILURE(
      isolate, NewRangeError(MessageTemplate::kInvalidTypedArrayAlignment,
                             problem_string, type, element_size));
}

159
RUNTIME_FUNCTION(Runtime_UnwindAndFindExceptionHandler) {
160
  SealHandleScope shs(isolate);
161
  DCHECK_EQ(0, args.length());
162
  return isolate->UnwindAndFindHandler();
163 164
}

165 166
RUNTIME_FUNCTION(Runtime_PromoteScheduledException) {
  SealHandleScope shs(isolate);
167
  DCHECK_EQ(0, args.length());
168 169 170 171 172
  return isolate->PromoteScheduledException();
}

RUNTIME_FUNCTION(Runtime_ThrowReferenceError) {
  HandleScope scope(isolate);
173
  DCHECK_EQ(1, args.length());
174 175
  CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
  THROW_NEW_ERROR_RETURN_FAILURE(
176
      isolate, NewReferenceError(MessageTemplate::kNotDefined, name));
177 178
}

179 180
RUNTIME_FUNCTION(Runtime_NewTypeError) {
  HandleScope scope(isolate);
181
  DCHECK_EQ(2, args.length());
182 183
  CONVERT_INT32_ARG_CHECKED(template_index, 0);
  CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 1);
184
  MessageTemplate message_template = MessageTemplateFromInt(template_index);
185 186 187 188 189
  return *isolate->factory()->NewTypeError(message_template, arg0);
}

RUNTIME_FUNCTION(Runtime_NewReferenceError) {
  HandleScope scope(isolate);
190
  DCHECK_EQ(2, args.length());
191 192
  CONVERT_INT32_ARG_CHECKED(template_index, 0);
  CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 1);
193
  MessageTemplate message_template = MessageTemplateFromInt(template_index);
194 195 196 197 198
  return *isolate->factory()->NewReferenceError(message_template, arg0);
}

RUNTIME_FUNCTION(Runtime_NewSyntaxError) {
  HandleScope scope(isolate);
199
  DCHECK_EQ(2, args.length());
200 201
  CONVERT_INT32_ARG_CHECKED(template_index, 0);
  CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 1);
202
  MessageTemplate message_template = MessageTemplateFromInt(template_index);
203 204 205
  return *isolate->factory()->NewSyntaxError(message_template, arg0);
}

206 207
RUNTIME_FUNCTION(Runtime_ThrowInvalidStringLength) {
  HandleScope scope(isolate);
208
  THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
209 210
}

211 212
RUNTIME_FUNCTION(Runtime_ThrowIteratorResultNotAnObject) {
  HandleScope scope(isolate);
213
  DCHECK_EQ(1, args.length());
214 215 216
  CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
  THROW_NEW_ERROR_RETURN_FAILURE(
      isolate,
217
      NewTypeError(MessageTemplate::kIteratorResultNotAnObject, value));
218 219
}

220 221 222 223 224 225 226
RUNTIME_FUNCTION(Runtime_ThrowThrowMethodMissing) {
  HandleScope scope(isolate);
  DCHECK_EQ(0, args.length());
  THROW_NEW_ERROR_RETURN_FAILURE(
      isolate, NewTypeError(MessageTemplate::kThrowMethodMissing));
}

227 228
RUNTIME_FUNCTION(Runtime_ThrowSymbolIteratorInvalid) {
  HandleScope scope(isolate);
229
  DCHECK_EQ(0, args.length());
230 231 232 233
  THROW_NEW_ERROR_RETURN_FAILURE(
      isolate, NewTypeError(MessageTemplate::kSymbolIteratorInvalid));
}

234 235 236 237 238 239 240 241
RUNTIME_FUNCTION(Runtime_ThrowNotConstructor) {
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());
  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
  THROW_NEW_ERROR_RETURN_FAILURE(
      isolate, NewTypeError(MessageTemplate::kNotConstructor, object));
}

242 243 244 245 246 247 248 249 250
RUNTIME_FUNCTION(Runtime_ThrowApplyNonFunction) {
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());
  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
  Handle<String> type = Object::TypeOf(isolate, object);
  THROW_NEW_ERROR_RETURN_FAILURE(
      isolate, NewTypeError(MessageTemplate::kApplyNonFunction, object, type));
}

251 252
RUNTIME_FUNCTION(Runtime_StackGuard) {
  SealHandleScope shs(isolate);
253
  DCHECK_EQ(0, args.length());
254 255 256 257 258 259 260 261 262 263 264 265

  // First check if this is a real stack overflow.
  StackLimitCheck check(isolate);
  if (check.JsHasOverflowed()) {
    return isolate->StackOverflow();
  }

  return isolate->stack_guard()->HandleInterrupts();
}

RUNTIME_FUNCTION(Runtime_Interrupt) {
  SealHandleScope shs(isolate);
266
  DCHECK_EQ(0, args.length());
267 268 269 270 271
  return isolate->stack_guard()->HandleInterrupts();
}

RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) {
  HandleScope scope(isolate);
272
  DCHECK_EQ(1, args.length());
273
  CONVERT_SMI_ARG_CHECKED(size, 0);
274
  CHECK(IsAligned(size, kPointerSize));
275 276
  CHECK_GT(size, 0);
  CHECK_LE(size, kMaxRegularHeapObjectSize);
277 278 279 280 281
  return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE);
}

RUNTIME_FUNCTION(Runtime_AllocateInTargetSpace) {
  HandleScope scope(isolate);
282
  DCHECK_EQ(2, args.length());
283 284
  CONVERT_SMI_ARG_CHECKED(size, 0);
  CONVERT_SMI_ARG_CHECKED(flags, 1);
285
  CHECK(IsAligned(size, kPointerSize));
286
  CHECK_GT(size, 0);
287 288
  bool double_align = AllocateDoubleAlignFlag::decode(flags);
  AllocationSpace space = AllocateTargetSpace::decode(flags);
289
  CHECK(size <= kMaxRegularHeapObjectSize || space == LO_SPACE);
290 291 292
  return *isolate->factory()->NewFillerObject(size, double_align, space);
}

293 294 295 296
RUNTIME_FUNCTION(Runtime_AllocateSeqOneByteString) {
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());
  CONVERT_SMI_ARG_CHECKED(length, 0);
297
  if (length == 0) return ReadOnlyRoots(isolate).empty_string();
298 299 300 301 302 303 304 305 306 307
  Handle<SeqOneByteString> result;
  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
      isolate, result, isolate->factory()->NewRawOneByteString(length));
  return *result;
}

RUNTIME_FUNCTION(Runtime_AllocateSeqTwoByteString) {
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());
  CONVERT_SMI_ARG_CHECKED(length, 0);
308
  if (length == 0) return ReadOnlyRoots(isolate).empty_string();
309 310 311 312 313 314
  Handle<SeqTwoByteString> result;
  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
      isolate, result, isolate->factory()->NewRawTwoByteString(length));
  return *result;
}

315 316 317 318
RUNTIME_FUNCTION(Runtime_IS_VAR) {
  UNREACHABLE();  // implemented as macro in the parser
}

319 320
namespace {

321 322 323
bool ComputeLocation(Isolate* isolate, MessageLocation* target) {
  JavaScriptFrameIterator it(isolate);
  if (!it.done()) {
324 325 326
    // Compute the location from the function and the relocation info of the
    // baseline code. For optimized code this will use the deoptimization
    // information to get canonical location information.
327
    std::vector<FrameSummary> frames;
328
    it.frame()->Summarize(&frames);
329
    auto& summary = frames.back().AsJavaScript();
330
    Handle<SharedFunctionInfo> shared(summary.function()->shared(), isolate);
331
    Handle<Object> script(shared->script(), isolate);
332
    int pos = summary.abstract_code()->SourcePosition(summary.code_offset());
333
    if (script->IsScript() &&
334 335
        !(Handle<Script>::cast(script)->source()->IsUndefined(isolate))) {
      Handle<Script> casted_script = Handle<Script>::cast(script);
336
      *target = MessageLocation(casted_script, pos, pos + 1, shared);
337 338 339 340 341 342
      return true;
    }
  }
  return false;
}

343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367
Handle<String> BuildDefaultCallSite(Isolate* isolate, Handle<Object> object) {
  IncrementalStringBuilder builder(isolate);

  builder.AppendString(Object::TypeOf(isolate, object));
  if (object->IsString()) {
    builder.AppendCString(" \"");
    builder.AppendString(Handle<String>::cast(object));
    builder.AppendCString("\"");
  } else if (object->IsNull(isolate)) {
    builder.AppendCString(" ");
    builder.AppendString(isolate->factory()->null_string());
  } else if (object->IsTrue(isolate)) {
    builder.AppendCString(" ");
    builder.AppendString(isolate->factory()->true_string());
  } else if (object->IsFalse(isolate)) {
    builder.AppendCString(" ");
    builder.AppendString(isolate->factory()->false_string());
  } else if (object->IsNumber()) {
    builder.AppendCString(" ");
    builder.AppendString(isolate->factory()->NumberToString(object));
  }

  return builder.Finish().ToHandleChecked();
}

368
Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object,
369
                              CallPrinter::ErrorHint* hint) {
370
  MessageLocation location;
371
  if (ComputeLocation(isolate, &location)) {
372
    ParseInfo info(isolate, location.shared());
373
    if (parsing::ParseAny(&info, location.shared(), isolate)) {
374
      info.ast_value_factory()->Internalize(isolate);
375
      CallPrinter printer(isolate, location.shared()->IsUserJavaScript());
376
      Handle<String> str = printer.Print(info.literal(), location.start_pos());
377
      *hint = printer.GetErrorHint();
378
      if (str->length() > 0) return str;
379 380 381 382
    } else {
      isolate->clear_pending_exception();
    }
  }
383
  return BuildDefaultCallSite(isolate, object);
384 385
}

386 387
MessageTemplate UpdateErrorTemplate(CallPrinter::ErrorHint hint,
                                    MessageTemplate default_id) {
388 389 390 391 392 393 394 395 396 397 398 399
  switch (hint) {
    case CallPrinter::ErrorHint::kNormalIterator:
      return MessageTemplate::kNotIterable;

    case CallPrinter::ErrorHint::kCallAndNormalIterator:
      return MessageTemplate::kNotCallableOrIterable;

    case CallPrinter::ErrorHint::kAsyncIterator:
      return MessageTemplate::kNotAsyncIterable;

    case CallPrinter::ErrorHint::kCallAndAsyncIterator:
      return MessageTemplate::kNotCallableOrAsyncIterable;
400

401 402
    case CallPrinter::ErrorHint::kNone:
      return default_id;
403
  }
404
  return default_id;
405 406
}

407 408
}  // namespace

409 410
MaybeHandle<Object> Runtime::ThrowIteratorError(Isolate* isolate,
                                                Handle<Object> object) {
411
  CallPrinter::ErrorHint hint = CallPrinter::kNone;
412
  Handle<String> callsite = RenderCallSite(isolate, object, &hint);
413
  MessageTemplate id = MessageTemplate::kNotIterableNoSymbolLoad;
414 415 416

  if (hint == CallPrinter::kNone) {
    Handle<Symbol> iterator_symbol = isolate->factory()->iterator_symbol();
417
    THROW_NEW_ERROR(isolate, NewTypeError(id, callsite, iterator_symbol),
418 419 420
                    Object);
  }

421
  id = UpdateErrorTemplate(hint, id);
422 423 424
  THROW_NEW_ERROR(isolate, NewTypeError(id, callsite), Object);
}

425 426 427 428 429 430 431 432
RUNTIME_FUNCTION(Runtime_ThrowIteratorError) {
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());
  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
  RETURN_RESULT_OR_FAILURE(isolate,
                           Runtime::ThrowIteratorError(isolate, object));
}

433 434 435 436
RUNTIME_FUNCTION(Runtime_ThrowCalledNonCallable) {
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());
  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
437
  CallPrinter::ErrorHint hint = CallPrinter::kNone;
438
  Handle<String> callsite = RenderCallSite(isolate, object, &hint);
439
  MessageTemplate id = MessageTemplate::kCalledNonCallable;
440
  id = UpdateErrorTemplate(hint, id);
441
  THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(id, callsite));
442 443
}

444 445 446 447
RUNTIME_FUNCTION(Runtime_ThrowConstructedNonConstructable) {
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());
  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
448
  CallPrinter::ErrorHint hint = CallPrinter::kNone;
449
  Handle<String> callsite = RenderCallSite(isolate, object, &hint);
450
  MessageTemplate id = MessageTemplate::kNotConstructor;
451
  THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(id, callsite));
452 453
}

454
RUNTIME_FUNCTION(Runtime_ThrowConstructorReturnedNonObject) {
455 456
  HandleScope scope(isolate);
  DCHECK_EQ(0, args.length());
457

458
  THROW_NEW_ERROR_RETURN_FAILURE(
459 460
      isolate,
      NewTypeError(MessageTemplate::kDerivedConstructorReturnedNonObject));
461 462
}

463 464 465 466 467
// ES6 section 7.3.17 CreateListFromArrayLike (obj)
RUNTIME_FUNCTION(Runtime_CreateListFromArrayLike) {
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());
  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
468 469
  RETURN_RESULT_OR_FAILURE(isolate, Object::CreateListFromArrayLike(
                                        isolate, object, ElementTypes::kAll));
470 471
}

472 473 474 475 476 477 478 479
RUNTIME_FUNCTION(Runtime_DeserializeLazy) {
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());
  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);

  DCHECK(FLAG_lazy_deserialization);

  Handle<SharedFunctionInfo> shared(function->shared(), isolate);
480 481

#ifdef DEBUG
482
  int builtin_id = shared->builtin_id();
483 484 485 486 487 488 489 490 491 492
  // At this point, the builtins table should definitely have DeserializeLazy
  // set at the position of the target builtin.
  CHECK_EQ(Builtins::kDeserializeLazy,
           isolate->builtins()->builtin(builtin_id)->builtin_index());
  // The DeserializeLazy builtin tail-calls the deserialized builtin. This only
  // works with JS-linkage.
  CHECK(Builtins::IsLazy(builtin_id));
  CHECK_EQ(Builtins::TFJ, Builtins::KindOf(builtin_id));
#endif  // DEBUG

493
  Code* code = Snapshot::EnsureBuiltinIsDeserialized(isolate, shared);
494

495 496
  function->set_code(code);
  return code;
497 498
}

499 500 501 502 503
RUNTIME_FUNCTION(Runtime_IncrementUseCounter) {
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());
  CONVERT_SMI_ARG_CHECKED(counter, 0);
  isolate->CountUsage(static_cast<v8::Isolate::UseCounterFeature>(counter));
504
  return ReadOnlyRoots(isolate).undefined_value();
505 506
}

507 508
RUNTIME_FUNCTION(Runtime_GetAndResetRuntimeCallStats) {
  HandleScope scope(isolate);
509 510 511 512 513 514

  // Append any worker thread runtime call stats to the main table before
  // printing.
  isolate->counters()->worker_thread_runtime_call_stats()->AddToMainTable(
      isolate->counters()->runtime_call_stats());

515 516 517 518 519 520 521 522 523 524
  if (args.length() == 0) {
    // Without arguments, the result is returned as a string.
    DCHECK_EQ(0, args.length());
    std::stringstream stats_stream;
    isolate->counters()->runtime_call_stats()->Print(stats_stream);
    Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(
        stats_stream.str().c_str());
    isolate->counters()->runtime_call_stats()->Reset();
    return *result;
  } else {
525
    DCHECK_LE(args.length(), 2);
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540
    std::FILE* f;
    if (args[0]->IsString()) {
      // With a string argument, the results are appended to that file.
      CONVERT_ARG_HANDLE_CHECKED(String, arg0, 0);
      String::FlatContent flat = arg0->GetFlatContent();
      const char* filename =
          reinterpret_cast<const char*>(&(flat.ToOneByteVector()[0]));
      f = std::fopen(filename, "a");
      DCHECK_NOT_NULL(f);
    } else {
      // With an integer argument, the results are written to stdout/stderr.
      CONVERT_SMI_ARG_CHECKED(fd, 0);
      DCHECK(fd == 1 || fd == 2);
      f = fd == 1 ? stdout : stderr;
    }
541 542 543 544 545 546 547
    // The second argument (if any) is a message header to be printed.
    if (args.length() >= 2) {
      CONVERT_ARG_HANDLE_CHECKED(String, arg1, 1);
      arg1->PrintOn(f);
      std::fputc('\n', f);
      std::fflush(f);
    }
548 549 550 551 552 553 554
    OFStream stats_stream(f);
    isolate->counters()->runtime_call_stats()->Print(stats_stream);
    isolate->counters()->runtime_call_stats()->Reset();
    if (args[0]->IsString())
      std::fclose(f);
    else
      std::fflush(f);
555
    return ReadOnlyRoots(isolate).undefined_value();
556
  }
557 558
}

559 560 561 562 563
RUNTIME_FUNCTION(Runtime_OrdinaryHasInstance) {
  HandleScope scope(isolate);
  DCHECK_EQ(2, args.length());
  CONVERT_ARG_HANDLE_CHECKED(Object, callable, 0);
  CONVERT_ARG_HANDLE_CHECKED(Object, object, 1);
564 565
  RETURN_RESULT_OR_FAILURE(
      isolate, Object::OrdinaryHasInstance(isolate, callable, object));
566 567
}

568 569 570 571 572 573 574
RUNTIME_FUNCTION(Runtime_Typeof) {
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());
  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
  return *Object::TypeOf(isolate, object);
}

575 576 577 578 579 580 581 582 583
RUNTIME_FUNCTION(Runtime_AllowDynamicFunction) {
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());
  CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
  Handle<JSObject> global_proxy(target->global_proxy(), isolate);
  return *isolate->factory()->ToBoolean(
      Builtins::AllowDynamicFunction(isolate, target, global_proxy));
}

584
RUNTIME_FUNCTION(Runtime_CreateAsyncFromSyncIterator) {
585 586 587 588 589 590 591 592 593 594
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());

  CONVERT_ARG_HANDLE_CHECKED(Object, sync_iterator, 0);

  if (!sync_iterator->IsJSReceiver()) {
    THROW_NEW_ERROR_RETURN_FAILURE(
        isolate, NewTypeError(MessageTemplate::kSymbolIteratorInvalid));
  }

595 596 597
  Handle<Object> next;
  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
      isolate, next,
598 599
      Object::GetProperty(isolate, sync_iterator,
                          isolate->factory()->next_string()));
600

601
  return *isolate->factory()->NewJSAsyncFromSyncIterator(
602
      Handle<JSReceiver>::cast(sync_iterator), next);
603 604
}

605
RUNTIME_FUNCTION(Runtime_CreateTemplateObject) {
606 607 608 609
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());
  CONVERT_ARG_HANDLE_CHECKED(TemplateObjectDescription, description, 0);

610
  return *TemplateObjectDescription::CreateTemplateObject(isolate, description);
611 612
}

613 614 615 616 617 618 619 620 621 622 623 624 625 626
RUNTIME_FUNCTION(Runtime_ReportMessage) {
  // Helper to report messages and continue JS execution. This is intended to
  // behave similarly to reporting exceptions which reach the top-level in
  // Execution.cc, but allow the JS code to continue. This is useful for
  // implementing algorithms such as RunMicrotasks in JS.
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());

  CONVERT_ARG_HANDLE_CHECKED(Object, message_obj, 0);

  DCHECK(!isolate->has_pending_exception());
  isolate->set_pending_exception(*message_obj);
  isolate->ReportPendingMessagesFromJavaScript();
  isolate->clear_pending_exception();
627
  return ReadOnlyRoots(isolate).undefined_value();
628 629
}

630 631 632 633 634 635 636 637 638
RUNTIME_FUNCTION(Runtime_GetInitializerFunction) {
  HandleScope scope(isolate);
  DCHECK_EQ(1, args.length());

  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, constructor, 0);
  Handle<Symbol> key = isolate->factory()->class_fields_symbol();
  Handle<Object> initializer = JSReceiver::GetDataProperty(constructor, key);
  return *initializer;
}
639 640
}  // namespace internal
}  // namespace v8