1 // Copyright 2011 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 #ifndef V8_BUILTINS_BUILTINS_H_ 6 #define V8_BUILTINS_BUILTINS_H_ 7 8 #include "src/base/flags.h" 9 #include "src/builtins/builtins-definitions.h" 10 #include "src/globals.h" 11 12 namespace v8 { 13 namespace internal { 14 15 class Callable; 16 template <typename T> 17 class Handle; 18 class Isolate; 19 20 // Forward declarations. 21 class BailoutId; 22 class RootVisitor; 23 enum class InterpreterPushArgsMode : unsigned; 24 namespace compiler { 25 class CodeAssemblerState; 26 } 27 28 // Convenience macro to avoid generating named accessors for all builtins. 29 #define BUILTIN_CODE(isolate, name) \ 30 (isolate)->builtins()->builtin_handle(Builtins::k##name) 31 32 class Builtins { 33 public: Builtins(Isolate * isolate)34 explicit Builtins(Isolate* isolate) : isolate_(isolate) {} 35 36 void TearDown(); 37 38 // Disassembler support. 39 const char* Lookup(Address pc); 40 41 enum Name : int32_t { 42 #define DEF_ENUM(Name, ...) k##Name, 43 #define DEF_ENUM_BYTECODE_HANDLER(Name, ...) \ 44 k##Name##Handler, k##Name##WideHandler, k##Name##ExtraWideHandler, 45 BUILTIN_LIST(DEF_ENUM, DEF_ENUM, DEF_ENUM, DEF_ENUM, DEF_ENUM, DEF_ENUM, 46 DEF_ENUM_BYTECODE_HANDLER, DEF_ENUM) 47 #undef DEF_ENUM 48 #undef DEF_ENUM_BYTECODE_HANDLER 49 builtin_count 50 }; 51 52 static const int32_t kNoBuiltinId = -1; 53 IsBuiltinId(int maybe_id)54 static constexpr bool IsBuiltinId(int maybe_id) { 55 return 0 <= maybe_id && maybe_id < builtin_count; 56 } 57 58 // The different builtin kinds are documented in builtins-definitions.h. 59 enum Kind { CPP, API, TFJ, TFC, TFS, TFH, BCH, ASM }; 60 61 static BailoutId GetContinuationBailoutId(Name name); 62 static Name GetBuiltinFromBailoutId(BailoutId); 63 64 // Convenience wrappers. 65 Handle<Code> CallFunction(ConvertReceiverMode = ConvertReceiverMode::kAny); 66 Handle<Code> Call(ConvertReceiverMode = ConvertReceiverMode::kAny); 67 Handle<Code> NonPrimitiveToPrimitive( 68 ToPrimitiveHint hint = ToPrimitiveHint::kDefault); 69 Handle<Code> OrdinaryToPrimitive(OrdinaryToPrimitiveHint hint); 70 Handle<Code> InterpreterPushArgsThenCall(ConvertReceiverMode receiver_mode, 71 InterpreterPushArgsMode mode); 72 Handle<Code> InterpreterPushArgsThenConstruct(InterpreterPushArgsMode mode); 73 Handle<Code> NewFunctionContext(ScopeType scope_type); 74 Handle<Code> JSConstructStubGeneric(); 75 76 // Used by BuiltinDeserializer and CreateOffHeapTrampolines in isolate.cc. 77 void set_builtin(int index, HeapObject* builtin); 78 79 Code* builtin(int index); 80 V8_EXPORT_PRIVATE Handle<Code> builtin_handle(int index); 81 82 V8_EXPORT_PRIVATE static Callable CallableFor(Isolate* isolate, Name name); 83 84 static int GetStackParameterCount(Name name); 85 86 static const char* name(int index); 87 88 // Returns the C++ entry point for builtins implemented in C++, and the null 89 // Address otherwise. 90 static Address CppEntryOf(int index); 91 92 static Kind KindOf(int index); 93 static const char* KindNameOf(int index); 94 95 static bool IsCpp(int index); 96 static bool HasCppImplementation(int index); 97 98 // True, iff the given code object is a builtin. Note that this does not 99 // necessarily mean that its kind is Code::BUILTIN. 100 static bool IsBuiltin(const Code* code); 101 102 // As above, but safe to access off the main thread since the check is done 103 // by handle location. Similar to Heap::IsRootHandle. 104 bool IsBuiltinHandle(Handle<HeapObject> maybe_code, int* index) const; 105 106 // True, iff the given code object is a builtin with off-heap embedded code. 107 static bool IsIsolateIndependentBuiltin(const Code* code); 108 109 // Returns true iff the given builtin can be lazy-loaded from the snapshot. 110 // This is true in general for most builtins with the exception of a few 111 // special cases such as CompileLazy and DeserializeLazy. 112 static bool IsLazy(int index); 113 114 // Helper methods used for testing isolate-independent builtins. 115 // TODO(jgruber,v8:6666): Remove once all builtins have been migrated. 116 static bool IsIsolateIndependent(int index); 117 118 // Wasm runtime stubs are treated specially by wasm. To guarantee reachability 119 // through near jumps, their code is completely copied into a fresh off-heap 120 // area. 121 static bool IsWasmRuntimeStub(int index); 122 is_initialized()123 bool is_initialized() const { return initialized_; } 124 125 // Used by SetupIsolateDelegate and Deserializer. MarkInitialized()126 void MarkInitialized() { 127 DCHECK(!initialized_); 128 initialized_ = true; 129 } 130 131 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> InvokeApiFunction( 132 Isolate* isolate, bool is_construct, Handle<HeapObject> function, 133 Handle<Object> receiver, int argc, Handle<Object> args[], 134 Handle<HeapObject> new_target); 135 136 enum ExitFrameType { EXIT, BUILTIN_EXIT }; 137 138 static void Generate_Adaptor(MacroAssembler* masm, Address builtin_address, 139 ExitFrameType exit_frame_type); 140 141 static void Generate_CEntry(MacroAssembler* masm, int result_size, 142 SaveFPRegsMode save_doubles, ArgvMode argv_mode, 143 bool builtin_exit_frame); 144 145 static bool AllowDynamicFunction(Isolate* isolate, Handle<JSFunction> target, 146 Handle<JSObject> target_global_proxy); 147 148 // Creates a trampoline code object that jumps to the given off-heap entry. 149 // The result should not be used directly, but only from the related Factory 150 // function. 151 static Handle<Code> GenerateOffHeapTrampolineFor(Isolate* isolate, 152 Address off_heap_entry); 153 154 private: 155 static void Generate_CallFunction(MacroAssembler* masm, 156 ConvertReceiverMode mode); 157 158 static void Generate_CallBoundFunctionImpl(MacroAssembler* masm); 159 160 static void Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode); 161 162 enum class CallOrConstructMode { kCall, kConstruct }; 163 static void Generate_CallOrConstructVarargs(MacroAssembler* masm, 164 Handle<Code> code); 165 static void Generate_CallOrConstructForwardVarargs(MacroAssembler* masm, 166 CallOrConstructMode mode, 167 Handle<Code> code); 168 169 static void Generate_InterpreterPushArgsThenCallImpl( 170 MacroAssembler* masm, ConvertReceiverMode receiver_mode, 171 InterpreterPushArgsMode mode); 172 173 static void Generate_InterpreterPushArgsThenConstructImpl( 174 MacroAssembler* masm, InterpreterPushArgsMode mode); 175 176 #define DECLARE_ASM(Name, ...) \ 177 static void Generate_##Name(MacroAssembler* masm); 178 #define DECLARE_TF(Name, ...) \ 179 static void Generate_##Name(compiler::CodeAssemblerState* state); 180 181 BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, DECLARE_TF, DECLARE_TF, 182 DECLARE_TF, DECLARE_TF, IGNORE_BUILTIN, DECLARE_ASM) 183 184 #undef DECLARE_ASM 185 #undef DECLARE_TF 186 187 Isolate* isolate_; 188 bool initialized_ = false; 189 190 friend class SetupIsolateDelegate; 191 192 DISALLOW_COPY_AND_ASSIGN(Builtins); 193 }; 194 195 } // namespace internal 196 } // namespace v8 197 198 #endif // V8_BUILTINS_BUILTINS_H_ 199