Line data Source code
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 : #include <memory>
9 :
10 : // Clients of this interface shouldn't depend on lots of compiler internals.
11 : // Do not include anything from src/compiler here!
12 : #include "src/compilation-info.h"
13 : #include "src/compiler.h"
14 : #include "src/trap-handler/trap-handler.h"
15 : #include "src/wasm/function-body-decoder.h"
16 : #include "src/wasm/wasm-module.h"
17 : #include "src/wasm/wasm-opcodes.h"
18 : #include "src/wasm/wasm-result.h"
19 : #include "src/zone/zone.h"
20 :
21 : namespace v8 {
22 : namespace internal {
23 :
24 : namespace compiler {
25 : // Forward declarations for some compiler data structures.
26 : class Node;
27 : class JSGraph;
28 : class Graph;
29 : class Operator;
30 : class SourcePositionTable;
31 : } // namespace compiler
32 :
33 : namespace wasm {
34 : struct DecodeStruct;
35 : class SignatureMap;
36 : // Expose {Node} and {Graph} opaquely as {wasm::TFNode} and {wasm::TFGraph}.
37 : typedef compiler::Node TFNode;
38 : typedef compiler::JSGraph TFGraph;
39 : } // namespace wasm
40 :
41 : namespace compiler {
42 :
43 : // The {ModuleEnv} encapsulates the module data that is used by the
44 : // {WasmGraphBuilder} during graph building. It represents the parameters to
45 : // which the compiled code should be specialized, including which code to call
46 : // for direct calls {function_code}, which tables to use for indirect calls
47 : // {function_tables}, memory start address and size {mem_start, mem_size},
48 : // as well as signature maps {signature_maps} and the module itself {module}.
49 : // ModuleEnvs are shareable across multiple compilations.
50 1192439 : struct ModuleEnv {
51 : // A pointer to the decoded module's static representation.
52 : const wasm::WasmModule* module;
53 : // The function tables are FixedArrays of code used to dispatch indirect
54 : // calls. (the same length as module.function_tables). We use the address
55 : // to a global handle to the FixedArray.
56 : const std::vector<Address> function_tables;
57 : // The signatures tables are FixedArrays of SMIs used to check signatures
58 : // match at runtime.
59 : // (the same length as module.function_tables)
60 : // We use the address to a global handle to the FixedArray.
61 : const std::vector<Address> signature_tables;
62 : // Contains the code objects to call for each direct call.
63 : // (the same length as module.functions)
64 : const std::vector<Handle<Code>> function_code;
65 : // If the default code is not a null handle, always use it for direct calls.
66 : const Handle<Code> default_function_code;
67 : };
68 :
69 : enum RuntimeExceptionSupport : bool {
70 : kRuntimeExceptionSupport = true,
71 : kNoRuntimeExceptionSupport = false
72 : };
73 :
74 467600 : class WasmCompilationUnit final {
75 : public:
76 : // If constructing from a background thread, pass in a Counters*, and ensure
77 : // that the Counters live at least as long as this compilation unit (which
78 : // typically means to hold a std::shared_ptr<Counters>).
79 : // If no such pointer is passed, Isolate::counters() will be called. This is
80 : // only allowed to happen on the foreground thread.
81 : WasmCompilationUnit(Isolate*, ModuleEnv*, wasm::FunctionBody, wasm::WasmName,
82 : int index, Handle<Code> centry_stub, Counters* = nullptr,
83 : RuntimeExceptionSupport = kRuntimeExceptionSupport,
84 : bool lower_simd = false);
85 :
86 : int func_index() const { return func_index_; }
87 :
88 : void ExecuteCompilation();
89 : MaybeHandle<Code> FinishCompilation(wasm::ErrorThrower* thrower);
90 :
91 : static MaybeHandle<Code> CompileWasmFunction(
92 : wasm::ErrorThrower* thrower, Isolate* isolate,
93 : const wasm::ModuleWireBytes& wire_bytes, ModuleEnv* env,
94 : const wasm::WasmFunction* function);
95 :
96 227958 : void set_memory_cost(size_t memory_cost) { memory_cost_ = memory_cost; }
97 : size_t memory_cost() const { return memory_cost_; }
98 :
99 : private:
100 : SourcePositionTable* BuildGraphForWasmFunction(double* decode_ms);
101 : Counters* counters() { return counters_; }
102 :
103 : Isolate* isolate_;
104 : ModuleEnv* env_;
105 : wasm::FunctionBody func_body_;
106 : wasm::WasmName func_name_;
107 : Counters* counters_;
108 : // The graph zone is deallocated at the end of ExecuteCompilation by virtue of
109 : // it being zone allocated.
110 : JSGraph* jsgraph_ = nullptr;
111 : // the compilation_zone_, info_, and job_ fields need to survive past
112 : // ExecuteCompilation, onto FinishCompilation (which happens on the main
113 : // thread).
114 : std::unique_ptr<Zone> compilation_zone_;
115 : std::unique_ptr<CompilationInfo> info_;
116 : std::unique_ptr<CompilationJob> job_;
117 : Handle<Code> centry_stub_;
118 : int func_index_;
119 : wasm::Result<wasm::DecodeStruct*> graph_construction_result_;
120 : // See WasmGraphBuilder::runtime_exception_support_.
121 : RuntimeExceptionSupport runtime_exception_support_;
122 : bool ok_ = true;
123 : size_t memory_cost_ = 0;
124 : bool lower_simd_;
125 :
126 : DISALLOW_COPY_AND_ASSIGN(WasmCompilationUnit);
127 : };
128 :
129 : // Wraps a JS function, producing a code object that can be called from wasm.
130 : // The global_js_imports_table is a global handle to a fixed array of target
131 : // JSReceiver with the lifetime tied to the module. We store it's location (non
132 : // GCable) in the generated code so that it can reside outside of GCed heap.
133 : Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target,
134 : wasm::FunctionSig* sig, uint32_t index,
135 : wasm::ModuleOrigin origin,
136 : Handle<FixedArray> global_js_imports_table);
137 :
138 : // Wraps a given wasm code object, producing a code object.
139 : Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::WasmModule* module,
140 : Handle<Code> wasm_code, uint32_t index,
141 : Address wasm_context_address);
142 :
143 : // Wraps a wasm function, producing a code object that can be called from other
144 : // wasm instances (the WasmContext address must be changed).
145 : Handle<Code> CompileWasmToWasmWrapper(Isolate* isolate, Handle<Code> target,
146 : wasm::FunctionSig* sig,
147 : uint32_t func_index,
148 : Address new_wasm_context_address);
149 :
150 : // Compiles a stub that redirects a call to a wasm function to the wasm
151 : // interpreter. It's ABI compatible with the compiled wasm function.
152 : Handle<Code> CompileWasmInterpreterEntry(Isolate* isolate, uint32_t func_index,
153 : wasm::FunctionSig* sig,
154 : Handle<WasmInstanceObject> instance);
155 :
156 : enum CWasmEntryParameters {
157 : kCodeObject,
158 : kArgumentsBuffer,
159 : // marker:
160 : kNumParameters
161 : };
162 :
163 : // Compiles a stub with JS linkage, taking parameters as described by
164 : // {CWasmEntryParameters}. It loads the wasm parameters from the argument
165 : // buffer and calls the wasm function given as first parameter.
166 : Handle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig,
167 : Address wasm_context_address);
168 :
169 : // Abstracts details of building TurboFan graph nodes for wasm to separate
170 : // the wasm decoder from the internal details of TurboFan.
171 : typedef ZoneVector<Node*> NodeVector;
172 : class WasmGraphBuilder {
173 : public:
174 : WasmGraphBuilder(ModuleEnv*, Zone*, JSGraph*, Handle<Code> centry_stub_,
175 : wasm::FunctionSig*, compiler::SourcePositionTable* = nullptr,
176 : RuntimeExceptionSupport = kRuntimeExceptionSupport);
177 :
178 1367297 : Node** Buffer(size_t count) {
179 1367297 : if (count > cur_bufsize_) {
180 5394 : size_t new_size = count + cur_bufsize_ + 5;
181 : cur_buffer_ =
182 5394 : reinterpret_cast<Node**>(zone_->New(new_size * sizeof(Node*)));
183 5394 : cur_bufsize_ = new_size;
184 : }
185 1367297 : return cur_buffer_;
186 : }
187 :
188 : //-----------------------------------------------------------------------
189 : // Operations independent of {control} or {effect}.
190 : //-----------------------------------------------------------------------
191 : Node* Error();
192 : Node* Start(unsigned params);
193 : Node* Param(unsigned index);
194 : Node* Loop(Node* entry);
195 : Node* Terminate(Node* effect, Node* control);
196 : Node* Merge(unsigned count, Node** controls);
197 : Node* Phi(wasm::ValueType type, unsigned count, Node** vals, Node* control);
198 : Node* EffectPhi(unsigned count, Node** effects, Node* control);
199 : Node* NumberConstant(int32_t value);
200 : Node* Uint32Constant(uint32_t value);
201 : Node* Int32Constant(int32_t value);
202 : Node* Int64Constant(int64_t value);
203 : Node* IntPtrConstant(intptr_t value);
204 : Node* Float32Constant(float value);
205 : Node* Float64Constant(double value);
206 : Node* HeapConstant(Handle<HeapObject> value);
207 : Node* Binop(wasm::WasmOpcode opcode, Node* left, Node* right,
208 : wasm::WasmCodePosition position = wasm::kNoCodePosition);
209 : Node* Unop(wasm::WasmOpcode opcode, Node* input,
210 : wasm::WasmCodePosition position = wasm::kNoCodePosition);
211 : Node* GrowMemory(Node* input);
212 : Node* Throw(uint32_t tag, const wasm::WasmException* exception,
213 : const Vector<Node*> values);
214 : Node* Rethrow();
215 : Node* ConvertExceptionTagToRuntimeId(uint32_t tag);
216 : Node* GetExceptionRuntimeId();
217 : Node** GetExceptionValues(const wasm::WasmException* except_decl);
218 : unsigned InputCount(Node* node);
219 : bool IsPhiWithMerge(Node* phi, Node* merge);
220 : bool ThrowsException(Node* node, Node** if_success, Node** if_exception);
221 : void AppendToMerge(Node* merge, Node* from);
222 : void AppendToPhi(Node* phi, Node* from);
223 :
224 : void StackCheck(wasm::WasmCodePosition position, Node** effect = nullptr,
225 : Node** control = nullptr);
226 :
227 : void PatchInStackCheckIfNeeded();
228 :
229 : //-----------------------------------------------------------------------
230 : // Operations that read and/or write {control} and {effect}.
231 : //-----------------------------------------------------------------------
232 : Node* BranchNoHint(Node* cond, Node** true_node, Node** false_node);
233 : Node* BranchExpectTrue(Node* cond, Node** true_node, Node** false_node);
234 : Node* BranchExpectFalse(Node* cond, Node** true_node, Node** false_node);
235 :
236 : Node* TrapIfTrue(wasm::TrapReason reason, Node* cond,
237 : wasm::WasmCodePosition position);
238 : Node* TrapIfFalse(wasm::TrapReason reason, Node* cond,
239 : wasm::WasmCodePosition position);
240 : Node* TrapIfEq32(wasm::TrapReason reason, Node* node, int32_t val,
241 : wasm::WasmCodePosition position);
242 : Node* ZeroCheck32(wasm::TrapReason reason, Node* node,
243 : wasm::WasmCodePosition position);
244 : Node* TrapIfEq64(wasm::TrapReason reason, Node* node, int64_t val,
245 : wasm::WasmCodePosition position);
246 : Node* ZeroCheck64(wasm::TrapReason reason, Node* node,
247 : wasm::WasmCodePosition position);
248 :
249 : Node* Switch(unsigned count, Node* key);
250 : Node* IfValue(int32_t value, Node* sw);
251 : Node* IfDefault(Node* sw);
252 : Node* Return(unsigned count, Node** nodes);
253 : template <typename... Nodes>
254 : Node* Return(Node* fst, Nodes*... more) {
255 174839 : Node* arr[] = {fst, more...};
256 174839 : return Return(arraysize(arr), arr);
257 : }
258 : Node* ReturnVoid();
259 : Node* Unreachable(wasm::WasmCodePosition position);
260 :
261 : Node* CallDirect(uint32_t index, Node** args, Node*** rets,
262 : wasm::WasmCodePosition position);
263 : Node* CallIndirect(uint32_t index, Node** args, Node*** rets,
264 : wasm::WasmCodePosition position);
265 :
266 : void BuildJSToWasmWrapper(Handle<Code> wasm_code,
267 : Address wasm_context_address);
268 : enum ImportDataType {
269 : kFunction = 1,
270 : kGlobalProxy = 2,
271 : kFunctionContext = 3,
272 : };
273 : Node* LoadImportDataAtOffset(int offset, Node* table);
274 : Node* LoadNativeContext(Node* table);
275 : Node* LoadImportData(int index, ImportDataType type, Node* table);
276 : bool BuildWasmToJSWrapper(Handle<JSReceiver> target,
277 : Handle<FixedArray> global_js_imports_table,
278 : int index);
279 : void BuildWasmToWasmWrapper(Handle<Code> target,
280 : Address new_wasm_context_address);
281 : void BuildWasmInterpreterEntry(uint32_t func_index,
282 : Handle<WasmInstanceObject> instance);
283 : void BuildCWasmEntry(Address wasm_context_address);
284 :
285 : Node* ToJS(Node* node, wasm::ValueType type);
286 : Node* FromJS(Node* node, Node* js_context, wasm::ValueType type);
287 : Node* Invert(Node* node);
288 : void EnsureFunctionTableNodes();
289 :
290 : //-----------------------------------------------------------------------
291 : // Operations that concern the linear memory.
292 : //-----------------------------------------------------------------------
293 : Node* CurrentMemoryPages();
294 : Node* GetGlobal(uint32_t index);
295 : Node* SetGlobal(uint32_t index, Node* val);
296 : Node* TraceMemoryOperation(bool is_store, MachineRepresentation, Node* index,
297 : uint32_t offset, wasm::WasmCodePosition);
298 : Node* LoadMem(wasm::ValueType type, MachineType memtype, Node* index,
299 : uint32_t offset, uint32_t alignment,
300 : wasm::WasmCodePosition position);
301 : Node* StoreMem(MachineType memtype, Node* index, uint32_t offset,
302 : uint32_t alignment, Node* val, wasm::WasmCodePosition position,
303 : wasm::ValueType type);
304 : static void PrintDebugName(Node* node);
305 :
306 : void set_wasm_context(Node* wasm_context) {
307 234405 : this->wasm_context_ = wasm_context;
308 : }
309 :
310 198459 : Node* Control() { return *control_; }
311 198459 : Node* Effect() { return *effect_; }
312 :
313 1959600 : void set_control_ptr(Node** control) { this->control_ = control; }
314 :
315 1959600 : void set_effect_ptr(Node** effect) { this->effect_ = effect; }
316 :
317 : Node* LoadMemSize();
318 : Node* LoadMemStart();
319 : void GetGlobalBaseAndOffset(MachineType mem_type, uint32_t offset,
320 : Node** base_node, Node** offset_node);
321 :
322 1414418 : void set_mem_size(Node** mem_size) { this->mem_size_ = mem_size; }
323 :
324 1414418 : void set_mem_start(Node** mem_start) { this->mem_start_ = mem_start; }
325 :
326 : wasm::FunctionSig* GetFunctionSignature() { return sig_; }
327 :
328 : void LowerInt64();
329 :
330 : void SimdScalarLoweringForTesting();
331 :
332 : void SetSourcePosition(Node* node, wasm::WasmCodePosition position);
333 :
334 : Node* S128Zero();
335 : Node* S1x4Zero();
336 : Node* S1x8Zero();
337 : Node* S1x16Zero();
338 :
339 : Node* SimdOp(wasm::WasmOpcode opcode, Node* const* inputs);
340 :
341 : Node* SimdLaneOp(wasm::WasmOpcode opcode, uint8_t lane, Node* const* inputs);
342 :
343 : Node* SimdShiftOp(wasm::WasmOpcode opcode, uint8_t shift,
344 : Node* const* inputs);
345 :
346 : Node* Simd8x16ShuffleOp(const uint8_t shuffle[16], Node* const* inputs);
347 :
348 : Node* AtomicOp(wasm::WasmOpcode opcode, Node* const* inputs,
349 : uint32_t alignment, uint32_t offset,
350 : wasm::WasmCodePosition position);
351 :
352 : bool has_simd() const { return has_simd_; }
353 :
354 234351 : const wasm::WasmModule* module() { return env_ ? env_->module : nullptr; }
355 :
356 : private:
357 : static const int kDefaultBufferSize = 16;
358 :
359 : Zone* zone_;
360 : JSGraph* jsgraph_;
361 : Node* centry_stub_node_;
362 : ModuleEnv* env_ = nullptr;
363 : Node* wasm_context_ = nullptr;
364 : NodeVector signature_tables_;
365 : NodeVector function_tables_;
366 : NodeVector function_table_sizes_;
367 : Node** control_ = nullptr;
368 : Node** effect_ = nullptr;
369 : Node** mem_size_ = nullptr;
370 : Node** mem_start_ = nullptr;
371 : Node* globals_start_ = nullptr;
372 : Node** cur_buffer_;
373 : size_t cur_bufsize_;
374 : Node* def_buffer_[kDefaultBufferSize];
375 : bool has_simd_ = false;
376 : bool needs_stack_check_ = false;
377 : // If the runtime doesn't support exception propagation,
378 : // we won't generate stack checks, and trap handling will also
379 : // be generated differently.
380 : RuntimeExceptionSupport runtime_exception_support_;
381 :
382 : wasm::FunctionSig* sig_;
383 : SetOncePointer<const Operator> allocate_heap_number_operator_;
384 :
385 : compiler::SourcePositionTable* source_position_table_ = nullptr;
386 :
387 : // Internal helper methods.
388 : JSGraph* jsgraph() { return jsgraph_; }
389 : Graph* graph();
390 :
391 : Node* String(const char* string);
392 : Node* MemBuffer(uint32_t offset);
393 : void BoundsCheckMem(MachineType memtype, Node* index, uint32_t offset,
394 : wasm::WasmCodePosition position);
395 : const Operator* GetSafeLoadOperator(int offset, wasm::ValueType type);
396 : const Operator* GetSafeStoreOperator(int offset, wasm::ValueType type);
397 : Node* BuildChangeEndiannessStore(Node* node, MachineType type,
398 : wasm::ValueType wasmtype = wasm::kWasmStmt);
399 : Node* BuildChangeEndiannessLoad(Node* node, MachineType type,
400 : wasm::ValueType wasmtype = wasm::kWasmStmt);
401 :
402 : Node* MaskShiftCount32(Node* node);
403 : Node* MaskShiftCount64(Node* node);
404 :
405 : template <typename... Args>
406 162 : Node* BuildCCall(MachineSignature* sig, Node* function, Args... args);
407 : Node* BuildWasmCall(wasm::FunctionSig* sig, Node** args, Node*** rets,
408 : wasm::WasmCodePosition position);
409 :
410 : Node* BuildF32CopySign(Node* left, Node* right);
411 : Node* BuildF64CopySign(Node* left, Node* right);
412 : Node* BuildI32SConvertF32(Node* input, wasm::WasmCodePosition position);
413 : Node* BuildI32SConvertF64(Node* input, wasm::WasmCodePosition position);
414 : Node* BuildI32UConvertF32(Node* input, wasm::WasmCodePosition position);
415 : Node* BuildI32UConvertF64(Node* input, wasm::WasmCodePosition position);
416 : Node* BuildI32Ctz(Node* input);
417 : Node* BuildI32Popcnt(Node* input);
418 : Node* BuildI64Ctz(Node* input);
419 : Node* BuildI64Popcnt(Node* input);
420 : Node* BuildBitCountingCall(Node* input, ExternalReference ref,
421 : MachineRepresentation input_type);
422 :
423 : Node* BuildCFuncInstruction(ExternalReference ref, MachineType type,
424 : Node* input0, Node* input1 = nullptr);
425 : Node* BuildF32Trunc(Node* input);
426 : Node* BuildF32Floor(Node* input);
427 : Node* BuildF32Ceil(Node* input);
428 : Node* BuildF32NearestInt(Node* input);
429 : Node* BuildF64Trunc(Node* input);
430 : Node* BuildF64Floor(Node* input);
431 : Node* BuildF64Ceil(Node* input);
432 : Node* BuildF64NearestInt(Node* input);
433 : Node* BuildI32Rol(Node* left, Node* right);
434 : Node* BuildI64Rol(Node* left, Node* right);
435 :
436 : Node* BuildF64Acos(Node* input);
437 : Node* BuildF64Asin(Node* input);
438 : Node* BuildF64Pow(Node* left, Node* right);
439 : Node* BuildF64Mod(Node* left, Node* right);
440 :
441 : Node* BuildIntToFloatConversionInstruction(
442 : Node* input, ExternalReference ref,
443 : MachineRepresentation parameter_representation,
444 : const MachineType result_type);
445 : Node* BuildF32SConvertI64(Node* input);
446 : Node* BuildF32UConvertI64(Node* input);
447 : Node* BuildF64SConvertI64(Node* input);
448 : Node* BuildF64UConvertI64(Node* input);
449 :
450 : Node* BuildFloatToIntConversionInstruction(
451 : Node* input, ExternalReference ref,
452 : MachineRepresentation parameter_representation,
453 : const MachineType result_type, wasm::WasmCodePosition position);
454 : Node* BuildI64SConvertF32(Node* input, wasm::WasmCodePosition position);
455 : Node* BuildI64UConvertF32(Node* input, wasm::WasmCodePosition position);
456 : Node* BuildI64SConvertF64(Node* input, wasm::WasmCodePosition position);
457 : Node* BuildI64UConvertF64(Node* input, wasm::WasmCodePosition position);
458 :
459 : Node* BuildI32DivS(Node* left, Node* right, wasm::WasmCodePosition position);
460 : Node* BuildI32RemS(Node* left, Node* right, wasm::WasmCodePosition position);
461 : Node* BuildI32DivU(Node* left, Node* right, wasm::WasmCodePosition position);
462 : Node* BuildI32RemU(Node* left, Node* right, wasm::WasmCodePosition position);
463 :
464 : Node* BuildI64DivS(Node* left, Node* right, wasm::WasmCodePosition position);
465 : Node* BuildI64RemS(Node* left, Node* right, wasm::WasmCodePosition position);
466 : Node* BuildI64DivU(Node* left, Node* right, wasm::WasmCodePosition position);
467 : Node* BuildI64RemU(Node* left, Node* right, wasm::WasmCodePosition position);
468 : Node* BuildDiv64Call(Node* left, Node* right, ExternalReference ref,
469 : MachineType result_type, int trap_zero,
470 : wasm::WasmCodePosition position);
471 :
472 : Node* BuildJavaScriptToNumber(Node* node, Node* js_context);
473 :
474 : Node* BuildChangeInt32ToTagged(Node* value);
475 : Node* BuildChangeFloat64ToTagged(Node* value);
476 : Node* BuildChangeTaggedToFloat64(Node* value);
477 :
478 : Node* BuildChangeInt32ToSmi(Node* value);
479 : Node* BuildChangeSmiToInt32(Node* value);
480 : Node* BuildChangeUint32ToSmi(Node* value);
481 : Node* BuildChangeSmiToFloat64(Node* value);
482 : Node* BuildTestNotSmi(Node* value);
483 : Node* BuildSmiShiftBitsConstant();
484 :
485 : Node* BuildAllocateHeapNumberWithValue(Node* value, Node* control);
486 : Node* BuildLoadHeapNumberValue(Node* value, Node* control);
487 : Node* BuildHeapNumberValueIndexConstant();
488 :
489 : // Asm.js specific functionality.
490 : Node* BuildI32AsmjsSConvertF32(Node* input);
491 : Node* BuildI32AsmjsSConvertF64(Node* input);
492 : Node* BuildI32AsmjsUConvertF32(Node* input);
493 : Node* BuildI32AsmjsUConvertF64(Node* input);
494 : Node* BuildI32AsmjsDivS(Node* left, Node* right);
495 : Node* BuildI32AsmjsRemS(Node* left, Node* right);
496 : Node* BuildI32AsmjsDivU(Node* left, Node* right);
497 : Node* BuildI32AsmjsRemU(Node* left, Node* right);
498 : Node* BuildAsmjsLoadMem(MachineType type, Node* index);
499 : Node* BuildAsmjsStoreMem(MachineType type, Node* index, Node* val);
500 :
501 : uint32_t GetExceptionEncodedSize(const wasm::WasmException* exception) const;
502 : void BuildEncodeException32BitValue(uint32_t* index, Node* value);
503 : Node* BuildDecodeException32BitValue(Node* const* values, uint32_t* index);
504 :
505 407203 : Node** Realloc(Node* const* buffer, size_t old_count, size_t new_count) {
506 407203 : Node** buf = Buffer(new_count);
507 407219 : if (buf != buffer) memcpy(buf, buffer, old_count * sizeof(Node*));
508 407219 : return buf;
509 : }
510 :
511 : int AddParameterNodes(Node** args, int pos, int param_count,
512 : wasm::FunctionSig* sig);
513 :
514 177199 : void SetNeedsStackCheck() { needs_stack_check_ = true; }
515 :
516 : //-----------------------------------------------------------------------
517 : // Operations involving the CEntryStub, a dependency we want to remove
518 : // to get off the GC heap.
519 : //-----------------------------------------------------------------------
520 : Node* BuildCallToRuntime(Runtime::FunctionId f, Node** parameters,
521 : int parameter_count);
522 :
523 : Node* BuildCallToRuntimeWithContext(Runtime::FunctionId f, Node* js_context,
524 : Node** parameters, int parameter_count);
525 : Node* BuildCallToRuntimeWithContextFromJS(Runtime::FunctionId f,
526 : Node* js_context,
527 : Node* const* parameters,
528 : int parameter_count);
529 : Node* BuildModifyThreadInWasmFlag(bool new_value);
530 : Builtins::Name GetBuiltinIdForTrap(wasm::TrapReason reason);
531 : };
532 :
533 : // The parameter index where the wasm_context paramter should be placed in wasm
534 : // call descriptors. This is used by the Int64Lowering::LowerNode method.
535 : constexpr int kWasmContextParameterIndex = 0;
536 :
537 : V8_EXPORT_PRIVATE CallDescriptor* GetWasmCallDescriptor(
538 : Zone* zone, wasm::FunctionSig* sig, bool supports_tails_calls = false);
539 : V8_EXPORT_PRIVATE CallDescriptor* GetI32WasmCallDescriptor(
540 : Zone* zone, CallDescriptor* descriptor);
541 : V8_EXPORT_PRIVATE CallDescriptor* GetI32WasmCallDescriptorForSimd(
542 : Zone* zone, CallDescriptor* descriptor);
543 :
544 : } // namespace compiler
545 : } // namespace internal
546 : } // namespace v8
547 :
548 : #endif // V8_COMPILER_WASM_COMPILER_H_
|