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 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 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 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 69 RUNTIME_FUNCTION(Runtime_Throw) { 70 HandleScope scope(isolate); 71 DCHECK_EQ(1, args.length()); 72 return isolate->Throw(args[0]); 73 } 74 75 RUNTIME_FUNCTION(Runtime_ReThrow) { 76 HandleScope scope(isolate); 77 DCHECK_EQ(1, args.length()); 78 return isolate->ReThrow(args[0]); 79 } 80 81 RUNTIME_FUNCTION(Runtime_ThrowStackOverflow) { 82 SealHandleScope shs(isolate); 83 DCHECK_LE(0, args.length()); 84 return isolate->StackOverflow(); 85 } 86 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 109 RUNTIME_FUNCTION(Runtime_ThrowRangeError) { 110 THROW_ERROR(isolate, args, NewRangeError); 111 } 112 113 RUNTIME_FUNCTION(Runtime_ThrowTypeError) { 114 THROW_ERROR(isolate, args, NewTypeError); 115 } 116 117 #undef THROW_ERROR 118 119 namespace { 120 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 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 159 RUNTIME_FUNCTION(Runtime_UnwindAndFindExceptionHandler) { 160 SealHandleScope shs(isolate); 161 DCHECK_EQ(0, args.length()); 162 return isolate->UnwindAndFindHandler(); 163 } 164 165 RUNTIME_FUNCTION(Runtime_PromoteScheduledException) { 166 SealHandleScope shs(isolate); 167 DCHECK_EQ(0, args.length()); 168 return isolate->PromoteScheduledException(); 169 } 170 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 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 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 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 209 RUNTIME_FUNCTION(Runtime_ThrowInvalidStringLength) { 210 HandleScope scope(isolate); 211 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError()); 212 } 213 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 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 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 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 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 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 267 RUNTIME_FUNCTION(Runtime_Interrupt) { 268 SealHandleScope shs(isolate); 269 DCHECK_EQ(0, args.length()); 270 return isolate->stack_guard()->HandleInterrupts(); 271 } 272 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 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 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 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 318 RUNTIME_FUNCTION(Runtime_IS_VAR) { 319 UNREACHABLE(); // implemented as macro in the parser 320 } 321 322 namespace { 323 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 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 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 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 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 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 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) 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 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 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 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 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 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 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 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 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 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