Home | History | Annotate | Download | only in compiler
      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 
     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 
    124   Node* Control() { return *control_; }
    125   Node* Effect() { return *effect_; }
    126 
    127   void set_module(wasm::ModuleEnv* module) { this->module_ = module; }
    128 
    129   void set_control_ptr(Node** control) { this->control_ = control; }
    130 
    131   void set_effect_ptr(Node** effect) { this->effect_ = effect; }
    132 
    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.
    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 
    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