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