1 // Copyright 2018 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/external-reference.h" 6 7 #include "src/api.h" 8 #include "src/base/ieee754.h" 9 #include "src/codegen.h" 10 #include "src/compiler/code-assembler.h" 11 #include "src/counters.h" 12 #include "src/debug/debug.h" 13 #include "src/deoptimizer.h" 14 #include "src/elements.h" 15 #include "src/heap/heap.h" 16 #include "src/ic/stub-cache.h" 17 #include "src/interpreter/interpreter.h" 18 #include "src/isolate.h" 19 #include "src/objects-inl.h" 20 #include "src/regexp/regexp-stack.h" 21 #include "src/simulator-base.h" 22 #include "src/string-search.h" 23 #include "src/wasm/wasm-external-refs.h" 24 25 // Include native regexp-macro-assembler. 26 #ifndef V8_INTERPRETED_REGEXP 27 #if V8_TARGET_ARCH_IA32 28 #include "src/regexp/ia32/regexp-macro-assembler-ia32.h" // NOLINT 29 #elif V8_TARGET_ARCH_X64 30 #include "src/regexp/x64/regexp-macro-assembler-x64.h" // NOLINT 31 #elif V8_TARGET_ARCH_ARM64 32 #include "src/regexp/arm64/regexp-macro-assembler-arm64.h" // NOLINT 33 #elif V8_TARGET_ARCH_ARM 34 #include "src/regexp/arm/regexp-macro-assembler-arm.h" // NOLINT 35 #elif V8_TARGET_ARCH_PPC 36 #include "src/regexp/ppc/regexp-macro-assembler-ppc.h" // NOLINT 37 #elif V8_TARGET_ARCH_MIPS 38 #include "src/regexp/mips/regexp-macro-assembler-mips.h" // NOLINT 39 #elif V8_TARGET_ARCH_MIPS64 40 #include "src/regexp/mips64/regexp-macro-assembler-mips64.h" // NOLINT 41 #elif V8_TARGET_ARCH_S390 42 #include "src/regexp/s390/regexp-macro-assembler-s390.h" // NOLINT 43 #else // Unknown architecture. 44 #error "Unknown architecture." 45 #endif // Target architecture. 46 #endif // V8_INTERPRETED_REGEXP 47 48 #ifdef V8_INTL_SUPPORT 49 #include "src/intl.h" 50 #endif // V8_INTL_SUPPORT 51 52 namespace v8 { 53 namespace internal { 54 55 // ----------------------------------------------------------------------------- 56 // Common double constants. 57 58 constexpr double double_min_int_constant = kMinInt; 59 constexpr double double_one_half_constant = 0.5; 60 constexpr uint64_t double_the_hole_nan_constant = kHoleNanInt64; 61 constexpr double double_uint32_bias_constant = 62 static_cast<double>(kMaxUInt32) + 1; 63 64 constexpr struct V8_ALIGNED(16) { 65 uint32_t a; 66 uint32_t b; 67 uint32_t c; 68 uint32_t d; 69 } float_absolute_constant = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF}; 70 71 constexpr struct V8_ALIGNED(16) { 72 uint32_t a; 73 uint32_t b; 74 uint32_t c; 75 uint32_t d; 76 } float_negate_constant = {0x80000000, 0x80000000, 0x80000000, 0x80000000}; 77 78 constexpr struct V8_ALIGNED(16) { 79 uint64_t a; 80 uint64_t b; 81 } double_absolute_constant = {uint64_t{0x7FFFFFFFFFFFFFFF}, 82 uint64_t{0x7FFFFFFFFFFFFFFF}}; 83 84 constexpr struct V8_ALIGNED(16) { 85 uint64_t a; 86 uint64_t b; 87 } double_negate_constant = {uint64_t{0x8000000000000000}, 88 uint64_t{0x8000000000000000}}; 89 90 // Implementation of ExternalReference 91 92 static ExternalReference::Type BuiltinCallTypeForResultSize(int result_size) { 93 switch (result_size) { 94 case 1: 95 return ExternalReference::BUILTIN_CALL; 96 case 2: 97 return ExternalReference::BUILTIN_CALL_PAIR; 98 } 99 UNREACHABLE(); 100 } 101 102 // static 103 ExternalReference ExternalReference::Create( 104 ApiFunction* fun, Type type = ExternalReference::BUILTIN_CALL) { 105 return ExternalReference(Redirect(fun->address(), type)); 106 } 107 108 // static 109 ExternalReference ExternalReference::Create(Runtime::FunctionId id) { 110 return Create(Runtime::FunctionForId(id)); 111 } 112 113 // static 114 ExternalReference ExternalReference::Create(const Runtime::Function* f) { 115 return ExternalReference( 116 Redirect(f->entry, BuiltinCallTypeForResultSize(f->result_size))); 117 } 118 119 // static 120 ExternalReference ExternalReference::Create(Address address) { 121 return ExternalReference(Redirect(address)); 122 } 123 124 ExternalReference ExternalReference::isolate_address(Isolate* isolate) { 125 return ExternalReference(isolate); 126 } 127 128 ExternalReference ExternalReference::builtins_address(Isolate* isolate) { 129 return ExternalReference(isolate->heap()->builtin_address(0)); 130 } 131 132 ExternalReference ExternalReference::handle_scope_implementer_address( 133 Isolate* isolate) { 134 return ExternalReference(isolate->handle_scope_implementer_address()); 135 } 136 137 ExternalReference ExternalReference::pending_microtask_count_address( 138 Isolate* isolate) { 139 return ExternalReference(isolate->pending_microtask_count_address()); 140 } 141 142 ExternalReference ExternalReference::interpreter_dispatch_table_address( 143 Isolate* isolate) { 144 return ExternalReference(isolate->interpreter()->dispatch_table_address()); 145 } 146 147 ExternalReference ExternalReference::interpreter_dispatch_counters( 148 Isolate* isolate) { 149 return ExternalReference( 150 isolate->interpreter()->bytecode_dispatch_counters_table()); 151 } 152 153 ExternalReference ExternalReference::bytecode_size_table_address() { 154 return ExternalReference( 155 interpreter::Bytecodes::bytecode_size_table_address()); 156 } 157 158 // static 159 ExternalReference ExternalReference::Create(StatsCounter* counter) { 160 return ExternalReference( 161 reinterpret_cast<Address>(counter->GetInternalPointer())); 162 } 163 164 // static 165 ExternalReference ExternalReference::Create(IsolateAddressId id, 166 Isolate* isolate) { 167 return ExternalReference(isolate->get_address_from_id(id)); 168 } 169 170 // static 171 ExternalReference ExternalReference::Create(const SCTableReference& table_ref) { 172 return ExternalReference(table_ref.address()); 173 } 174 175 ExternalReference 176 ExternalReference::incremental_marking_record_write_function() { 177 return ExternalReference( 178 Redirect(FUNCTION_ADDR(IncrementalMarking::RecordWriteFromCode))); 179 } 180 181 ExternalReference ExternalReference::store_buffer_overflow_function() { 182 return ExternalReference( 183 Redirect(Heap::store_buffer_overflow_function_address())); 184 } 185 186 ExternalReference ExternalReference::delete_handle_scope_extensions() { 187 return ExternalReference( 188 Redirect(FUNCTION_ADDR(HandleScope::DeleteExtensions))); 189 } 190 191 ExternalReference ExternalReference::get_date_field_function() { 192 return ExternalReference(Redirect(FUNCTION_ADDR(JSDate::GetField))); 193 } 194 195 ExternalReference ExternalReference::date_cache_stamp(Isolate* isolate) { 196 return ExternalReference(isolate->date_cache()->stamp_address()); 197 } 198 199 // static 200 ExternalReference 201 ExternalReference::runtime_function_table_address_for_unittests( 202 Isolate* isolate) { 203 return runtime_function_table_address(isolate); 204 } 205 206 // static 207 Address ExternalReference::Redirect(Address address, Type type) { 208 #ifdef USE_SIMULATOR 209 return SimulatorBase::RedirectExternalReference(address, type); 210 #else 211 return address; 212 #endif 213 } 214 215 ExternalReference ExternalReference::stress_deopt_count(Isolate* isolate) { 216 return ExternalReference(isolate->stress_deopt_count_address()); 217 } 218 219 ExternalReference ExternalReference::force_slow_path(Isolate* isolate) { 220 return ExternalReference(isolate->force_slow_path_address()); 221 } 222 223 ExternalReference ExternalReference::new_deoptimizer_function() { 224 return ExternalReference(Redirect(FUNCTION_ADDR(Deoptimizer::New))); 225 } 226 227 ExternalReference ExternalReference::compute_output_frames_function() { 228 return ExternalReference( 229 Redirect(FUNCTION_ADDR(Deoptimizer::ComputeOutputFrames))); 230 } 231 232 ExternalReference ExternalReference::wasm_f32_trunc() { 233 return ExternalReference(Redirect(FUNCTION_ADDR(wasm::f32_trunc_wrapper))); 234 } 235 ExternalReference ExternalReference::wasm_f32_floor() { 236 return ExternalReference(Redirect(FUNCTION_ADDR(wasm::f32_floor_wrapper))); 237 } 238 ExternalReference ExternalReference::wasm_f32_ceil() { 239 return ExternalReference(Redirect(FUNCTION_ADDR(wasm::f32_ceil_wrapper))); 240 } 241 ExternalReference ExternalReference::wasm_f32_nearest_int() { 242 return ExternalReference( 243 Redirect(FUNCTION_ADDR(wasm::f32_nearest_int_wrapper))); 244 } 245 246 ExternalReference ExternalReference::wasm_f64_trunc() { 247 return ExternalReference(Redirect(FUNCTION_ADDR(wasm::f64_trunc_wrapper))); 248 } 249 250 ExternalReference ExternalReference::wasm_f64_floor() { 251 return ExternalReference(Redirect(FUNCTION_ADDR(wasm::f64_floor_wrapper))); 252 } 253 254 ExternalReference ExternalReference::wasm_f64_ceil() { 255 return ExternalReference(Redirect(FUNCTION_ADDR(wasm::f64_ceil_wrapper))); 256 } 257 258 ExternalReference ExternalReference::wasm_f64_nearest_int() { 259 return ExternalReference( 260 Redirect(FUNCTION_ADDR(wasm::f64_nearest_int_wrapper))); 261 } 262 263 ExternalReference ExternalReference::wasm_int64_to_float32() { 264 return ExternalReference( 265 Redirect(FUNCTION_ADDR(wasm::int64_to_float32_wrapper))); 266 } 267 268 ExternalReference ExternalReference::wasm_uint64_to_float32() { 269 return ExternalReference( 270 Redirect(FUNCTION_ADDR(wasm::uint64_to_float32_wrapper))); 271 } 272 273 ExternalReference ExternalReference::wasm_int64_to_float64() { 274 return ExternalReference( 275 Redirect(FUNCTION_ADDR(wasm::int64_to_float64_wrapper))); 276 } 277 278 ExternalReference ExternalReference::wasm_uint64_to_float64() { 279 return ExternalReference( 280 Redirect(FUNCTION_ADDR(wasm::uint64_to_float64_wrapper))); 281 } 282 283 ExternalReference ExternalReference::wasm_float32_to_int64() { 284 return ExternalReference( 285 Redirect(FUNCTION_ADDR(wasm::float32_to_int64_wrapper))); 286 } 287 288 ExternalReference ExternalReference::wasm_float32_to_uint64() { 289 return ExternalReference( 290 Redirect(FUNCTION_ADDR(wasm::float32_to_uint64_wrapper))); 291 } 292 293 ExternalReference ExternalReference::wasm_float64_to_int64() { 294 return ExternalReference( 295 Redirect(FUNCTION_ADDR(wasm::float64_to_int64_wrapper))); 296 } 297 298 ExternalReference ExternalReference::wasm_float64_to_uint64() { 299 return ExternalReference( 300 Redirect(FUNCTION_ADDR(wasm::float64_to_uint64_wrapper))); 301 } 302 303 ExternalReference ExternalReference::wasm_int64_div() { 304 return ExternalReference(Redirect(FUNCTION_ADDR(wasm::int64_div_wrapper))); 305 } 306 307 ExternalReference ExternalReference::wasm_int64_mod() { 308 return ExternalReference(Redirect(FUNCTION_ADDR(wasm::int64_mod_wrapper))); 309 } 310 311 ExternalReference ExternalReference::wasm_uint64_div() { 312 return ExternalReference(Redirect(FUNCTION_ADDR(wasm::uint64_div_wrapper))); 313 } 314 315 ExternalReference ExternalReference::wasm_uint64_mod() { 316 return ExternalReference(Redirect(FUNCTION_ADDR(wasm::uint64_mod_wrapper))); 317 } 318 319 ExternalReference ExternalReference::wasm_word32_ctz() { 320 return ExternalReference(Redirect(FUNCTION_ADDR(wasm::word32_ctz_wrapper))); 321 } 322 323 ExternalReference ExternalReference::wasm_word64_ctz() { 324 return ExternalReference(Redirect(FUNCTION_ADDR(wasm::word64_ctz_wrapper))); 325 } 326 327 ExternalReference ExternalReference::wasm_word32_popcnt() { 328 return ExternalReference( 329 Redirect(FUNCTION_ADDR(wasm::word32_popcnt_wrapper))); 330 } 331 332 ExternalReference ExternalReference::wasm_word64_popcnt() { 333 return ExternalReference( 334 Redirect(FUNCTION_ADDR(wasm::word64_popcnt_wrapper))); 335 } 336 337 ExternalReference ExternalReference::wasm_word32_rol() { 338 return ExternalReference(Redirect(FUNCTION_ADDR(wasm::word32_rol_wrapper))); 339 } 340 341 ExternalReference ExternalReference::wasm_word32_ror() { 342 return ExternalReference(Redirect(FUNCTION_ADDR(wasm::word32_ror_wrapper))); 343 } 344 345 static void f64_acos_wrapper(Address data) { 346 double input = ReadUnalignedValue<double>(data); 347 WriteUnalignedValue(data, base::ieee754::acos(input)); 348 } 349 350 ExternalReference ExternalReference::f64_acos_wrapper_function() { 351 return ExternalReference(Redirect(FUNCTION_ADDR(f64_acos_wrapper))); 352 } 353 354 static void f64_asin_wrapper(Address data) { 355 double input = ReadUnalignedValue<double>(data); 356 WriteUnalignedValue<double>(data, base::ieee754::asin(input)); 357 } 358 359 ExternalReference ExternalReference::f64_asin_wrapper_function() { 360 return ExternalReference(Redirect(FUNCTION_ADDR(f64_asin_wrapper))); 361 } 362 363 ExternalReference ExternalReference::wasm_float64_pow() { 364 return ExternalReference(Redirect(FUNCTION_ADDR(wasm::float64_pow_wrapper))); 365 } 366 367 static void f64_mod_wrapper(Address data) { 368 double dividend = ReadUnalignedValue<double>(data); 369 double divisor = ReadUnalignedValue<double>(data + sizeof(dividend)); 370 WriteUnalignedValue<double>(data, Modulo(dividend, divisor)); 371 } 372 373 ExternalReference ExternalReference::f64_mod_wrapper_function() { 374 return ExternalReference(Redirect(FUNCTION_ADDR(f64_mod_wrapper))); 375 } 376 377 ExternalReference ExternalReference::wasm_call_trap_callback_for_testing() { 378 return ExternalReference( 379 Redirect(FUNCTION_ADDR(wasm::call_trap_callback_for_testing))); 380 } 381 382 ExternalReference ExternalReference::log_enter_external_function() { 383 return ExternalReference(Redirect(FUNCTION_ADDR(Logger::EnterExternal))); 384 } 385 386 ExternalReference ExternalReference::log_leave_external_function() { 387 return ExternalReference(Redirect(FUNCTION_ADDR(Logger::LeaveExternal))); 388 } 389 390 ExternalReference ExternalReference::roots_array_start(Isolate* isolate) { 391 return ExternalReference(isolate->heap()->roots_array_start()); 392 } 393 394 ExternalReference ExternalReference::allocation_sites_list_address( 395 Isolate* isolate) { 396 return ExternalReference(isolate->heap()->allocation_sites_list_address()); 397 } 398 399 ExternalReference ExternalReference::address_of_stack_limit(Isolate* isolate) { 400 return ExternalReference(isolate->stack_guard()->address_of_jslimit()); 401 } 402 403 ExternalReference ExternalReference::address_of_real_stack_limit( 404 Isolate* isolate) { 405 return ExternalReference(isolate->stack_guard()->address_of_real_jslimit()); 406 } 407 408 ExternalReference ExternalReference::store_buffer_top(Isolate* isolate) { 409 return ExternalReference(isolate->heap()->store_buffer_top_address()); 410 } 411 412 ExternalReference ExternalReference::heap_is_marking_flag_address( 413 Isolate* isolate) { 414 return ExternalReference(isolate->heap()->IsMarkingFlagAddress()); 415 } 416 417 ExternalReference ExternalReference::new_space_allocation_top_address( 418 Isolate* isolate) { 419 return ExternalReference(isolate->heap()->NewSpaceAllocationTopAddress()); 420 } 421 422 ExternalReference ExternalReference::new_space_allocation_limit_address( 423 Isolate* isolate) { 424 return ExternalReference(isolate->heap()->NewSpaceAllocationLimitAddress()); 425 } 426 427 ExternalReference ExternalReference::old_space_allocation_top_address( 428 Isolate* isolate) { 429 return ExternalReference(isolate->heap()->OldSpaceAllocationTopAddress()); 430 } 431 432 ExternalReference ExternalReference::old_space_allocation_limit_address( 433 Isolate* isolate) { 434 return ExternalReference(isolate->heap()->OldSpaceAllocationLimitAddress()); 435 } 436 437 ExternalReference ExternalReference::handle_scope_level_address( 438 Isolate* isolate) { 439 return ExternalReference(HandleScope::current_level_address(isolate)); 440 } 441 442 ExternalReference ExternalReference::handle_scope_next_address( 443 Isolate* isolate) { 444 return ExternalReference(HandleScope::current_next_address(isolate)); 445 } 446 447 ExternalReference ExternalReference::handle_scope_limit_address( 448 Isolate* isolate) { 449 return ExternalReference(HandleScope::current_limit_address(isolate)); 450 } 451 452 ExternalReference ExternalReference::scheduled_exception_address( 453 Isolate* isolate) { 454 return ExternalReference(isolate->scheduled_exception_address()); 455 } 456 457 ExternalReference ExternalReference::address_of_pending_message_obj( 458 Isolate* isolate) { 459 return ExternalReference(isolate->pending_message_obj_address()); 460 } 461 462 ExternalReference ExternalReference::abort_with_reason() { 463 return ExternalReference(Redirect(FUNCTION_ADDR(i::abort_with_reason))); 464 } 465 466 ExternalReference ExternalReference::address_of_min_int() { 467 return ExternalReference(reinterpret_cast<Address>(&double_min_int_constant)); 468 } 469 470 ExternalReference ExternalReference::address_of_runtime_stats_flag() { 471 return ExternalReference(&FLAG_runtime_stats); 472 } 473 474 ExternalReference ExternalReference::address_of_one_half() { 475 return ExternalReference( 476 reinterpret_cast<Address>(&double_one_half_constant)); 477 } 478 479 ExternalReference ExternalReference::address_of_the_hole_nan() { 480 return ExternalReference( 481 reinterpret_cast<Address>(&double_the_hole_nan_constant)); 482 } 483 484 ExternalReference ExternalReference::address_of_uint32_bias() { 485 return ExternalReference( 486 reinterpret_cast<Address>(&double_uint32_bias_constant)); 487 } 488 489 ExternalReference ExternalReference::address_of_float_abs_constant() { 490 return ExternalReference(reinterpret_cast<Address>(&float_absolute_constant)); 491 } 492 493 ExternalReference ExternalReference::address_of_float_neg_constant() { 494 return ExternalReference(reinterpret_cast<Address>(&float_negate_constant)); 495 } 496 497 ExternalReference ExternalReference::address_of_double_abs_constant() { 498 return ExternalReference( 499 reinterpret_cast<Address>(&double_absolute_constant)); 500 } 501 502 ExternalReference ExternalReference::address_of_double_neg_constant() { 503 return ExternalReference(reinterpret_cast<Address>(&double_negate_constant)); 504 } 505 506 ExternalReference ExternalReference::is_profiling_address(Isolate* isolate) { 507 return ExternalReference(isolate->is_profiling_address()); 508 } 509 510 ExternalReference ExternalReference::invoke_function_callback() { 511 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); 512 ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL; 513 ApiFunction thunk_fun(thunk_address); 514 return ExternalReference::Create(&thunk_fun, thunk_type); 515 } 516 517 ExternalReference ExternalReference::invoke_accessor_getter_callback() { 518 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); 519 ExternalReference::Type thunk_type = ExternalReference::PROFILING_GETTER_CALL; 520 ApiFunction thunk_fun(thunk_address); 521 return ExternalReference::Create(&thunk_fun, thunk_type); 522 } 523 524 #ifndef V8_INTERPRETED_REGEXP 525 526 ExternalReference ExternalReference::re_check_stack_guard_state( 527 Isolate* isolate) { 528 Address function; 529 #if V8_TARGET_ARCH_X64 530 function = FUNCTION_ADDR(RegExpMacroAssemblerX64::CheckStackGuardState); 531 #elif V8_TARGET_ARCH_IA32 532 function = FUNCTION_ADDR(RegExpMacroAssemblerIA32::CheckStackGuardState); 533 #elif V8_TARGET_ARCH_ARM64 534 function = FUNCTION_ADDR(RegExpMacroAssemblerARM64::CheckStackGuardState); 535 #elif V8_TARGET_ARCH_ARM 536 function = FUNCTION_ADDR(RegExpMacroAssemblerARM::CheckStackGuardState); 537 #elif V8_TARGET_ARCH_PPC 538 function = FUNCTION_ADDR(RegExpMacroAssemblerPPC::CheckStackGuardState); 539 #elif V8_TARGET_ARCH_MIPS 540 function = FUNCTION_ADDR(RegExpMacroAssemblerMIPS::CheckStackGuardState); 541 #elif V8_TARGET_ARCH_MIPS64 542 function = FUNCTION_ADDR(RegExpMacroAssemblerMIPS::CheckStackGuardState); 543 #elif V8_TARGET_ARCH_S390 544 function = FUNCTION_ADDR(RegExpMacroAssemblerS390::CheckStackGuardState); 545 #else 546 UNREACHABLE(); 547 #endif 548 return ExternalReference(Redirect(function)); 549 } 550 551 ExternalReference ExternalReference::re_grow_stack(Isolate* isolate) { 552 return ExternalReference( 553 Redirect(FUNCTION_ADDR(NativeRegExpMacroAssembler::GrowStack))); 554 } 555 556 ExternalReference ExternalReference::re_case_insensitive_compare_uc16( 557 Isolate* isolate) { 558 return ExternalReference(Redirect( 559 FUNCTION_ADDR(NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16))); 560 } 561 562 ExternalReference ExternalReference::re_word_character_map(Isolate* isolate) { 563 return ExternalReference( 564 NativeRegExpMacroAssembler::word_character_map_address()); 565 } 566 567 ExternalReference ExternalReference::address_of_static_offsets_vector( 568 Isolate* isolate) { 569 return ExternalReference( 570 reinterpret_cast<Address>(isolate->jsregexp_static_offsets_vector())); 571 } 572 573 ExternalReference ExternalReference::address_of_regexp_stack_limit( 574 Isolate* isolate) { 575 return ExternalReference(isolate->regexp_stack()->limit_address()); 576 } 577 578 ExternalReference ExternalReference::address_of_regexp_stack_memory_address( 579 Isolate* isolate) { 580 return ExternalReference(isolate->regexp_stack()->memory_address()); 581 } 582 583 ExternalReference ExternalReference::address_of_regexp_stack_memory_size( 584 Isolate* isolate) { 585 return ExternalReference(isolate->regexp_stack()->memory_size_address()); 586 } 587 588 #endif // V8_INTERPRETED_REGEXP 589 590 ExternalReference ExternalReference::ieee754_acos_function() { 591 return ExternalReference( 592 Redirect(FUNCTION_ADDR(base::ieee754::acos), BUILTIN_FP_CALL)); 593 } 594 595 ExternalReference ExternalReference::ieee754_acosh_function() { 596 return ExternalReference( 597 Redirect(FUNCTION_ADDR(base::ieee754::acosh), BUILTIN_FP_FP_CALL)); 598 } 599 600 ExternalReference ExternalReference::ieee754_asin_function() { 601 return ExternalReference( 602 Redirect(FUNCTION_ADDR(base::ieee754::asin), BUILTIN_FP_CALL)); 603 } 604 605 ExternalReference ExternalReference::ieee754_asinh_function() { 606 return ExternalReference( 607 Redirect(FUNCTION_ADDR(base::ieee754::asinh), BUILTIN_FP_FP_CALL)); 608 } 609 610 ExternalReference ExternalReference::ieee754_atan_function() { 611 return ExternalReference( 612 Redirect(FUNCTION_ADDR(base::ieee754::atan), BUILTIN_FP_CALL)); 613 } 614 615 ExternalReference ExternalReference::ieee754_atanh_function() { 616 return ExternalReference( 617 Redirect(FUNCTION_ADDR(base::ieee754::atanh), BUILTIN_FP_FP_CALL)); 618 } 619 620 ExternalReference ExternalReference::ieee754_atan2_function() { 621 return ExternalReference( 622 Redirect(FUNCTION_ADDR(base::ieee754::atan2), BUILTIN_FP_FP_CALL)); 623 } 624 625 ExternalReference ExternalReference::ieee754_cbrt_function() { 626 return ExternalReference( 627 Redirect(FUNCTION_ADDR(base::ieee754::cbrt), BUILTIN_FP_FP_CALL)); 628 } 629 630 ExternalReference ExternalReference::ieee754_cos_function() { 631 return ExternalReference( 632 Redirect(FUNCTION_ADDR(base::ieee754::cos), BUILTIN_FP_CALL)); 633 } 634 635 ExternalReference ExternalReference::ieee754_cosh_function() { 636 return ExternalReference( 637 Redirect(FUNCTION_ADDR(base::ieee754::cosh), BUILTIN_FP_CALL)); 638 } 639 640 ExternalReference ExternalReference::ieee754_exp_function() { 641 return ExternalReference( 642 Redirect(FUNCTION_ADDR(base::ieee754::exp), BUILTIN_FP_CALL)); 643 } 644 645 ExternalReference ExternalReference::ieee754_expm1_function() { 646 return ExternalReference( 647 Redirect(FUNCTION_ADDR(base::ieee754::expm1), BUILTIN_FP_FP_CALL)); 648 } 649 650 ExternalReference ExternalReference::ieee754_log_function() { 651 return ExternalReference( 652 Redirect(FUNCTION_ADDR(base::ieee754::log), BUILTIN_FP_CALL)); 653 } 654 655 ExternalReference ExternalReference::ieee754_log1p_function() { 656 return ExternalReference( 657 Redirect(FUNCTION_ADDR(base::ieee754::log1p), BUILTIN_FP_CALL)); 658 } 659 660 ExternalReference ExternalReference::ieee754_log10_function() { 661 return ExternalReference( 662 Redirect(FUNCTION_ADDR(base::ieee754::log10), BUILTIN_FP_CALL)); 663 } 664 665 ExternalReference ExternalReference::ieee754_log2_function() { 666 return ExternalReference( 667 Redirect(FUNCTION_ADDR(base::ieee754::log2), BUILTIN_FP_CALL)); 668 } 669 670 ExternalReference ExternalReference::ieee754_sin_function() { 671 return ExternalReference( 672 Redirect(FUNCTION_ADDR(base::ieee754::sin), BUILTIN_FP_CALL)); 673 } 674 675 ExternalReference ExternalReference::ieee754_sinh_function() { 676 return ExternalReference( 677 Redirect(FUNCTION_ADDR(base::ieee754::sinh), BUILTIN_FP_CALL)); 678 } 679 680 ExternalReference ExternalReference::ieee754_tan_function() { 681 return ExternalReference( 682 Redirect(FUNCTION_ADDR(base::ieee754::tan), BUILTIN_FP_CALL)); 683 } 684 685 ExternalReference ExternalReference::ieee754_tanh_function() { 686 return ExternalReference( 687 Redirect(FUNCTION_ADDR(base::ieee754::tanh), BUILTIN_FP_CALL)); 688 } 689 690 void* libc_memchr(void* string, int character, size_t search_length) { 691 return memchr(string, character, search_length); 692 } 693 694 ExternalReference ExternalReference::libc_memchr_function() { 695 return ExternalReference(Redirect(FUNCTION_ADDR(libc_memchr))); 696 } 697 698 void* libc_memcpy(void* dest, const void* src, size_t n) { 699 return memcpy(dest, src, n); 700 } 701 702 ExternalReference ExternalReference::libc_memcpy_function() { 703 return ExternalReference(Redirect(FUNCTION_ADDR(libc_memcpy))); 704 } 705 706 void* libc_memmove(void* dest, const void* src, size_t n) { 707 return memmove(dest, src, n); 708 } 709 710 ExternalReference ExternalReference::libc_memmove_function() { 711 return ExternalReference(Redirect(FUNCTION_ADDR(libc_memmove))); 712 } 713 714 void* libc_memset(void* dest, int value, size_t n) { 715 DCHECK_EQ(static_cast<byte>(value), value); 716 return memset(dest, value, n); 717 } 718 719 ExternalReference ExternalReference::libc_memset_function() { 720 return ExternalReference(Redirect(FUNCTION_ADDR(libc_memset))); 721 } 722 723 ExternalReference ExternalReference::printf_function() { 724 return ExternalReference(Redirect(FUNCTION_ADDR(std::printf))); 725 } 726 727 template <typename SubjectChar, typename PatternChar> 728 ExternalReference ExternalReference::search_string_raw() { 729 auto f = SearchStringRaw<SubjectChar, PatternChar>; 730 return ExternalReference(Redirect(FUNCTION_ADDR(f))); 731 } 732 733 ExternalReference ExternalReference::search_string_raw_one_one() { 734 return search_string_raw<const uint8_t, const uint8_t>(); 735 } 736 737 ExternalReference ExternalReference::search_string_raw_one_two() { 738 return search_string_raw<const uint8_t, const uc16>(); 739 } 740 741 ExternalReference ExternalReference::search_string_raw_two_one() { 742 return search_string_raw<const uc16, const uint8_t>(); 743 } 744 745 ExternalReference ExternalReference::search_string_raw_two_two() { 746 return search_string_raw<const uc16, const uc16>(); 747 } 748 749 ExternalReference ExternalReference::orderedhashmap_gethash_raw() { 750 auto f = OrderedHashMap::GetHash; 751 return ExternalReference(Redirect(FUNCTION_ADDR(f))); 752 } 753 754 ExternalReference ExternalReference::get_or_create_hash_raw(Isolate* isolate) { 755 typedef Smi* (*GetOrCreateHash)(Isolate * isolate, Object * key); 756 GetOrCreateHash f = Object::GetOrCreateHash; 757 return ExternalReference(Redirect(FUNCTION_ADDR(f))); 758 } 759 760 ExternalReference ExternalReference::jsreceiver_create_identity_hash( 761 Isolate* isolate) { 762 typedef Smi* (*CreateIdentityHash)(Isolate * isolate, JSReceiver * key); 763 CreateIdentityHash f = JSReceiver::CreateIdentityHash; 764 return ExternalReference(Redirect(FUNCTION_ADDR(f))); 765 } 766 767 ExternalReference 768 ExternalReference::copy_fast_number_jsarray_elements_to_typed_array() { 769 return ExternalReference( 770 Redirect(FUNCTION_ADDR(CopyFastNumberJSArrayElementsToTypedArray))); 771 } 772 773 ExternalReference 774 ExternalReference::copy_typed_array_elements_to_typed_array() { 775 return ExternalReference( 776 Redirect(FUNCTION_ADDR(CopyTypedArrayElementsToTypedArray))); 777 } 778 779 ExternalReference ExternalReference::copy_typed_array_elements_slice() { 780 return ExternalReference( 781 Redirect(FUNCTION_ADDR(CopyTypedArrayElementsSlice))); 782 } 783 784 ExternalReference ExternalReference::try_internalize_string_function() { 785 return ExternalReference( 786 Redirect(FUNCTION_ADDR(StringTable::LookupStringIfExists_NoAllocate))); 787 } 788 789 ExternalReference ExternalReference::check_object_type() { 790 return ExternalReference(Redirect(FUNCTION_ADDR(CheckObjectType))); 791 } 792 793 #ifdef V8_INTL_SUPPORT 794 ExternalReference ExternalReference::intl_convert_one_byte_to_lower() { 795 return ExternalReference(Redirect(FUNCTION_ADDR(ConvertOneByteToLower))); 796 } 797 798 ExternalReference ExternalReference::intl_to_latin1_lower_table() { 799 uint8_t* ptr = const_cast<uint8_t*>(ToLatin1LowerTable()); 800 return ExternalReference(reinterpret_cast<Address>(ptr)); 801 } 802 #endif // V8_INTL_SUPPORT 803 804 // Explicit instantiations for all combinations of 1- and 2-byte strings. 805 template ExternalReference 806 ExternalReference::search_string_raw<const uint8_t, const uint8_t>(); 807 template ExternalReference 808 ExternalReference::search_string_raw<const uint8_t, const uc16>(); 809 template ExternalReference 810 ExternalReference::search_string_raw<const uc16, const uint8_t>(); 811 template ExternalReference 812 ExternalReference::search_string_raw<const uc16, const uc16>(); 813 814 ExternalReference ExternalReference::page_flags(Page* page) { 815 return ExternalReference(reinterpret_cast<Address>(page) + 816 MemoryChunk::kFlagsOffset); 817 } 818 819 ExternalReference ExternalReference::ForDeoptEntry(Address entry) { 820 return ExternalReference(entry); 821 } 822 823 ExternalReference ExternalReference::cpu_features() { 824 DCHECK(CpuFeatures::initialized_); 825 return ExternalReference(&CpuFeatures::supported_); 826 } 827 828 ExternalReference ExternalReference::promise_hook_address(Isolate* isolate) { 829 return ExternalReference(isolate->promise_hook_address()); 830 } 831 832 ExternalReference ExternalReference::async_event_delegate_address( 833 Isolate* isolate) { 834 return ExternalReference(isolate->async_event_delegate_address()); 835 } 836 837 ExternalReference 838 ExternalReference::promise_hook_or_async_event_delegate_address( 839 Isolate* isolate) { 840 return ExternalReference( 841 isolate->promise_hook_or_async_event_delegate_address()); 842 } 843 844 ExternalReference ExternalReference::debug_is_active_address(Isolate* isolate) { 845 return ExternalReference(isolate->debug()->is_active_address()); 846 } 847 848 ExternalReference ExternalReference::debug_hook_on_function_call_address( 849 Isolate* isolate) { 850 return ExternalReference(isolate->debug()->hook_on_function_call_address()); 851 } 852 853 ExternalReference ExternalReference::runtime_function_table_address( 854 Isolate* isolate) { 855 return ExternalReference( 856 const_cast<Runtime::Function*>(Runtime::RuntimeFunctionTable(isolate))); 857 } 858 859 ExternalReference ExternalReference::invalidate_prototype_chains_function() { 860 return ExternalReference( 861 Redirect(FUNCTION_ADDR(JSObject::InvalidatePrototypeChains))); 862 } 863 864 double power_helper(Isolate* isolate, double x, double y) { 865 int y_int = static_cast<int>(y); 866 if (y == y_int) { 867 return power_double_int(x, y_int); // Returns 1 if exponent is 0. 868 } 869 if (y == 0.5) { 870 lazily_initialize_fast_sqrt(isolate); 871 return (std::isinf(x)) ? V8_INFINITY 872 : fast_sqrt(x + 0.0, isolate); // Convert -0 to +0. 873 } 874 if (y == -0.5) { 875 lazily_initialize_fast_sqrt(isolate); 876 return (std::isinf(x)) ? 0 877 : 1.0 / fast_sqrt(x + 0.0, 878 isolate); // Convert -0 to +0. 879 } 880 return power_double_double(x, y); 881 } 882 883 // Helper function to compute x^y, where y is known to be an 884 // integer. Uses binary decomposition to limit the number of 885 // multiplications; see the discussion in "Hacker's Delight" by Henry 886 // S. Warren, Jr., figure 11-6, page 213. 887 double power_double_int(double x, int y) { 888 double m = (y < 0) ? 1 / x : x; 889 unsigned n = (y < 0) ? -y : y; 890 double p = 1; 891 while (n != 0) { 892 if ((n & 1) != 0) p *= m; 893 m *= m; 894 if ((n & 2) != 0) p *= m; 895 m *= m; 896 n >>= 2; 897 } 898 return p; 899 } 900 901 double power_double_double(double x, double y) { 902 // The checks for special cases can be dropped in ia32 because it has already 903 // been done in generated code before bailing out here. 904 if (std::isnan(y) || ((x == 1 || x == -1) && std::isinf(y))) { 905 return std::numeric_limits<double>::quiet_NaN(); 906 } 907 return Pow(x, y); 908 } 909 910 double modulo_double_double(double x, double y) { return Modulo(x, y); } 911 912 ExternalReference ExternalReference::power_double_double_function() { 913 return ExternalReference( 914 Redirect(FUNCTION_ADDR(power_double_double), BUILTIN_FP_FP_CALL)); 915 } 916 917 ExternalReference ExternalReference::mod_two_doubles_operation() { 918 return ExternalReference( 919 Redirect(FUNCTION_ADDR(modulo_double_double), BUILTIN_FP_FP_CALL)); 920 } 921 922 ExternalReference ExternalReference::debug_suspended_generator_address( 923 Isolate* isolate) { 924 return ExternalReference(isolate->debug()->suspended_generator_address()); 925 } 926 927 ExternalReference ExternalReference::debug_restart_fp_address( 928 Isolate* isolate) { 929 return ExternalReference(isolate->debug()->restart_fp_address()); 930 } 931 932 ExternalReference ExternalReference::wasm_thread_in_wasm_flag_address_address( 933 Isolate* isolate) { 934 return ExternalReference(reinterpret_cast<Address>( 935 &isolate->thread_local_top()->thread_in_wasm_flag_address_)); 936 } 937 938 ExternalReference ExternalReference::fixed_typed_array_base_data_offset() { 939 return ExternalReference(reinterpret_cast<void*>( 940 FixedTypedArrayBase::kDataOffset - kHeapObjectTag)); 941 } 942 943 bool operator==(ExternalReference lhs, ExternalReference rhs) { 944 return lhs.address() == rhs.address(); 945 } 946 947 bool operator!=(ExternalReference lhs, ExternalReference rhs) { 948 return !(lhs == rhs); 949 } 950 951 size_t hash_value(ExternalReference reference) { 952 return base::hash<Address>()(reference.address()); 953 } 954 955 std::ostream& operator<<(std::ostream& os, ExternalReference reference) { 956 os << reinterpret_cast<const void*>(reference.address()); 957 const Runtime::Function* fn = Runtime::FunctionForEntry(reference.address()); 958 if (fn) os << "<" << fn->name << ".entry>"; 959 return os; 960 } 961 962 void abort_with_reason(int reason) { 963 if (IsValidAbortReason(reason)) { 964 const char* message = GetAbortReason(static_cast<AbortReason>(reason)); 965 base::OS::PrintError("abort: %s\n", message); 966 } else { 967 base::OS::PrintError("abort: <unknown reason: %d>\n", reason); 968 } 969 base::OS::Abort(); 970 UNREACHABLE(); 971 } 972 973 } // namespace internal 974 } // namespace v8 975