v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
wasm-compiler.h
Go to the documentation of this file.
1// Copyright 2015 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_COMPILER_WASM_COMPILER_H_
6#define V8_COMPILER_WASM_COMPILER_H_
7
8#if !V8_ENABLE_WEBASSEMBLY
9#error This header should only be included if WebAssembly is enabled.
10#endif // !V8_ENABLE_WEBASSEMBLY
11
12#include <memory>
13#include <utility>
14
15// Clients of this interface shouldn't depend on lots of compiler internals.
16// Do not include anything else from src/compiler here!
20#include "src/runtime/runtime.h"
28#include "src/zone/zone.h"
29
30namespace v8 {
31
32class CFunctionInfo;
33
34namespace internal {
35enum class AbortReason : uint8_t;
36struct AssemblerOptions;
37enum class BranchHint : uint8_t;
38class TurbofanCompilationJob;
39
40namespace compiler {
41// Forward declarations for some compiler data structures.
42class CallDescriptor;
43class TFGraph;
44class MachineGraph;
45class Node;
46class NodeOriginTable;
47class Operator;
48class SourcePositionTable;
49struct WasmCompilationData;
50class WasmDecorator;
51class WasmGraphAssembler;
52enum class TrapId : int32_t;
53struct Int64LoweringSpecialCase;
54template <size_t VarCount>
57} // namespace compiler
58
59namespace wasm {
60struct DecodeStruct;
61class WasmCode;
62class WireBytesStorage;
63enum class LoadTransformationKind : uint8_t;
64enum Suspend : int;
66} // namespace wasm
67
68namespace compiler {
69
70// Compiles an import call wrapper, which allows Wasm to call imports.
71V8_EXPORT_PRIVATE wasm::WasmCompilationResult CompileWasmImportCallWrapper(
72 wasm::ImportCallKind, const wasm::CanonicalSig*, bool source_positions,
73 int expected_arity, wasm::Suspend);
74
75// Compiles a host call wrapper, which allows Wasm to call host functions.
76wasm::WasmCompilationResult CompileWasmCapiCallWrapper(
77 const wasm::CanonicalSig*);
78
80// Compiles a wrapper to call a Fast API function from Wasm.
81wasm::WasmCompilationResult CompileWasmJSFastCallWrapper(
82 const wasm::CanonicalSig*, DirectHandle<JSReceiver> callable);
83
84// Returns a TurboshaftCompilationJob object for a JS to Wasm wrapper.
85std::unique_ptr<OptimizedCompilationJob> NewJSToWasmCompilationJob(
86 Isolate* isolate, const wasm::CanonicalSig* sig);
87
96
97// Compiles a stub with C++ linkage, to be called from Execution::CallWasm,
98// which knows how to feed it its parameters.
100 const wasm::CanonicalSig*);
101
105 // This loop has, to our best knowledge, no other loops nested within it. A
106 // loop can obtain inner loops despite this after inlining.
108
113};
114
118
119 size_t body_size() { return func_body.end - func_body.start; }
120
124 std::vector<WasmLoopInfo>* loop_infos{nullptr};
125 std::unique_ptr<wasm::AssumptionsJournal> assumptions{};
128};
129
130// Abstracts details of building TurboFan graph nodes for wasm to separate
131// the wasm decoder from the internal details of TurboFan.
133 public:
134 // ParameterMode specifies how the instance is passed.
136 // Normal wasm functions pass the instance as an implicit first parameter.
138 // For Wasm-to-JS and C-API wrappers, a {WasmImportData} object is
139 // passed as first parameter.
141 // For JS-to-Wasm wrappers (which are JS functions), we load the Wasm
142 // instance from the JS function data. The generated code objects live on
143 // the JS heap, so those compilation pass an isolate.
145 // The JS-to-JS wrapper does not have an associated instance.
146 // The C-entry stub uses a custom ABI (see {CWasmEntryParameters}).
148 };
149
153 ParameterMode parameter_mode, Isolate* isolate,
154 wasm::WasmEnabledFeatures enabled_features,
155 const wasm::CanonicalSig* wrapper_sig = nullptr);
156
158
159 bool TryWasmInlining(int fct_index, wasm::NativeModule* native_module,
160 int inlining_id);
161
162 //-----------------------------------------------------------------------
163 // Operations independent of {control} or {effect}.
164 //-----------------------------------------------------------------------
165 void Start(unsigned params);
166 Node* Param(int index, const char* debug_name = nullptr);
167 void TerminateThrow(Node* effect, Node* control);
168 Node* Int32Constant(int32_t value);
169
170 //-----------------------------------------------------------------------
171 // Operations that read and/or write {control} and {effect}.
172 //-----------------------------------------------------------------------
173
175 template <typename... Nodes>
176 Node* Return(Node* fst, Nodes*... more) {
177 Node* arr[] = {fst, more...};
178 return Return(base::ArrayVector(arr));
179 }
180
181 Node* effect();
182 Node* control();
183 Node* SetEffect(Node* node);
184 Node* SetControl(Node* node);
185 void SetEffectControl(Node* effect, Node* control);
186 Node* SetEffectControl(Node* effect_and_control) {
187 SetEffectControl(effect_and_control, effect_and_control);
188 return effect_and_control;
189 }
190
191 Node* SetType(Node* node, wasm::ValueType type);
192
193 // Overload for when we want to provide a specific signature, rather than
194 // build one using sig_, for example after scalar lowering.
197
199
200 Node* IsNull(Node* object, wasm::ValueType type);
201 Node* TypeGuard(Node* value, wasm::ValueType type);
202
203 bool has_simd() const { return has_simd_; }
204
206 TFGraph* graph();
207 Zone* graph_zone();
208
209 protected:
211
214
216 Node* BuildSafeStore(int offset, wasm::ValueTypeBase type, Node* arg_buffer,
217 Node* value, Node* effect, Node* control);
218
219 Node* BuildCallNode(size_t param_count, base::Vector<Node*> args,
220 wasm::WasmCodePosition position, Node* instance_node,
221 const Operator* op, Node* frame_state = nullptr);
222 template <typename T>
225 Node* implicit_first_arg, bool indirect,
226 Node* frame_state = nullptr);
227
228 //-----------------------------------------------------------------------
229 // Operations involving the CEntry, a dependency we want to remove
230 // to get off the GC heap.
231 //-----------------------------------------------------------------------
233 int parameter_count);
234
236 Node** parameters, int parameter_count);
237
238 TrapId GetTrapIdForTrap(wasm::TrapReason reason);
239
240 void BuildModifyThreadInWasmFlag(bool new_value);
241 void BuildModifyThreadInWasmFlagHelper(Node* thread_in_wasm_flag_address,
242 bool new_value);
243
245
246 void Assert(Node* condition, AbortReason abort_reason);
247
248 std::unique_ptr<WasmGraphAssembler> gasm_;
249 Zone* const zone_;
252 // For the main WasmGraphBuilder class, this is identical to the features
253 // field in {env_}, but the WasmWrapperGraphBuilder subclass doesn't have
254 // that, so common code should use this field instead.
256
258
261
262 bool has_simd_ = false;
263 bool needs_stack_check_ = false;
264
266 const wasm::CanonicalSig* const wrapper_sig_{nullptr};
267
269
271 int inlining_id_ = -1;
276 static constexpr int kNoCachedMemoryIndex = -1;
278};
279
281 Zone* zone, MachineGraph* mcgraph, const wasm::CanonicalSig* signature,
282 Isolate* isolate, compiler::SourcePositionTable* spt, Node* frame_state,
283 bool set_in_wasm_flag);
284
287
288template <typename T>
290 Zone* zone, const Signature<T>* sig, wasm::CallOrigin origin);
291
292} // namespace compiler
293} // namespace internal
294} // namespace v8
295
296#endif // V8_COMPILER_WASM_COMPILER_H_
#define Assert(condition)
int16_t parameter_count
Definition builtins.cc:67
Node * Return(Node *fst, Nodes *... more)
Node * BuildSafeStore(int offset, wasm::ValueTypeBase type, Node *arg_buffer, Node *value, Node *effect, Node *control)
V8_EXPORT_PRIVATE void LowerInt64(Signature< MachineRepresentation > *sig)
SetOncePointer< const Operator > stack_check_call_operator_
Node * Return(base::Vector< Node * > nodes)
Node * SetType(Node *node, wasm::ValueType type)
void BuildModifyThreadInWasmFlagHelper(Node *thread_in_wasm_flag_address, bool new_value)
bool TryWasmInlining(int fct_index, wasm::NativeModule *native_module, int inlining_id)
std::unique_ptr< WasmGraphAssembler > gasm_
Node * BuildCallToRuntime(Runtime::FunctionId f, Node **parameters, int parameter_count)
const wasm::CanonicalSig *const wrapper_sig_
Node * TypeGuard(Node *value, wasm::ValueType type)
wasm::WasmEnabledFeatures enabled_features_
Node * BuildWasmCall(const Signature< T > *sig, base::Vector< Node * > args, base::Vector< Node * > rets, wasm::WasmCodePosition position, Node *implicit_first_arg, bool indirect, Node *frame_state=nullptr)
void SetSourcePosition(Node *node, wasm::WasmCodePosition position)
Node * Param(int index, const char *debug_name=nullptr)
Node * IsNull(Node *object, wasm::ValueType type)
Node * BuildCallNode(size_t param_count, base::Vector< Node * > args, wasm::WasmCodePosition position, Node *instance_node, const Operator *op, Node *frame_state=nullptr)
const Operator * GetSafeLoadOperator(int offset, wasm::ValueTypeBase type)
void SetEffectControl(Node *effect, Node *control)
void TerminateThrow(Node *effect, Node *control)
V8_EXPORT_PRIVATE WasmGraphBuilder(wasm::CompilationEnv *env, Zone *zone, MachineGraph *mcgraph, const wasm::FunctionSig *sig, compiler::SourcePositionTable *spt, ParameterMode parameter_mode, Isolate *isolate, wasm::WasmEnabledFeatures enabled_features, const wasm::CanonicalSig *wrapper_sig=nullptr)
const wasm::FunctionSig *const function_sig_
Node * BuildChangeInt64ToBigInt(Node *input, StubCallMode stub_mode)
TrapId GetTrapIdForTrap(wasm::TrapReason reason)
Node * SetEffectControl(Node *effect_and_control)
compiler::SourcePositionTable *const source_position_table_
SetOncePointer< Node > stack_check_code_node_
Node * BuildCallToRuntimeWithContext(Runtime::FunctionId f, Node *js_context, Node **parameters, int parameter_count)
base::Vector< const DirectHandle< Object > > args
Definition execution.cc:74
SourcePositionTable * source_positions
int32_t offset
int position
Definition liveedit.cc:290
int int32_t
Definition unicode.cc:40
constexpr Vector< T > ArrayVector(T(&arr)[N])
Definition vector.h:354
AssemblerOptions WasmAssemblerOptions()
AssemblerOptions WasmStubAssemblerOptions()
Signature< MachineRepresentation > * CreateMachineSignature(Zone *zone, const Signature< T > *sig, wasm::CallOrigin origin)
bool IsFastCallSupportedSignature(const v8::CFunctionInfo *sig)
wasm::WasmCompilationResult CompileWasmCapiCallWrapper(const wasm::CanonicalSig *sig)
std::unique_ptr< OptimizedCompilationJob > NewJSToWasmCompilationJob(Isolate *isolate, const wasm::CanonicalSig *sig)
wasm::WasmCompilationResult CompileWasmImportCallWrapper(wasm::ImportCallKind kind, const wasm::CanonicalSig *sig, bool source_positions, int expected_arity, wasm::Suspend suspend)
void BuildInlinedJSToWasmWrapper(Zone *zone, MachineGraph *mcgraph, const wasm::CanonicalSig *signature, Isolate *isolate, compiler::SourcePositionTable *spt, Node *frame_state, bool set_in_wasm_flag)
wasm::WasmCompilationResult CompileWasmJSFastCallWrapper(const wasm::CanonicalSig *sig, DirectHandle< JSReceiver > callable)
Handle< Code > CompileCWasmEntry(Isolate *isolate, const wasm::CanonicalSig *sig)
kWasmInternalFunctionIndirectPointerTag kProtectedInstanceDataOffset sig
Definition c-api.cc:87
#define V8_EXPORT_PRIVATE
Definition macros.h:460
const wasm::WireBytesStorage * wire_bytes_storage
WasmCompilationData(const wasm::FunctionBody &func_body)
std::unique_ptr< wasm::AssumptionsJournal > assumptions
std::vector< WasmLoopInfo > * loop_infos
WasmLoopInfo(Node *header, uint32_t nesting_depth, bool can_be_innermost)