11cb0ef41Sopenharmony_ci// Copyright 2009 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_EXECUTION_SIMULATOR_H_ 61cb0ef41Sopenharmony_ci#define V8_EXECUTION_SIMULATOR_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "src/common/globals.h" 91cb0ef41Sopenharmony_ci#include "src/objects/code.h" 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ci#if !defined(USE_SIMULATOR) 121cb0ef41Sopenharmony_ci#include "src/utils/utils.h" 131cb0ef41Sopenharmony_ci#endif 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ci#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 161cb0ef41Sopenharmony_ci// No simulator for ia32 or x64. 171cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_ARM64 181cb0ef41Sopenharmony_ci#include "src/execution/arm64/simulator-arm64.h" 191cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_ARM 201cb0ef41Sopenharmony_ci#include "src/execution/arm/simulator-arm.h" 211cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64 221cb0ef41Sopenharmony_ci#include "src/execution/ppc/simulator-ppc.h" 231cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_MIPS 241cb0ef41Sopenharmony_ci#include "src/execution/mips/simulator-mips.h" 251cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_MIPS64 261cb0ef41Sopenharmony_ci#include "src/execution/mips64/simulator-mips64.h" 271cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_LOONG64 281cb0ef41Sopenharmony_ci#include "src/execution/loong64/simulator-loong64.h" 291cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_S390 301cb0ef41Sopenharmony_ci#include "src/execution/s390/simulator-s390.h" 311cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_RISCV64 321cb0ef41Sopenharmony_ci#include "src/execution/riscv64/simulator-riscv64.h" 331cb0ef41Sopenharmony_ci#else 341cb0ef41Sopenharmony_ci#error Unsupported target architecture. 351cb0ef41Sopenharmony_ci#endif 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_cinamespace v8 { 381cb0ef41Sopenharmony_cinamespace internal { 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci#if defined(USE_SIMULATOR) 411cb0ef41Sopenharmony_ci// Running with a simulator. 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci// The simulator has its own stack. Thus it has a different stack limit from 441cb0ef41Sopenharmony_ci// the C-based native code. The JS-based limit normally points near the end of 451cb0ef41Sopenharmony_ci// the simulator stack. When the C-based limit is exhausted we reflect that by 461cb0ef41Sopenharmony_ci// lowering the JS-based limit as well, to make stack checks trigger. 471cb0ef41Sopenharmony_ciclass SimulatorStack : public v8::internal::AllStatic { 481cb0ef41Sopenharmony_ci public: 491cb0ef41Sopenharmony_ci static inline uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate, 501cb0ef41Sopenharmony_ci uintptr_t c_limit) { 511cb0ef41Sopenharmony_ci return Simulator::current(isolate)->StackLimit(c_limit); 521cb0ef41Sopenharmony_ci } 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci // Returns the current stack address on the simulator stack frame. 551cb0ef41Sopenharmony_ci // The returned address is comparable with JS stack address. 561cb0ef41Sopenharmony_ci static inline uintptr_t RegisterJSStackComparableAddress( 571cb0ef41Sopenharmony_ci v8::internal::Isolate* isolate) { 581cb0ef41Sopenharmony_ci // The value of |kPlaceHolder| is actually not used. It just occupies a 591cb0ef41Sopenharmony_ci // single word on the stack frame of the simulator. 601cb0ef41Sopenharmony_ci const uintptr_t kPlaceHolder = 0x4A535350u; // "JSSP" in ASCII 611cb0ef41Sopenharmony_ci return Simulator::current(isolate)->PushAddress(kPlaceHolder); 621cb0ef41Sopenharmony_ci } 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci static inline void UnregisterJSStackComparableAddress( 651cb0ef41Sopenharmony_ci v8::internal::Isolate* isolate) { 661cb0ef41Sopenharmony_ci Simulator::current(isolate)->PopAddress(); 671cb0ef41Sopenharmony_ci } 681cb0ef41Sopenharmony_ci}; 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci#else // defined(USE_SIMULATOR) 711cb0ef41Sopenharmony_ci// Running without a simulator on a native platform. 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci// The stack limit beyond which we will throw stack overflow errors in 741cb0ef41Sopenharmony_ci// generated code. Because generated code uses the C stack, we just use 751cb0ef41Sopenharmony_ci// the C stack limit. 761cb0ef41Sopenharmony_ciclass SimulatorStack : public v8::internal::AllStatic { 771cb0ef41Sopenharmony_ci public: 781cb0ef41Sopenharmony_ci static inline uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate, 791cb0ef41Sopenharmony_ci uintptr_t c_limit) { 801cb0ef41Sopenharmony_ci USE(isolate); 811cb0ef41Sopenharmony_ci return c_limit; 821cb0ef41Sopenharmony_ci } 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ci // Returns the current stack address on the native stack frame. 851cb0ef41Sopenharmony_ci // The returned address is comparable with JS stack address. 861cb0ef41Sopenharmony_ci static inline uintptr_t RegisterJSStackComparableAddress( 871cb0ef41Sopenharmony_ci v8::internal::Isolate* isolate) { 881cb0ef41Sopenharmony_ci USE(isolate); 891cb0ef41Sopenharmony_ci return internal::GetCurrentStackPosition(); 901cb0ef41Sopenharmony_ci } 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci static inline void UnregisterJSStackComparableAddress( 931cb0ef41Sopenharmony_ci v8::internal::Isolate* isolate) { 941cb0ef41Sopenharmony_ci USE(isolate); 951cb0ef41Sopenharmony_ci } 961cb0ef41Sopenharmony_ci}; 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci#endif // defined(USE_SIMULATOR) 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci// Use this class either as {GeneratedCode<ret, arg1, arg2>} or 1011cb0ef41Sopenharmony_ci// {GeneratedCode<ret(arg1, arg2)>} (see specialization below). 1021cb0ef41Sopenharmony_citemplate <typename Return, typename... Args> 1031cb0ef41Sopenharmony_ciclass GeneratedCode { 1041cb0ef41Sopenharmony_ci public: 1051cb0ef41Sopenharmony_ci using Signature = Return(Args...); 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci static GeneratedCode FromAddress(Isolate* isolate, Address addr) { 1081cb0ef41Sopenharmony_ci return GeneratedCode(isolate, reinterpret_cast<Signature*>(addr)); 1091cb0ef41Sopenharmony_ci } 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci static GeneratedCode FromBuffer(Isolate* isolate, byte* buffer) { 1121cb0ef41Sopenharmony_ci return GeneratedCode(isolate, reinterpret_cast<Signature*>(buffer)); 1131cb0ef41Sopenharmony_ci } 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci static GeneratedCode FromCode(Code code) { 1161cb0ef41Sopenharmony_ci return FromAddress(code.GetIsolate(), code.entry()); 1171cb0ef41Sopenharmony_ci } 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci#ifdef USE_SIMULATOR 1201cb0ef41Sopenharmony_ci // Defined in simulator-base.h. 1211cb0ef41Sopenharmony_ci Return Call(Args... args) { 1221cb0ef41Sopenharmony_ci// Starboard is a platform abstraction interface that also include Windows 1231cb0ef41Sopenharmony_ci// platforms like UWP. 1241cb0ef41Sopenharmony_ci#if defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN) && \ 1251cb0ef41Sopenharmony_ci !defined(V8_OS_STARBOARD) && !defined(V8_TARGET_ARCH_ARM) 1261cb0ef41Sopenharmony_ci FATAL( 1271cb0ef41Sopenharmony_ci "Generated code execution not possible during cross-compilation." 1281cb0ef41Sopenharmony_ci "Also, generic C function calls are not implemented on 32-bit arm " 1291cb0ef41Sopenharmony_ci "yet."); 1301cb0ef41Sopenharmony_ci#endif // defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN) && 1311cb0ef41Sopenharmony_ci // !defined(V8_OS_STARBOARD) && !defined(V8_TARGET_ARCH_ARM) 1321cb0ef41Sopenharmony_ci return Simulator::current(isolate_)->template Call<Return>( 1331cb0ef41Sopenharmony_ci reinterpret_cast<Address>(fn_ptr_), args...); 1341cb0ef41Sopenharmony_ci } 1351cb0ef41Sopenharmony_ci#else 1361cb0ef41Sopenharmony_ci 1371cb0ef41Sopenharmony_ci DISABLE_CFI_ICALL Return Call(Args... args) { 1381cb0ef41Sopenharmony_ci // When running without a simulator we call the entry directly. 1391cb0ef41Sopenharmony_ci// Starboard is a platform abstraction interface that also include Windows 1401cb0ef41Sopenharmony_ci// platforms like UWP. 1411cb0ef41Sopenharmony_ci#if defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN) && \ 1421cb0ef41Sopenharmony_ci !defined(V8_OS_STARBOARD) 1431cb0ef41Sopenharmony_ci FATAL("Generated code execution not possible during cross-compilation."); 1441cb0ef41Sopenharmony_ci#endif // defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN) 1451cb0ef41Sopenharmony_ci#if ABI_USES_FUNCTION_DESCRIPTORS 1461cb0ef41Sopenharmony_ci // AIX ABI requires function descriptors (FD). Artificially create a pseudo 1471cb0ef41Sopenharmony_ci // FD to ensure correct dispatch to generated code. The 'volatile' 1481cb0ef41Sopenharmony_ci // declaration is required to avoid the compiler from not observing the 1491cb0ef41Sopenharmony_ci // alias of the pseudo FD to the function pointer, and hence, optimizing the 1501cb0ef41Sopenharmony_ci // pseudo FD declaration/initialization away. 1511cb0ef41Sopenharmony_ci volatile Address function_desc[] = {reinterpret_cast<Address>(fn_ptr_), 0, 1521cb0ef41Sopenharmony_ci 0}; 1531cb0ef41Sopenharmony_ci Signature* fn = reinterpret_cast<Signature*>(function_desc); 1541cb0ef41Sopenharmony_ci return fn(args...); 1551cb0ef41Sopenharmony_ci#else 1561cb0ef41Sopenharmony_ci return fn_ptr_(args...); 1571cb0ef41Sopenharmony_ci#endif // ABI_USES_FUNCTION_DESCRIPTORS 1581cb0ef41Sopenharmony_ci } 1591cb0ef41Sopenharmony_ci#endif // USE_SIMULATOR 1601cb0ef41Sopenharmony_ci 1611cb0ef41Sopenharmony_ci private: 1621cb0ef41Sopenharmony_ci friend class GeneratedCode<Return(Args...)>; 1631cb0ef41Sopenharmony_ci Isolate* isolate_; 1641cb0ef41Sopenharmony_ci Signature* fn_ptr_; 1651cb0ef41Sopenharmony_ci GeneratedCode(Isolate* isolate, Signature* fn_ptr) 1661cb0ef41Sopenharmony_ci : isolate_(isolate), fn_ptr_(fn_ptr) {} 1671cb0ef41Sopenharmony_ci}; 1681cb0ef41Sopenharmony_ci 1691cb0ef41Sopenharmony_ci// Allow to use {GeneratedCode<ret(arg1, arg2)>} instead of 1701cb0ef41Sopenharmony_ci// {GeneratedCode<ret, arg1, arg2>}. 1711cb0ef41Sopenharmony_citemplate <typename Return, typename... Args> 1721cb0ef41Sopenharmony_ciclass GeneratedCode<Return(Args...)> : public GeneratedCode<Return, Args...> { 1731cb0ef41Sopenharmony_ci public: 1741cb0ef41Sopenharmony_ci // Automatically convert from {GeneratedCode<ret, arg1, arg2>} to 1751cb0ef41Sopenharmony_ci // {GeneratedCode<ret(arg1, arg2)>}. 1761cb0ef41Sopenharmony_ci GeneratedCode(GeneratedCode<Return, Args...> other) 1771cb0ef41Sopenharmony_ci : GeneratedCode<Return, Args...>(other.isolate_, other.fn_ptr_) {} 1781cb0ef41Sopenharmony_ci}; 1791cb0ef41Sopenharmony_ci 1801cb0ef41Sopenharmony_ci} // namespace internal 1811cb0ef41Sopenharmony_ci} // namespace v8 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci#endif // V8_EXECUTION_SIMULATOR_H_ 184