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 // Clients of this interface shouldn't depend on lots of compiler internals. 9 // Do not include anything from src/compiler here! 10 #include "src/wasm/wasm-opcodes.h" 11 #include "src/zone.h" 12 13 namespace v8 { 14 namespace internal { 15 16 namespace compiler { 17 // Forward declarations for some compiler data structures. 18 class Node; 19 class JSGraph; 20 class Graph; 21 } 22 23 namespace wasm { 24 // Forward declarations for some WASM data structures. 25 struct ModuleEnv; 26 struct WasmFunction; 27 class ErrorThrower; 28 29 // Expose {Node} and {Graph} opaquely as {wasm::TFNode} and {wasm::TFGraph}. 30 typedef compiler::Node TFNode; 31 typedef compiler::JSGraph TFGraph; 32 } 33 34 namespace compiler { 35 // Compiles a single function, producing a code object. 36 Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate, 37 wasm::ModuleEnv* module_env, 38 const wasm::WasmFunction& function, int index); 39 40 // Wraps a JS function, producing a code object that can be called from WASM. 41 Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module, 42 Handle<JSFunction> function, 43 uint32_t index); 44 45 // Wraps a given wasm code object, producing a JSFunction that can be called 46 // from JavaScript. 47 Handle<JSFunction> CompileJSToWasmWrapper( 48 Isolate* isolate, wasm::ModuleEnv* module, Handle<String> name, 49 Handle<Code> wasm_code, Handle<JSObject> module_object, uint32_t index); 50 51 // Abstracts details of building TurboFan graph nodes for WASM to separate 52 // the WASM decoder from the internal details of TurboFan. 53 class WasmTrapHelper; 54 class WasmGraphBuilder { 55 public: 56 WasmGraphBuilder(Zone* z, JSGraph* g, wasm::FunctionSig* function_signature); 57 Buffer(size_t count)58 Node** Buffer(size_t count) { 59 if (count > cur_bufsize_) { 60 size_t new_size = count + cur_bufsize_ + 5; 61 cur_buffer_ = 62 reinterpret_cast<Node**>(zone_->New(new_size * sizeof(Node*))); 63 cur_bufsize_ = new_size; 64 } 65 return cur_buffer_; 66 } 67 68 //----------------------------------------------------------------------- 69 // Operations independent of {control} or {effect}. 70 //----------------------------------------------------------------------- 71 Node* Error(); 72 Node* Start(unsigned params); 73 Node* Param(unsigned index, wasm::LocalType type); 74 Node* Loop(Node* entry); 75 Node* Terminate(Node* effect, Node* control); 76 Node* Merge(unsigned count, Node** controls); 77 Node* Phi(wasm::LocalType type, unsigned count, Node** vals, Node* control); 78 Node* EffectPhi(unsigned count, Node** effects, Node* control); 79 Node* Int32Constant(int32_t value); 80 Node* Int64Constant(int64_t value); 81 Node* Float32Constant(float value); 82 Node* Float64Constant(double value); 83 Node* Constant(Handle<Object> value); 84 Node* Binop(wasm::WasmOpcode opcode, Node* left, Node* right); 85 Node* Unop(wasm::WasmOpcode opcode, Node* input); 86 unsigned InputCount(Node* node); 87 bool IsPhiWithMerge(Node* phi, Node* merge); 88 void AppendToMerge(Node* merge, Node* from); 89 void AppendToPhi(Node* merge, Node* phi, Node* from); 90 91 //----------------------------------------------------------------------- 92 // Operations that read and/or write {control} and {effect}. 93 //----------------------------------------------------------------------- 94 Node* Branch(Node* cond, Node** true_node, Node** false_node); 95 Node* Switch(unsigned count, Node* key); 96 Node* IfValue(int32_t value, Node* sw); 97 Node* IfDefault(Node* sw); 98 Node* Return(unsigned count, Node** vals); 99 Node* ReturnVoid(); 100 Node* Unreachable(); 101 102 Node* CallDirect(uint32_t index, Node** args); 103 Node* CallIndirect(uint32_t index, Node** args); 104 void BuildJSToWasmWrapper(Handle<Code> wasm_code, wasm::FunctionSig* sig); 105 void BuildWasmToJSWrapper(Handle<JSFunction> function, 106 wasm::FunctionSig* sig); 107 Node* ToJS(Node* node, Node* context, wasm::LocalType type); 108 Node* FromJS(Node* node, Node* context, wasm::LocalType type); 109 Node* Invert(Node* node); 110 Node* FunctionTable(); 111 112 //----------------------------------------------------------------------- 113 // Operations that concern the linear memory. 114 //----------------------------------------------------------------------- 115 Node* MemSize(uint32_t offset); 116 Node* LoadGlobal(uint32_t index); 117 Node* StoreGlobal(uint32_t index, Node* val); 118 Node* LoadMem(wasm::LocalType type, MachineType memtype, Node* index, 119 uint32_t offset); 120 Node* StoreMem(MachineType type, Node* index, uint32_t offset, Node* val); 121 122 static void PrintDebugName(Node* node); 123 Control()124 Node* Control() { return *control_; } Effect()125 Node* Effect() { return *effect_; } 126 set_module(wasm::ModuleEnv * module)127 void set_module(wasm::ModuleEnv* module) { this->module_ = module; } 128 set_control_ptr(Node ** control)129 void set_control_ptr(Node** control) { this->control_ = control; } 130 set_effect_ptr(Node ** effect)131 void set_effect_ptr(Node** effect) { this->effect_ = effect; } 132 GetFunctionSignature()133 wasm::FunctionSig* GetFunctionSignature() { return function_signature_; } 134 135 private: 136 static const int kDefaultBufferSize = 16; 137 friend class WasmTrapHelper; 138 139 Zone* zone_; 140 JSGraph* jsgraph_; 141 wasm::ModuleEnv* module_; 142 Node* mem_buffer_; 143 Node* mem_size_; 144 Node* function_table_; 145 Node** control_; 146 Node** effect_; 147 Node** cur_buffer_; 148 size_t cur_bufsize_; 149 Node* def_buffer_[kDefaultBufferSize]; 150 151 WasmTrapHelper* trap_; 152 wasm::FunctionSig* function_signature_; 153 154 // Internal helper methods. jsgraph()155 JSGraph* jsgraph() { return jsgraph_; } 156 Graph* graph(); 157 158 Node* String(const char* string); 159 Node* MemBuffer(uint32_t offset); 160 void BoundsCheckMem(MachineType memtype, Node* index, uint32_t offset); 161 162 Node* BuildWasmCall(wasm::FunctionSig* sig, Node** args); 163 Node* BuildF32Neg(Node* input); 164 Node* BuildF64Neg(Node* input); 165 Node* BuildF32CopySign(Node* left, Node* right); 166 Node* BuildF64CopySign(Node* left, Node* right); 167 Node* BuildF32Min(Node* left, Node* right); 168 Node* BuildF32Max(Node* left, Node* right); 169 Node* BuildF64Min(Node* left, Node* right); 170 Node* BuildF64Max(Node* left, Node* right); 171 Node* BuildI32SConvertF32(Node* input); 172 Node* BuildI32SConvertF64(Node* input); 173 Node* BuildI32UConvertF32(Node* input); 174 Node* BuildI32UConvertF64(Node* input); 175 Node* BuildI32Ctz(Node* input); 176 Node* BuildI32Popcnt(Node* input); 177 Node* BuildI64Ctz(Node* input); 178 Node* BuildI64Popcnt(Node* input); 179 Realloc(Node ** buffer,size_t count)180 Node** Realloc(Node** buffer, size_t count) { 181 Node** buf = Buffer(count); 182 if (buf != buffer) memcpy(buf, buffer, count * sizeof(Node*)); 183 return buf; 184 } 185 }; 186 } // namespace compiler 187 } // namespace internal 188 } // namespace v8 189 190 #endif // V8_COMPILER_WASM_COMPILER_H_ 191