• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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