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