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