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