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 "src/runtime/runtime-utils.h" 6 7 #include <memory> 8 9 #include "src/arguments.h" 10 #include "src/ast/prettyprinter.h" 11 #include "src/bootstrapper.h" 12 #include "src/builtins/builtins.h" 13 #include "src/conversions.h" 14 #include "src/debug/debug.h" 15 #include "src/frames-inl.h" 16 #include "src/isolate-inl.h" 17 #include "src/messages.h" 18 #include "src/parsing/parse-info.h" 19 #include "src/parsing/parsing.h" 20 #include "src/wasm/wasm-module.h" 21 22 namespace v8 { 23 namespace internal { 24 25 RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) { 26 SealHandleScope shs(isolate); 27 DCHECK_EQ(0, args.length()); 28 CHECK(isolate->bootstrapper()->IsActive()); 29 return isolate->heap()->undefined_value(); 30 } 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 46 RUNTIME_FUNCTION(Runtime_InstallToContext) { 47 HandleScope scope(isolate); 48 DCHECK_EQ(1, args.length()); 49 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); 50 CHECK(array->HasFastElements()); 51 CHECK(isolate->bootstrapper()->IsActive()); 52 Handle<Context> native_context = isolate->native_context(); 53 Handle<FixedArray> fixed_array(FixedArray::cast(array->elements())); 54 int length = Smi::cast(array->length())->value(); 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))); 58 CHECK(fixed_array->get(i + 1)->IsJSObject()); 59 Handle<JSObject> object(JSObject::cast(fixed_array->get(i + 1))); 60 int index = Context::ImportedFieldIndexForName(name); 61 if (index == Context::kNotFound) { 62 index = Context::IntrinsicIndexForName(name); 63 } 64 CHECK(index != Context::kNotFound); 65 native_context->set(index, *object); 66 } 67 return isolate->heap()->undefined_value(); 68 } 69 70 71 RUNTIME_FUNCTION(Runtime_Throw) { 72 HandleScope scope(isolate); 73 DCHECK_EQ(1, args.length()); 74 return isolate->Throw(args[0]); 75 } 76 77 78 RUNTIME_FUNCTION(Runtime_ReThrow) { 79 HandleScope scope(isolate); 80 DCHECK_EQ(1, args.length()); 81 return isolate->ReThrow(args[0]); 82 } 83 84 85 RUNTIME_FUNCTION(Runtime_ThrowStackOverflow) { 86 SealHandleScope shs(isolate); 87 DCHECK_LE(0, args.length()); 88 return isolate->StackOverflow(); 89 } 90 91 RUNTIME_FUNCTION(Runtime_ThrowSymbolAsyncIteratorInvalid) { 92 HandleScope scope(isolate); 93 DCHECK_EQ(0, args.length()); 94 THROW_NEW_ERROR_RETURN_FAILURE( 95 isolate, NewTypeError(MessageTemplate::kSymbolAsyncIteratorInvalid)); 96 } 97 98 RUNTIME_FUNCTION(Runtime_ThrowTypeError) { 99 HandleScope scope(isolate); 100 DCHECK_LE(1, args.length()); 101 CONVERT_SMI_ARG_CHECKED(message_id_smi, 0); 102 103 Handle<Object> undefined = isolate->factory()->undefined_value(); 104 Handle<Object> arg0 = (args.length() > 1) ? args.at(1) : undefined; 105 Handle<Object> arg1 = (args.length() > 2) ? args.at(2) : undefined; 106 Handle<Object> arg2 = (args.length() > 3) ? args.at(3) : undefined; 107 108 MessageTemplate::Template message_id = 109 static_cast<MessageTemplate::Template>(message_id_smi); 110 111 THROW_NEW_ERROR_RETURN_FAILURE(isolate, 112 NewTypeError(message_id, arg0, arg1, arg2)); 113 } 114 115 RUNTIME_FUNCTION(Runtime_UnwindAndFindExceptionHandler) { 116 SealHandleScope shs(isolate); 117 DCHECK_EQ(0, args.length()); 118 return isolate->UnwindAndFindHandler(); 119 } 120 121 122 RUNTIME_FUNCTION(Runtime_PromoteScheduledException) { 123 SealHandleScope shs(isolate); 124 DCHECK_EQ(0, args.length()); 125 return isolate->PromoteScheduledException(); 126 } 127 128 129 RUNTIME_FUNCTION(Runtime_ThrowReferenceError) { 130 HandleScope scope(isolate); 131 DCHECK_EQ(1, args.length()); 132 CONVERT_ARG_HANDLE_CHECKED(Object, name, 0); 133 THROW_NEW_ERROR_RETURN_FAILURE( 134 isolate, NewReferenceError(MessageTemplate::kNotDefined, name)); 135 } 136 137 138 RUNTIME_FUNCTION(Runtime_NewTypeError) { 139 HandleScope scope(isolate); 140 DCHECK_EQ(2, args.length()); 141 CONVERT_INT32_ARG_CHECKED(template_index, 0); 142 CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 1); 143 auto message_template = 144 static_cast<MessageTemplate::Template>(template_index); 145 return *isolate->factory()->NewTypeError(message_template, arg0); 146 } 147 148 149 RUNTIME_FUNCTION(Runtime_NewReferenceError) { 150 HandleScope scope(isolate); 151 DCHECK_EQ(2, args.length()); 152 CONVERT_INT32_ARG_CHECKED(template_index, 0); 153 CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 1); 154 auto message_template = 155 static_cast<MessageTemplate::Template>(template_index); 156 return *isolate->factory()->NewReferenceError(message_template, arg0); 157 } 158 159 160 RUNTIME_FUNCTION(Runtime_NewSyntaxError) { 161 HandleScope scope(isolate); 162 DCHECK_EQ(2, args.length()); 163 CONVERT_INT32_ARG_CHECKED(template_index, 0); 164 CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 1); 165 auto message_template = 166 static_cast<MessageTemplate::Template>(template_index); 167 return *isolate->factory()->NewSyntaxError(message_template, arg0); 168 } 169 170 RUNTIME_FUNCTION(Runtime_ThrowCannotConvertToPrimitive) { 171 HandleScope scope(isolate); 172 THROW_NEW_ERROR_RETURN_FAILURE( 173 isolate, NewTypeError(MessageTemplate::kCannotConvertToPrimitive)); 174 } 175 176 RUNTIME_FUNCTION(Runtime_ThrowIllegalInvocation) { 177 HandleScope scope(isolate); 178 DCHECK_EQ(0, args.length()); 179 THROW_NEW_ERROR_RETURN_FAILURE( 180 isolate, NewTypeError(MessageTemplate::kIllegalInvocation)); 181 } 182 183 RUNTIME_FUNCTION(Runtime_ThrowIncompatibleMethodReceiver) { 184 HandleScope scope(isolate); 185 DCHECK_EQ(2, args.length()); 186 CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 0); 187 CONVERT_ARG_HANDLE_CHECKED(Object, arg1, 1); 188 THROW_NEW_ERROR_RETURN_FAILURE( 189 isolate, 190 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, arg0, arg1)); 191 } 192 193 RUNTIME_FUNCTION(Runtime_ThrowInvalidHint) { 194 HandleScope scope(isolate); 195 DCHECK_EQ(1, args.length()); 196 CONVERT_ARG_HANDLE_CHECKED(Object, hint, 0); 197 THROW_NEW_ERROR_RETURN_FAILURE( 198 isolate, NewTypeError(MessageTemplate::kInvalidHint, hint)); 199 } 200 201 RUNTIME_FUNCTION(Runtime_ThrowInvalidStringLength) { 202 HandleScope scope(isolate); 203 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError()); 204 } 205 206 RUNTIME_FUNCTION(Runtime_ThrowIteratorResultNotAnObject) { 207 HandleScope scope(isolate); 208 DCHECK_EQ(1, args.length()); 209 CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); 210 THROW_NEW_ERROR_RETURN_FAILURE( 211 isolate, 212 NewTypeError(MessageTemplate::kIteratorResultNotAnObject, value)); 213 } 214 215 RUNTIME_FUNCTION(Runtime_ThrowSymbolIteratorInvalid) { 216 HandleScope scope(isolate); 217 DCHECK_EQ(0, args.length()); 218 THROW_NEW_ERROR_RETURN_FAILURE( 219 isolate, NewTypeError(MessageTemplate::kSymbolIteratorInvalid)); 220 } 221 222 RUNTIME_FUNCTION(Runtime_ThrowNonCallableInInstanceOfCheck) { 223 HandleScope scope(isolate); 224 THROW_NEW_ERROR_RETURN_FAILURE( 225 isolate, NewTypeError(MessageTemplate::kNonCallableInInstanceOfCheck)); 226 } 227 228 RUNTIME_FUNCTION(Runtime_ThrowNonObjectInInstanceOfCheck) { 229 HandleScope scope(isolate); 230 THROW_NEW_ERROR_RETURN_FAILURE( 231 isolate, NewTypeError(MessageTemplate::kNonObjectInInstanceOfCheck)); 232 } 233 234 RUNTIME_FUNCTION(Runtime_ThrowNotConstructor) { 235 HandleScope scope(isolate); 236 DCHECK_EQ(1, args.length()); 237 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); 238 THROW_NEW_ERROR_RETURN_FAILURE( 239 isolate, NewTypeError(MessageTemplate::kNotConstructor, object)); 240 } 241 242 RUNTIME_FUNCTION(Runtime_ThrowNotGeneric) { 243 HandleScope scope(isolate); 244 DCHECK_EQ(1, args.length()); 245 CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 0); 246 THROW_NEW_ERROR_RETURN_FAILURE( 247 isolate, NewTypeError(MessageTemplate::kNotGeneric, arg0)); 248 } 249 250 RUNTIME_FUNCTION(Runtime_ThrowGeneratorRunning) { 251 HandleScope scope(isolate); 252 DCHECK_EQ(0, args.length()); 253 THROW_NEW_ERROR_RETURN_FAILURE( 254 isolate, NewTypeError(MessageTemplate::kGeneratorRunning)); 255 } 256 257 RUNTIME_FUNCTION(Runtime_ThrowApplyNonFunction) { 258 HandleScope scope(isolate); 259 DCHECK_EQ(1, args.length()); 260 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); 261 Handle<String> type = Object::TypeOf(isolate, object); 262 THROW_NEW_ERROR_RETURN_FAILURE( 263 isolate, NewTypeError(MessageTemplate::kApplyNonFunction, object, type)); 264 } 265 266 267 RUNTIME_FUNCTION(Runtime_StackGuard) { 268 SealHandleScope shs(isolate); 269 DCHECK_EQ(0, args.length()); 270 271 // First check if this is a real stack overflow. 272 StackLimitCheck check(isolate); 273 if (check.JsHasOverflowed()) { 274 return isolate->StackOverflow(); 275 } 276 277 return isolate->stack_guard()->HandleInterrupts(); 278 } 279 280 281 RUNTIME_FUNCTION(Runtime_Interrupt) { 282 SealHandleScope shs(isolate); 283 DCHECK_EQ(0, args.length()); 284 return isolate->stack_guard()->HandleInterrupts(); 285 } 286 287 288 RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) { 289 HandleScope scope(isolate); 290 DCHECK_EQ(1, args.length()); 291 CONVERT_SMI_ARG_CHECKED(size, 0); 292 CHECK(IsAligned(size, kPointerSize)); 293 CHECK(size > 0); 294 CHECK(size <= kMaxRegularHeapObjectSize); 295 return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE); 296 } 297 298 299 RUNTIME_FUNCTION(Runtime_AllocateInTargetSpace) { 300 HandleScope scope(isolate); 301 DCHECK_EQ(2, args.length()); 302 CONVERT_SMI_ARG_CHECKED(size, 0); 303 CONVERT_SMI_ARG_CHECKED(flags, 1); 304 CHECK(IsAligned(size, kPointerSize)); 305 CHECK(size > 0); 306 bool double_align = AllocateDoubleAlignFlag::decode(flags); 307 AllocationSpace space = AllocateTargetSpace::decode(flags); 308 CHECK(size <= kMaxRegularHeapObjectSize || space == LO_SPACE); 309 return *isolate->factory()->NewFillerObject(size, double_align, space); 310 } 311 312 RUNTIME_FUNCTION(Runtime_AllocateSeqOneByteString) { 313 HandleScope scope(isolate); 314 DCHECK_EQ(1, args.length()); 315 CONVERT_SMI_ARG_CHECKED(length, 0); 316 if (length == 0) return isolate->heap()->empty_string(); 317 Handle<SeqOneByteString> result; 318 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 319 isolate, result, isolate->factory()->NewRawOneByteString(length)); 320 return *result; 321 } 322 323 RUNTIME_FUNCTION(Runtime_AllocateSeqTwoByteString) { 324 HandleScope scope(isolate); 325 DCHECK_EQ(1, args.length()); 326 CONVERT_SMI_ARG_CHECKED(length, 0); 327 if (length == 0) return isolate->heap()->empty_string(); 328 Handle<SeqTwoByteString> result; 329 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 330 isolate, result, isolate->factory()->NewRawTwoByteString(length)); 331 return *result; 332 } 333 334 335 RUNTIME_FUNCTION(Runtime_IS_VAR) { 336 UNREACHABLE(); // implemented as macro in the parser 337 return NULL; 338 } 339 340 341 namespace { 342 343 bool ComputeLocation(Isolate* isolate, MessageLocation* target) { 344 JavaScriptFrameIterator it(isolate); 345 if (!it.done()) { 346 // Compute the location from the function and the relocation info of the 347 // baseline code. For optimized code this will use the deoptimization 348 // information to get canonical location information. 349 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); 350 it.frame()->Summarize(&frames); 351 auto& summary = frames.last().AsJavaScript(); 352 Handle<SharedFunctionInfo> shared(summary.function()->shared()); 353 Handle<Object> script(shared->script(), isolate); 354 int pos = summary.abstract_code()->SourcePosition(summary.code_offset()); 355 if (script->IsScript() && 356 !(Handle<Script>::cast(script)->source()->IsUndefined(isolate))) { 357 Handle<Script> casted_script = Handle<Script>::cast(script); 358 *target = MessageLocation(casted_script, pos, pos + 1, shared); 359 return true; 360 } 361 } 362 return false; 363 } 364 365 366 Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object) { 367 MessageLocation location; 368 if (ComputeLocation(isolate, &location)) { 369 std::unique_ptr<ParseInfo> info(new ParseInfo(location.shared())); 370 if (parsing::ParseAny(info.get())) { 371 CallPrinter printer(isolate, location.shared()->IsUserJavaScript()); 372 Handle<String> str = printer.Print(info->literal(), location.start_pos()); 373 if (str->length() > 0) return str; 374 } else { 375 isolate->clear_pending_exception(); 376 } 377 } 378 return Object::TypeOf(isolate, object); 379 } 380 381 } // namespace 382 383 RUNTIME_FUNCTION(Runtime_ThrowCalledNonCallable) { 384 HandleScope scope(isolate); 385 DCHECK_EQ(1, args.length()); 386 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); 387 Handle<String> callsite = RenderCallSite(isolate, object); 388 THROW_NEW_ERROR_RETURN_FAILURE( 389 isolate, NewTypeError(MessageTemplate::kCalledNonCallable, callsite)); 390 } 391 392 RUNTIME_FUNCTION(Runtime_ThrowCalledOnNullOrUndefined) { 393 HandleScope scope(isolate); 394 DCHECK_EQ(1, args.length()); 395 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); 396 THROW_NEW_ERROR_RETURN_FAILURE( 397 isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, name)); 398 } 399 400 RUNTIME_FUNCTION(Runtime_ThrowConstructedNonConstructable) { 401 HandleScope scope(isolate); 402 DCHECK_EQ(1, args.length()); 403 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); 404 Handle<String> callsite = RenderCallSite(isolate, object); 405 THROW_NEW_ERROR_RETURN_FAILURE( 406 isolate, NewTypeError(MessageTemplate::kNotConstructor, callsite)); 407 } 408 409 RUNTIME_FUNCTION(Runtime_ThrowDerivedConstructorReturnedNonObject) { 410 HandleScope scope(isolate); 411 DCHECK_EQ(0, args.length()); 412 THROW_NEW_ERROR_RETURN_FAILURE( 413 isolate, NewTypeError(MessageTemplate::kDerivedConstructorReturn)); 414 } 415 416 RUNTIME_FUNCTION(Runtime_ThrowUndefinedOrNullToObject) { 417 HandleScope scope(isolate); 418 DCHECK_EQ(1, args.length()); 419 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); 420 THROW_NEW_ERROR_RETURN_FAILURE( 421 isolate, NewTypeError(MessageTemplate::kUndefinedOrNullToObject, name)); 422 } 423 424 // ES6 section 7.3.17 CreateListFromArrayLike (obj) 425 RUNTIME_FUNCTION(Runtime_CreateListFromArrayLike) { 426 HandleScope scope(isolate); 427 DCHECK_EQ(1, args.length()); 428 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); 429 RETURN_RESULT_OR_FAILURE(isolate, Object::CreateListFromArrayLike( 430 isolate, object, ElementTypes::kAll)); 431 } 432 433 434 RUNTIME_FUNCTION(Runtime_IncrementUseCounter) { 435 HandleScope scope(isolate); 436 DCHECK_EQ(1, args.length()); 437 CONVERT_SMI_ARG_CHECKED(counter, 0); 438 isolate->CountUsage(static_cast<v8::Isolate::UseCounterFeature>(counter)); 439 return isolate->heap()->undefined_value(); 440 } 441 442 RUNTIME_FUNCTION(Runtime_GetAndResetRuntimeCallStats) { 443 HandleScope scope(isolate); 444 if (args.length() == 0) { 445 // Without arguments, the result is returned as a string. 446 DCHECK_EQ(0, args.length()); 447 std::stringstream stats_stream; 448 isolate->counters()->runtime_call_stats()->Print(stats_stream); 449 Handle<String> result = isolate->factory()->NewStringFromAsciiChecked( 450 stats_stream.str().c_str()); 451 isolate->counters()->runtime_call_stats()->Reset(); 452 return *result; 453 } else { 454 DCHECK_LE(args.length(), 2); 455 std::FILE* f; 456 if (args[0]->IsString()) { 457 // With a string argument, the results are appended to that file. 458 CONVERT_ARG_HANDLE_CHECKED(String, arg0, 0); 459 String::FlatContent flat = arg0->GetFlatContent(); 460 const char* filename = 461 reinterpret_cast<const char*>(&(flat.ToOneByteVector()[0])); 462 f = std::fopen(filename, "a"); 463 DCHECK_NOT_NULL(f); 464 } else { 465 // With an integer argument, the results are written to stdout/stderr. 466 CONVERT_SMI_ARG_CHECKED(fd, 0); 467 DCHECK(fd == 1 || fd == 2); 468 f = fd == 1 ? stdout : stderr; 469 } 470 // The second argument (if any) is a message header to be printed. 471 if (args.length() >= 2) { 472 CONVERT_ARG_HANDLE_CHECKED(String, arg1, 1); 473 arg1->PrintOn(f); 474 std::fputc('\n', f); 475 std::fflush(f); 476 } 477 OFStream stats_stream(f); 478 isolate->counters()->runtime_call_stats()->Print(stats_stream); 479 isolate->counters()->runtime_call_stats()->Reset(); 480 if (args[0]->IsString()) 481 std::fclose(f); 482 else 483 std::fflush(f); 484 return isolate->heap()->undefined_value(); 485 } 486 } 487 488 RUNTIME_FUNCTION(Runtime_OrdinaryHasInstance) { 489 HandleScope scope(isolate); 490 DCHECK_EQ(2, args.length()); 491 CONVERT_ARG_HANDLE_CHECKED(Object, callable, 0); 492 CONVERT_ARG_HANDLE_CHECKED(Object, object, 1); 493 RETURN_RESULT_OR_FAILURE( 494 isolate, Object::OrdinaryHasInstance(isolate, callable, object)); 495 } 496 497 RUNTIME_FUNCTION(Runtime_Typeof) { 498 HandleScope scope(isolate); 499 DCHECK_EQ(1, args.length()); 500 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); 501 return *Object::TypeOf(isolate, object); 502 } 503 504 RUNTIME_FUNCTION(Runtime_AllowDynamicFunction) { 505 HandleScope scope(isolate); 506 DCHECK_EQ(1, args.length()); 507 CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0); 508 Handle<JSObject> global_proxy(target->global_proxy(), isolate); 509 return *isolate->factory()->ToBoolean( 510 Builtins::AllowDynamicFunction(isolate, target, global_proxy)); 511 } 512 513 RUNTIME_FUNCTION(Runtime_CreateAsyncFromSyncIterator) { 514 HandleScope scope(isolate); 515 DCHECK_EQ(1, args.length()); 516 517 CONVERT_ARG_HANDLE_CHECKED(Object, sync_iterator, 0); 518 519 if (!sync_iterator->IsJSReceiver()) { 520 THROW_NEW_ERROR_RETURN_FAILURE( 521 isolate, NewTypeError(MessageTemplate::kSymbolIteratorInvalid)); 522 } 523 524 return *isolate->factory()->NewJSAsyncFromSyncIterator( 525 Handle<JSReceiver>::cast(sync_iterator)); 526 } 527 528 } // namespace internal 529 } // namespace v8 530