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/runtime/runtime.h"
13 : #include "src/wasm/function-body-decoder.h"
14 : #include "src/wasm/function-compiler.h"
15 : #include "src/wasm/wasm-module.h"
16 : #include "src/wasm/wasm-opcodes.h"
17 : #include "src/wasm/wasm-result.h"
18 : #include "src/zone/zone.h"
19 :
20 : namespace v8 {
21 : namespace internal {
22 : struct AssemblerOptions;
23 :
24 : namespace compiler {
25 : // Forward declarations for some compiler data structures.
26 : class CallDescriptor;
27 : class Graph;
28 : class MachineGraph;
29 : class Node;
30 : class NodeOriginTable;
31 : class Operator;
32 : class SourcePositionTable;
33 : class WasmDecorator;
34 : enum class TrapId : uint32_t;
35 : } // namespace compiler
36 :
37 : namespace wasm {
38 : struct DecodeStruct;
39 : // Expose {Node} and {Graph} opaquely as {wasm::TFNode} and {wasm::TFGraph}.
40 : typedef compiler::Node TFNode;
41 : typedef compiler::MachineGraph TFGraph;
42 : class WasmCode;
43 : struct WasmFeatures;
44 : } // namespace wasm
45 :
46 : namespace compiler {
47 :
48 504200 : class TurbofanWasmCompilationUnit {
49 : public:
50 : explicit TurbofanWasmCompilationUnit(wasm::WasmCompilationUnit* wasm_unit);
51 : ~TurbofanWasmCompilationUnit();
52 :
53 : bool BuildGraphForWasmFunction(wasm::CompilationEnv* env,
54 : const wasm::FunctionBody& func_body,
55 : wasm::WasmFeatures* detected,
56 : double* decode_ms, MachineGraph* mcgraph,
57 : NodeOriginTable* node_origins,
58 : SourcePositionTable* source_positions,
59 : wasm::WasmError* error_out);
60 :
61 : wasm::WasmCompilationResult ExecuteCompilation(wasm::CompilationEnv*,
62 : const wasm::FunctionBody&,
63 : Counters*,
64 : wasm::WasmFeatures* detected);
65 :
66 : private:
67 : wasm::WasmCompilationUnit* const wasm_unit_;
68 :
69 : DISALLOW_COPY_AND_ASSIGN(TurbofanWasmCompilationUnit);
70 : };
71 :
72 : // Calls to WASM imports are handled in several different ways, depending
73 : // on the type of the target function/callable and whether the signature
74 : // matches the argument arity.
75 : enum class WasmImportCallKind : uint8_t {
76 : kLinkError, // static WASM->WASM type error
77 : kRuntimeTypeError, // runtime WASM->JS type error
78 : kWasmToWasm, // fast WASM->WASM call
79 : kJSFunctionArityMatch, // fast WASM->JS call
80 : kJSFunctionArityMatchSloppy, // fast WASM->JS call, sloppy receiver
81 : kJSFunctionArityMismatch, // WASM->JS, needs adapter frame
82 : kJSFunctionArityMismatchSloppy, // WASM->JS, needs adapter frame, sloppy
83 : // Math functions imported from JavaScript that are intrinsified
84 : kFirstMathIntrinsic,
85 : kF64Acos = kFirstMathIntrinsic,
86 : kF64Asin,
87 : kF64Atan,
88 : kF64Cos,
89 : kF64Sin,
90 : kF64Tan,
91 : kF64Exp,
92 : kF64Log,
93 : kF64Atan2,
94 : kF64Pow,
95 : kF64Ceil,
96 : kF64Floor,
97 : kF64Sqrt,
98 : kF64Min,
99 : kF64Max,
100 : kF64Abs,
101 : kF32Min,
102 : kF32Max,
103 : kF32Abs,
104 : kF32Ceil,
105 : kF32Floor,
106 : kF32Sqrt,
107 : kF32ConvertF64,
108 : kLastMathIntrinsic = kF32ConvertF64,
109 : // For everything else, there's the call builtin.
110 : kUseCallBuiltin
111 : };
112 :
113 : WasmImportCallKind GetWasmImportCallKind(Handle<JSReceiver> callable,
114 : wasm::FunctionSig* sig,
115 : bool has_bigint_feature);
116 :
117 : // Compiles an import call wrapper, which allows WASM to call imports.
118 : wasm::WasmCode* CompileWasmImportCallWrapper(wasm::WasmEngine*,
119 : wasm::NativeModule*,
120 : WasmImportCallKind,
121 : wasm::FunctionSig*,
122 : bool source_positions);
123 :
124 : // Creates a code object calling a wasm function with the given signature,
125 : // callable from JS.
126 : V8_EXPORT_PRIVATE MaybeHandle<Code> CompileJSToWasmWrapper(Isolate*,
127 : wasm::FunctionSig*,
128 : bool is_import);
129 :
130 : // Compiles a stub that redirects a call to a wasm function to the wasm
131 : // interpreter. It's ABI compatible with the compiled wasm function.
132 : wasm::WasmCode* CompileWasmInterpreterEntry(wasm::WasmEngine*,
133 : wasm::NativeModule*,
134 : uint32_t func_index,
135 : wasm::FunctionSig*);
136 :
137 : enum CWasmEntryParameters {
138 : kCodeEntry,
139 : kObjectRef,
140 : kArgumentsBuffer,
141 : // marker:
142 : kNumParameters
143 : };
144 :
145 : // Compiles a stub with JS linkage, taking parameters as described by
146 : // {CWasmEntryParameters}. It loads the wasm parameters from the argument
147 : // buffer and calls the wasm function given as first parameter.
148 : MaybeHandle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig);
149 :
150 : // Values from the instance object are cached between WASM-level function calls.
151 : // This struct allows the SSA environment handling this cache to be defined
152 : // and manipulated in wasm-compiler.{h,cc} instead of inside the WASM decoder.
153 : // (Note that currently, the globals base is immutable, so not cached here.)
154 : struct WasmInstanceCacheNodes {
155 : Node* mem_start;
156 : Node* mem_size;
157 : Node* mem_mask;
158 : };
159 :
160 : // Abstracts details of building TurboFan graph nodes for wasm to separate
161 : // the wasm decoder from the internal details of TurboFan.
162 : class WasmGraphBuilder {
163 : public:
164 : enum EnforceBoundsCheck : bool { // --
165 : kNeedsBoundsCheck = true,
166 : kCanOmitBoundsCheck = false
167 : };
168 : enum UseRetpoline : bool { // --
169 : kRetpoline = true,
170 : kNoRetpoline = false
171 : };
172 : enum ExtraCallableParam : bool { // --
173 : kExtraCallableParam = true,
174 : kNoExtraCallableParam = false
175 : };
176 :
177 : WasmGraphBuilder(wasm::CompilationEnv* env, Zone* zone, MachineGraph* mcgraph,
178 : wasm::FunctionSig* sig,
179 : compiler::SourcePositionTable* spt = nullptr);
180 :
181 1126407 : Node** Buffer(size_t count) {
182 1126407 : if (count > cur_bufsize_) {
183 3660 : size_t new_size = count + cur_bufsize_ + 5;
184 : cur_buffer_ =
185 3660 : reinterpret_cast<Node**>(zone_->New(new_size * sizeof(Node*)));
186 3660 : cur_bufsize_ = new_size;
187 : }
188 1126407 : return cur_buffer_;
189 : }
190 :
191 : //-----------------------------------------------------------------------
192 : // Operations independent of {control} or {effect}.
193 : //-----------------------------------------------------------------------
194 : Node* Error();
195 : Node* Start(unsigned params);
196 : Node* Param(unsigned index);
197 : Node* Loop(Node* entry);
198 : Node* TerminateLoop(Node* effect, Node* control);
199 : Node* TerminateThrow(Node* effect, Node* control);
200 : Node* Merge(unsigned count, Node** controls);
201 : Node* Phi(wasm::ValueType type, unsigned count, Node** vals, Node* control);
202 : Node* CreateOrMergeIntoPhi(MachineRepresentation rep, Node* merge,
203 : Node* tnode, Node* fnode);
204 : Node* CreateOrMergeIntoEffectPhi(Node* merge, Node* tnode, Node* fnode);
205 : Node* EffectPhi(unsigned count, Node** effects, Node* control);
206 : Node* RefNull();
207 : Node* Uint32Constant(uint32_t value);
208 : Node* Int32Constant(int32_t value);
209 : Node* Int64Constant(int64_t value);
210 : Node* IntPtrConstant(intptr_t value);
211 : Node* Float32Constant(float value);
212 : Node* Float64Constant(double value);
213 : Node* Binop(wasm::WasmOpcode opcode, Node* left, Node* right,
214 : wasm::WasmCodePosition position = wasm::kNoCodePosition);
215 : Node* Unop(wasm::WasmOpcode opcode, Node* input,
216 : wasm::WasmCodePosition position = wasm::kNoCodePosition);
217 : Node* MemoryGrow(Node* input);
218 : Node* Throw(uint32_t exception_index, const wasm::WasmException* exception,
219 : const Vector<Node*> values);
220 : Node* Rethrow(Node* except_obj);
221 : Node* ExceptionTagEqual(Node* caught_tag, Node* expected_tag);
222 : Node* LoadExceptionTagFromTable(uint32_t exception_index);
223 : Node* GetExceptionTag(Node* except_obj);
224 : Node** GetExceptionValues(Node* except_obj,
225 : const wasm::WasmException* exception);
226 : bool IsPhiWithMerge(Node* phi, Node* merge);
227 : bool ThrowsException(Node* node, Node** if_success, Node** if_exception);
228 : void AppendToMerge(Node* merge, Node* from);
229 : void AppendToPhi(Node* phi, Node* from);
230 :
231 : void StackCheck(wasm::WasmCodePosition position, Node** effect = nullptr,
232 : Node** control = nullptr);
233 :
234 : void PatchInStackCheckIfNeeded();
235 :
236 : //-----------------------------------------------------------------------
237 : // Operations that read and/or write {control} and {effect}.
238 : //-----------------------------------------------------------------------
239 : Node* BranchNoHint(Node* cond, Node** true_node, Node** false_node);
240 : Node* BranchExpectTrue(Node* cond, Node** true_node, Node** false_node);
241 : Node* BranchExpectFalse(Node* cond, Node** true_node, Node** false_node);
242 :
243 : Node* TrapIfTrue(wasm::TrapReason reason, Node* cond,
244 : wasm::WasmCodePosition position);
245 : Node* TrapIfFalse(wasm::TrapReason reason, Node* cond,
246 : wasm::WasmCodePosition position);
247 : Node* TrapIfEq32(wasm::TrapReason reason, Node* node, int32_t val,
248 : wasm::WasmCodePosition position);
249 : Node* ZeroCheck32(wasm::TrapReason reason, Node* node,
250 : wasm::WasmCodePosition position);
251 : Node* TrapIfEq64(wasm::TrapReason reason, Node* node, int64_t val,
252 : wasm::WasmCodePosition position);
253 : Node* ZeroCheck64(wasm::TrapReason reason, Node* node,
254 : wasm::WasmCodePosition position);
255 :
256 : Node* Switch(unsigned count, Node* key);
257 : Node* IfValue(int32_t value, Node* sw);
258 : Node* IfDefault(Node* sw);
259 : Node* Return(unsigned count, Node** nodes);
260 : template <typename... Nodes>
261 : Node* Return(Node* fst, Nodes*... more) {
262 149397 : Node* arr[] = {fst, more...};
263 149397 : return Return(arraysize(arr), arr);
264 : }
265 : Node* ReturnVoid();
266 : Node* Unreachable(wasm::WasmCodePosition position);
267 :
268 : Node* CallDirect(uint32_t index, Node** args, Node*** rets,
269 : wasm::WasmCodePosition position);
270 : Node* CallIndirect(uint32_t index, Node** args, Node*** rets,
271 : wasm::WasmCodePosition position);
272 :
273 : Node* Invert(Node* node);
274 :
275 : Node* GetGlobal(uint32_t index);
276 : Node* SetGlobal(uint32_t index, Node* val);
277 : Node* GetTable(uint32_t table_index, Node* index,
278 : wasm::WasmCodePosition position);
279 : Node* SetTable(uint32_t table_index, Node* index, Node* val,
280 : wasm::WasmCodePosition position);
281 : //-----------------------------------------------------------------------
282 : // Operations that concern the linear memory.
283 : //-----------------------------------------------------------------------
284 : Node* CurrentMemoryPages();
285 : Node* TraceMemoryOperation(bool is_store, MachineRepresentation, Node* index,
286 : uint32_t offset, wasm::WasmCodePosition);
287 : Node* LoadMem(wasm::ValueType type, MachineType memtype, Node* index,
288 : uint32_t offset, uint32_t alignment,
289 : wasm::WasmCodePosition position);
290 : Node* StoreMem(MachineRepresentation mem_rep, Node* index, uint32_t offset,
291 : uint32_t alignment, Node* val, wasm::WasmCodePosition position,
292 : wasm::ValueType type);
293 : static void PrintDebugName(Node* node);
294 :
295 : void set_instance_node(Node* instance_node) {
296 : this->instance_node_ = instance_node;
297 : }
298 :
299 : Node* Control() {
300 : DCHECK_NOT_NULL(*control_);
301 4599618 : return *control_;
302 : }
303 : Node* Effect() {
304 : DCHECK_NOT_NULL(*effect_);
305 4687132 : return *effect_;
306 : }
307 : Node* SetControl(Node* node) {
308 663636 : *control_ = node;
309 : return node;
310 : }
311 : Node* SetEffect(Node* node) {
312 3892989 : *effect_ = node;
313 : return node;
314 : }
315 :
316 1731823 : void set_control_ptr(Node** control) { this->control_ = control; }
317 :
318 1731823 : void set_effect_ptr(Node** effect) { this->effect_ = effect; }
319 :
320 : Node* GetImportedMutableGlobals();
321 :
322 : void GetGlobalBaseAndOffset(MachineType mem_type, const wasm::WasmGlobal&,
323 : Node** base_node, Node** offset_node);
324 :
325 : void GetBaseAndOffsetForImportedMutableAnyRefGlobal(
326 : const wasm::WasmGlobal& global, Node** base, Node** offset);
327 :
328 : void GetTableBaseAndOffset(uint32_t table_index, Node* index,
329 : wasm::WasmCodePosition position, Node** base_node,
330 : Node** offset_node);
331 :
332 : // Utilities to manipulate sets of instance cache nodes.
333 : void InitInstanceCache(WasmInstanceCacheNodes* instance_cache);
334 : void PrepareInstanceCacheForLoop(WasmInstanceCacheNodes* instance_cache,
335 : Node* control);
336 : void NewInstanceCacheMerge(WasmInstanceCacheNodes* to,
337 : WasmInstanceCacheNodes* from, Node* merge);
338 : void MergeInstanceCacheInto(WasmInstanceCacheNodes* to,
339 : WasmInstanceCacheNodes* from, Node* merge);
340 :
341 : void set_instance_cache(WasmInstanceCacheNodes* instance_cache) {
342 1078698 : this->instance_cache_ = instance_cache;
343 : }
344 :
345 : wasm::FunctionSig* GetFunctionSignature() { return sig_; }
346 :
347 : void LowerInt64();
348 :
349 : void SimdScalarLoweringForTesting();
350 :
351 : void SetSourcePosition(Node* node, wasm::WasmCodePosition position);
352 :
353 : Node* S128Zero();
354 : Node* S1x4Zero();
355 : Node* S1x8Zero();
356 : Node* S1x16Zero();
357 :
358 : Node* SimdOp(wasm::WasmOpcode opcode, Node* const* inputs);
359 :
360 : Node* SimdLaneOp(wasm::WasmOpcode opcode, uint8_t lane, Node* const* inputs);
361 :
362 : Node* SimdShiftOp(wasm::WasmOpcode opcode, uint8_t shift,
363 : Node* const* inputs);
364 :
365 : Node* Simd8x16ShuffleOp(const uint8_t shuffle[16], Node* const* inputs);
366 :
367 : Node* AtomicOp(wasm::WasmOpcode opcode, Node* const* inputs,
368 : uint32_t alignment, uint32_t offset,
369 : wasm::WasmCodePosition position);
370 :
371 : // Returns a pointer to the dropped_data_segments array. Traps if the data
372 : // segment is active or has been dropped.
373 : Node* CheckDataSegmentIsPassiveAndNotDropped(uint32_t data_segment_index,
374 : wasm::WasmCodePosition position);
375 : Node* CheckElemSegmentIsPassiveAndNotDropped(uint32_t elem_segment_index,
376 : wasm::WasmCodePosition position);
377 : Node* MemoryInit(uint32_t data_segment_index, Node* dst, Node* src,
378 : Node* size, wasm::WasmCodePosition position);
379 : Node* MemoryCopy(Node* dst, Node* src, Node* size,
380 : wasm::WasmCodePosition position);
381 : Node* DataDrop(uint32_t data_segment_index, wasm::WasmCodePosition position);
382 : Node* MemoryFill(Node* dst, Node* fill, Node* size,
383 : wasm::WasmCodePosition position);
384 :
385 : Node* TableInit(uint32_t table_index, uint32_t elem_segment_index, Node* dst,
386 : Node* src, Node* size, wasm::WasmCodePosition position);
387 : Node* ElemDrop(uint32_t elem_segment_index, wasm::WasmCodePosition position);
388 : Node* TableCopy(uint32_t table_src_index, uint32_t table_dst_index, Node* dst,
389 : Node* src, Node* size, wasm::WasmCodePosition position);
390 :
391 : bool has_simd() const { return has_simd_; }
392 :
393 : const wasm::WasmModule* module() { return env_ ? env_->module : nullptr; }
394 :
395 : wasm::UseTrapHandler use_trap_handler() const {
396 509449 : return env_ ? env_->use_trap_handler : wasm::kNoTrapHandler;
397 : }
398 :
399 : MachineGraph* mcgraph() { return mcgraph_; }
400 : Graph* graph();
401 :
402 : void AddBytecodePositionDecorator(NodeOriginTable* node_origins,
403 : wasm::Decoder* decoder);
404 :
405 : void RemoveBytecodePositionDecorator();
406 :
407 : protected:
408 : static const int kDefaultBufferSize = 16;
409 :
410 : Zone* const zone_;
411 : MachineGraph* const mcgraph_;
412 : wasm::CompilationEnv* const env_;
413 :
414 : Node** control_ = nullptr;
415 : Node** effect_ = nullptr;
416 : WasmInstanceCacheNodes* instance_cache_ = nullptr;
417 :
418 : SetOncePointer<Node> instance_node_;
419 : SetOncePointer<Node> globals_start_;
420 : SetOncePointer<Node> imported_mutable_globals_;
421 : SetOncePointer<Node> stack_check_code_node_;
422 : SetOncePointer<const Operator> stack_check_call_operator_;
423 :
424 : Node** cur_buffer_;
425 : size_t cur_bufsize_;
426 : Node* def_buffer_[kDefaultBufferSize];
427 : bool has_simd_ = false;
428 : bool needs_stack_check_ = false;
429 : const bool untrusted_code_mitigations_ = true;
430 :
431 : wasm::FunctionSig* const sig_;
432 :
433 : compiler::WasmDecorator* decorator_ = nullptr;
434 :
435 : compiler::SourcePositionTable* const source_position_table_ = nullptr;
436 :
437 : Node* NoContextConstant();
438 :
439 : Node* MemBuffer(uint32_t offset);
440 : // BoundsCheckMem receives a uint32 {index} node and returns a ptrsize index.
441 : Node* BoundsCheckMem(uint8_t access_size, Node* index, uint32_t offset,
442 : wasm::WasmCodePosition, EnforceBoundsCheck);
443 : // Check that the range [start, start + size) is in the range [0, max).
444 : void BoundsCheckRange(Node* start, Node* size, Node* max,
445 : wasm::WasmCodePosition);
446 : // BoundsCheckMemRange receives a uint32 {start} and {size} and returns
447 : // a pointer into memory at that index, if it is in bounds.
448 : Node* BoundsCheckMemRange(Node* start, Node* size, wasm::WasmCodePosition);
449 : Node* CheckBoundsAndAlignment(uint8_t access_size, Node* index,
450 : uint32_t offset, wasm::WasmCodePosition);
451 :
452 : Node* Uint32ToUintptr(Node*);
453 : const Operator* GetSafeLoadOperator(int offset, wasm::ValueType type);
454 : const Operator* GetSafeStoreOperator(int offset, wasm::ValueType type);
455 : Node* BuildChangeEndiannessStore(Node* node, MachineRepresentation rep,
456 : wasm::ValueType wasmtype = wasm::kWasmStmt);
457 : Node* BuildChangeEndiannessLoad(Node* node, MachineType type,
458 : wasm::ValueType wasmtype = wasm::kWasmStmt);
459 :
460 : Node* MaskShiftCount32(Node* node);
461 : Node* MaskShiftCount64(Node* node);
462 :
463 : template <typename... Args>
464 355 : Node* BuildCCall(MachineSignature* sig, Node* function, Args... args);
465 : Node* BuildWasmCall(wasm::FunctionSig* sig, Node** args, Node*** rets,
466 : wasm::WasmCodePosition position, Node* instance_node,
467 : UseRetpoline use_retpoline);
468 : Node* BuildImportCall(wasm::FunctionSig* sig, Node** args, Node*** rets,
469 : wasm::WasmCodePosition position, int func_index);
470 : Node* BuildImportCall(wasm::FunctionSig* sig, Node** args, Node*** rets,
471 : wasm::WasmCodePosition position, Node* func_index);
472 :
473 : Node* BuildF32CopySign(Node* left, Node* right);
474 : Node* BuildF64CopySign(Node* left, Node* right);
475 :
476 : Node* BuildIntConvertFloat(Node* input, wasm::WasmCodePosition position,
477 : wasm::WasmOpcode);
478 : Node* BuildI32Ctz(Node* input);
479 : Node* BuildI32Popcnt(Node* input);
480 : Node* BuildI64Ctz(Node* input);
481 : Node* BuildI64Popcnt(Node* input);
482 : Node* BuildBitCountingCall(Node* input, ExternalReference ref,
483 : MachineRepresentation input_type);
484 :
485 : Node* BuildCFuncInstruction(ExternalReference ref, MachineType type,
486 : Node* input0, Node* input1 = nullptr);
487 : Node* BuildF32Trunc(Node* input);
488 : Node* BuildF32Floor(Node* input);
489 : Node* BuildF32Ceil(Node* input);
490 : Node* BuildF32NearestInt(Node* input);
491 : Node* BuildF64Trunc(Node* input);
492 : Node* BuildF64Floor(Node* input);
493 : Node* BuildF64Ceil(Node* input);
494 : Node* BuildF64NearestInt(Node* input);
495 : Node* BuildI32Rol(Node* left, Node* right);
496 : Node* BuildI64Rol(Node* left, Node* right);
497 :
498 : Node* BuildF64Acos(Node* input);
499 : Node* BuildF64Asin(Node* input);
500 : Node* BuildF64Pow(Node* left, Node* right);
501 : Node* BuildF64Mod(Node* left, Node* right);
502 :
503 : Node* BuildIntToFloatConversionInstruction(
504 : Node* input, ExternalReference ref,
505 : MachineRepresentation parameter_representation,
506 : const MachineType result_type);
507 : Node* BuildF32SConvertI64(Node* input);
508 : Node* BuildF32UConvertI64(Node* input);
509 : Node* BuildF64SConvertI64(Node* input);
510 : Node* BuildF64UConvertI64(Node* input);
511 :
512 : Node* BuildCcallConvertFloat(Node* input, wasm::WasmCodePosition position,
513 : wasm::WasmOpcode opcode);
514 :
515 : Node* BuildI32DivS(Node* left, Node* right, wasm::WasmCodePosition position);
516 : Node* BuildI32RemS(Node* left, Node* right, wasm::WasmCodePosition position);
517 : Node* BuildI32DivU(Node* left, Node* right, wasm::WasmCodePosition position);
518 : Node* BuildI32RemU(Node* left, Node* right, wasm::WasmCodePosition position);
519 :
520 : Node* BuildI64DivS(Node* left, Node* right, wasm::WasmCodePosition position);
521 : Node* BuildI64RemS(Node* left, Node* right, wasm::WasmCodePosition position);
522 : Node* BuildI64DivU(Node* left, Node* right, wasm::WasmCodePosition position);
523 : Node* BuildI64RemU(Node* left, Node* right, wasm::WasmCodePosition position);
524 : Node* BuildDiv64Call(Node* left, Node* right, ExternalReference ref,
525 : MachineType result_type, wasm::TrapReason trap_zero,
526 : wasm::WasmCodePosition position);
527 :
528 : Node* BuildChangeInt32ToIntPtr(Node* value);
529 : Node* BuildChangeInt32ToSmi(Node* value);
530 : Node* BuildChangeUint31ToSmi(Node* value);
531 : Node* BuildSmiShiftBitsConstant();
532 : Node* BuildChangeSmiToInt32(Node* value);
533 : // generates {index > max ? Smi(max) : Smi(index)}
534 : Node* BuildConvertUint32ToSmiWithSaturation(Node* index, uint32_t maxval);
535 :
536 : // Asm.js specific functionality.
537 : Node* BuildI32AsmjsSConvertF32(Node* input);
538 : Node* BuildI32AsmjsSConvertF64(Node* input);
539 : Node* BuildI32AsmjsUConvertF32(Node* input);
540 : Node* BuildI32AsmjsUConvertF64(Node* input);
541 : Node* BuildI32AsmjsDivS(Node* left, Node* right);
542 : Node* BuildI32AsmjsRemS(Node* left, Node* right);
543 : Node* BuildI32AsmjsDivU(Node* left, Node* right);
544 : Node* BuildI32AsmjsRemU(Node* left, Node* right);
545 : Node* BuildAsmjsLoadMem(MachineType type, Node* index);
546 : Node* BuildAsmjsStoreMem(MachineType type, Node* index, Node* val);
547 :
548 : void BuildEncodeException32BitValue(Node* values_array, uint32_t* index,
549 : Node* value);
550 : Node* BuildDecodeException32BitValue(Node* values_array, uint32_t* index);
551 : Node* BuildDecodeException64BitValue(Node* values_array, uint32_t* index);
552 :
553 300057 : Node** Realloc(Node* const* buffer, size_t old_count, size_t new_count) {
554 300057 : Node** buf = Buffer(new_count);
555 300058 : if (buf != buffer) memcpy(buf, buffer, old_count * sizeof(Node*));
556 300058 : return buf;
557 : }
558 :
559 : Node* BuildLoadBuiltinFromInstance(int builtin_index);
560 :
561 : //-----------------------------------------------------------------------
562 : // Operations involving the CEntry, a dependency we want to remove
563 : // to get off the GC heap.
564 : //-----------------------------------------------------------------------
565 : Node* BuildCallToRuntime(Runtime::FunctionId f, Node** parameters,
566 : int parameter_count);
567 :
568 : Node* BuildCallToRuntimeWithContext(Runtime::FunctionId f, Node* js_context,
569 : Node** parameters, int parameter_count,
570 : Node** effect, Node* control);
571 : TrapId GetTrapIdForTrap(wasm::TrapReason reason);
572 : };
573 :
574 : V8_EXPORT_PRIVATE CallDescriptor* GetWasmCallDescriptor(
575 : Zone* zone, wasm::FunctionSig* signature,
576 : WasmGraphBuilder::UseRetpoline use_retpoline =
577 : WasmGraphBuilder::kNoRetpoline,
578 : WasmGraphBuilder::ExtraCallableParam callable_param =
579 : WasmGraphBuilder::kNoExtraCallableParam);
580 :
581 : V8_EXPORT_PRIVATE CallDescriptor* GetI32WasmCallDescriptor(
582 : Zone* zone, CallDescriptor* call_descriptor);
583 :
584 : V8_EXPORT_PRIVATE CallDescriptor* GetI32WasmCallDescriptorForSimd(
585 : Zone* zone, CallDescriptor* call_descriptor);
586 :
587 : AssemblerOptions WasmAssemblerOptions();
588 : AssemblerOptions WasmStubAssemblerOptions();
589 :
590 : } // namespace compiler
591 : } // namespace internal
592 : } // namespace v8
593 :
594 : #endif // V8_COMPILER_WASM_COMPILER_H_
|