LCOV - code coverage report
Current view: top level - src/wasm - wasm-interpreter.h (source / functions) Hit Total Coverage
Test: app.info Lines: 3 3 100.0 %
Date: 2017-04-26 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright 2016 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_WASM_INTERPRETER_H_
       6             : #define V8_WASM_INTERPRETER_H_
       7             : 
       8             : #include "src/wasm/wasm-opcodes.h"
       9             : #include "src/zone/zone-containers.h"
      10             : 
      11             : namespace v8 {
      12             : namespace base {
      13             : class AccountingAllocator;
      14             : }
      15             : 
      16             : namespace internal {
      17             : class WasmInstanceObject;
      18             : 
      19             : namespace wasm {
      20             : 
      21             : // forward declarations.
      22             : struct ModuleBytesEnv;
      23             : struct WasmFunction;
      24             : struct WasmModule;
      25             : class WasmInterpreterInternals;
      26             : 
      27             : using pc_t = size_t;
      28             : using sp_t = size_t;
      29             : using pcdiff_t = int32_t;
      30             : using spdiff_t = uint32_t;
      31             : 
      32             : constexpr pc_t kInvalidPc = 0x80000000;
      33             : 
      34             : struct ControlTransferEntry {
      35             :   // Distance from the instruction to the label to jump to (forward, but can be
      36             :   // negative).
      37             :   pcdiff_t pc_diff;
      38             :   // Delta by which to decrease the stack height.
      39             :   spdiff_t sp_diff;
      40             :   // Arity of the block we jump to.
      41             :   uint32_t target_arity;
      42             : };
      43             : 
      44             : using ControlTransferMap = ZoneMap<pc_t, ControlTransferEntry>;
      45             : 
      46             : // Macro for defining union members.
      47             : #define FOREACH_UNION_MEMBER(V) \
      48             :   V(i32, kWasmI32, int32_t)     \
      49             :   V(u32, kWasmI32, uint32_t)    \
      50             :   V(i64, kWasmI64, int64_t)     \
      51             :   V(u64, kWasmI64, uint64_t)    \
      52             :   V(f32, kWasmF32, float)       \
      53             :   V(f64, kWasmF64, double)
      54             : 
      55             : // Representation of values within the interpreter.
      56             : struct WasmVal {
      57             :   ValueType type;
      58             :   union {
      59             : #define DECLARE_FIELD(field, localtype, ctype) ctype field;
      60             :     FOREACH_UNION_MEMBER(DECLARE_FIELD)
      61             : #undef DECLARE_FIELD
      62             :   } val;
      63             : 
      64       72900 :   WasmVal() : type(kWasmStmt) {}
      65             : 
      66             : #define DECLARE_CONSTRUCTOR(field, localtype, ctype) \
      67             :   explicit WasmVal(ctype v) : type(localtype) { val.field = v; }
      68             :   FOREACH_UNION_MEMBER(DECLARE_CONSTRUCTOR)
      69             : #undef DECLARE_CONSTRUCTOR
      70             : 
      71             :   bool operator==(const WasmVal& other) const {
      72             :     if (type != other.type) return false;
      73             : #define CHECK_VAL_EQ(field, localtype, ctype) \
      74             :   if (type == localtype) {                    \
      75             :     return val.field == other.val.field;      \
      76             :   }
      77             :     FOREACH_UNION_MEMBER(CHECK_VAL_EQ)
      78             : #undef CHECK_VAL_EQ
      79             :     UNREACHABLE();
      80             :     return false;
      81             :   }
      82             : 
      83             :   template <typename T>
      84             :   inline T to() const {
      85             :     UNREACHABLE();
      86             :   }
      87             : 
      88             :   template <typename T>
      89             :   inline T to_unchecked() const {
      90             :     UNREACHABLE();
      91             :   }
      92             : };
      93             : 
      94             : #define DECLARE_CAST(field, localtype, ctype)  \
      95             :   template <>                                  \
      96             :   inline ctype WasmVal::to_unchecked() const { \
      97             :     return val.field;                          \
      98             :   }                                            \
      99             :   template <>                                  \
     100             :   inline ctype WasmVal::to() const {           \
     101             :     CHECK_EQ(localtype, type);                 \
     102             :     return val.field;                          \
     103             :   }
     104     4644512 : FOREACH_UNION_MEMBER(DECLARE_CAST)
     105             : #undef DECLARE_CAST
     106             : 
     107             : // Representation of frames within the interpreter.
     108             : //
     109             : // Layout of a frame:
     110             : // -----------------
     111             : // stack slot #N  ‾\.
     112             : // ...             |  stack entries: GetStackHeight(); GetStackValue()
     113             : // stack slot #0  _/·
     114             : // local #L       ‾\.
     115             : // ...             |  locals: GetLocalCount(); GetLocalValue()
     116             : // local #P+1      |
     117             : // param #P        |   ‾\.
     118             : // ...             |    | parameters: GetParameterCount(); GetLocalValue()
     119             : // param #0       _/·  _/·
     120             : // -----------------
     121             : //
     122             : class InterpretedFrame {
     123             :  public:
     124             :   const WasmFunction* function() const;
     125             :   int pc() const;
     126             : 
     127             :   int GetParameterCount() const;
     128             :   int GetLocalCount() const;
     129             :   int GetStackHeight() const;
     130             :   WasmVal GetLocalValue(int index) const;
     131             :   WasmVal GetStackValue(int index) const;
     132             : 
     133             :  private:
     134             :   friend class WasmInterpreter;
     135             :   // Don't instante InterpretedFrames; they will be allocated as
     136             :   // InterpretedFrameImpl in the interpreter implementation.
     137             :   InterpretedFrame() = delete;
     138             :   DISALLOW_COPY_AND_ASSIGN(InterpretedFrame);
     139             : };
     140             : 
     141             : // An interpreter capable of executing WASM.
     142             : class V8_EXPORT_PRIVATE WasmInterpreter {
     143             :  public:
     144             :   // State machine for a Thread:
     145             :   //                         +---------Run()/Step()--------+
     146             :   //                         V                             |
     147             :   // STOPPED ---Run()-->  RUNNING  ------Pause()-----+-> PAUSED
     148             :   //  ^                   | | | |                   /
     149             :   //  +- HandleException -+ | | +--- Breakpoint ---+
     150             :   //                        | |
     151             :   //                        | +---------- Trap --------------> TRAPPED
     152             :   //                        +----------- Finish -------------> FINISHED
     153             :   enum State { STOPPED, RUNNING, PAUSED, FINISHED, TRAPPED };
     154             : 
     155             :   // Tells a thread to pause after certain instructions.
     156             :   enum BreakFlag : uint8_t {
     157             :     None = 0,
     158             :     AfterReturn = 1 << 0,
     159             :     AfterCall = 1 << 1
     160             :   };
     161             : 
     162             :   // Representation of a thread in the interpreter.
     163             :   class V8_EXPORT_PRIVATE Thread {
     164             :     // Don't instante Threads; they will be allocated as ThreadImpl in the
     165             :     // interpreter implementation.
     166             :     Thread() = delete;
     167             : 
     168             :    public:
     169             :     enum ExceptionHandlingResult { HANDLED, UNWOUND };
     170             : 
     171             :     // Execution control.
     172             :     State state();
     173             :     void InitFrame(const WasmFunction* function, WasmVal* args);
     174             :     // Pass -1 as num_steps to run till completion, pause or breakpoint.
     175             :     State Run(int num_steps = -1);
     176         219 :     State Step() { return Run(1); }
     177             :     void Pause();
     178             :     void Reset();
     179             :     // Handle the pending exception in the passed isolate. Unwind the stack
     180             :     // accordingly. Return whether the exception was handled inside wasm.
     181             :     ExceptionHandlingResult HandleException(Isolate* isolate);
     182             : 
     183             :     // Stack inspection and modification.
     184             :     pc_t GetBreakpointPc();
     185             :     // TODO(clemensh): Make this uint32_t.
     186             :     int GetFrameCount();
     187             :     // The InterpretedFrame is only valid as long as the Thread is paused.
     188             :     std::unique_ptr<InterpretedFrame> GetFrame(int index);
     189             :     WasmVal GetReturnValue(int index = 0);
     190             :     TrapReason GetTrapReason();
     191             : 
     192             :     // Returns true if the thread executed an instruction which may produce
     193             :     // nondeterministic results, e.g. float div, float sqrt, and float mul,
     194             :     // where the sign bit of a NaN is nondeterministic.
     195             :     bool PossibleNondeterminism();
     196             : 
     197             :     // Returns the number of calls / function frames executed on this thread.
     198             :     uint64_t NumInterpretedCalls();
     199             : 
     200             :     // Thread-specific breakpoints.
     201             :     // TODO(wasm): Implement this once we support multiple threads.
     202             :     // bool SetBreakpoint(const WasmFunction* function, int pc, bool enabled);
     203             :     // bool GetBreakpoint(const WasmFunction* function, int pc);
     204             : 
     205             :     void AddBreakFlags(uint8_t flags);
     206             :     void ClearBreakFlags();
     207             : 
     208             :     // Each thread can have multiple activations, each represented by a portion
     209             :     // of the stack frames of this thread. StartActivation returns the id
     210             :     // (counting from 0 up) of the started activation.
     211             :     // Activations must be properly stacked, i.e. if FinishActivation is called,
     212             :     // the given id must the the latest activation on the stack.
     213             :     uint32_t NumActivations();
     214             :     uint32_t StartActivation();
     215             :     void FinishActivation(uint32_t activation_id);
     216             :     // Return the frame base of the given activation, i.e. the number of frames
     217             :     // when this activation was started.
     218             :     uint32_t ActivationFrameBase(uint32_t activation_id);
     219             :   };
     220             : 
     221             :   WasmInterpreter(Isolate* isolate, const ModuleBytesEnv& env);
     222             :   ~WasmInterpreter();
     223             : 
     224             :   //==========================================================================
     225             :   // Execution controls.
     226             :   //==========================================================================
     227             :   void Run();
     228             :   void Pause();
     229             : 
     230             :   // Set a breakpoint at {pc} in {function} to be {enabled}. Returns the
     231             :   // previous state of the breakpoint at {pc}.
     232             :   bool SetBreakpoint(const WasmFunction* function, pc_t pc, bool enabled);
     233             : 
     234             :   // Gets the current state of the breakpoint at {function}.
     235             :   bool GetBreakpoint(const WasmFunction* function, pc_t pc);
     236             : 
     237             :   // Enable or disable tracing for {function}. Return the previous state.
     238             :   bool SetTracing(const WasmFunction* function, bool enabled);
     239             : 
     240             :   // Set the associated wasm instance object.
     241             :   // If the instance object has been set, some tables stored inside it are used
     242             :   // instead of the tables stored in the WasmModule struct. This allows to call
     243             :   // back and forth between the interpreter and outside code (JS or wasm
     244             :   // compiled) without repeatedly copying information.
     245             :   void SetInstanceObject(WasmInstanceObject*);
     246             : 
     247             :   //==========================================================================
     248             :   // Thread iteration and inspection.
     249             :   //==========================================================================
     250             :   int GetThreadCount();
     251             :   Thread* GetThread(int id);
     252             : 
     253             :   //==========================================================================
     254             :   // Memory access.
     255             :   //==========================================================================
     256             :   size_t GetMemorySize();
     257             :   WasmVal ReadMemory(size_t offset);
     258             :   void WriteMemory(size_t offset, WasmVal val);
     259             : 
     260             :   //==========================================================================
     261             :   // Testing functionality.
     262             :   //==========================================================================
     263             :   // Manually adds a function to this interpreter. The func_index of the
     264             :   // function must match the current number of functions.
     265             :   void AddFunctionForTesting(const WasmFunction* function);
     266             :   // Manually adds code to the interpreter for the given function.
     267             :   void SetFunctionCodeForTesting(const WasmFunction* function,
     268             :                                  const byte* start, const byte* end);
     269             : 
     270             :   // Computes the control transfers for the given bytecode. Used internally in
     271             :   // the interpreter, but exposed for testing.
     272             :   static ControlTransferMap ComputeControlTransfersForTesting(
     273             :       Zone* zone, const WasmModule* module, const byte* start, const byte* end);
     274             : 
     275             :  private:
     276             :   Zone zone_;
     277             :   WasmInterpreterInternals* internals_;
     278             : };
     279             : 
     280             : }  // namespace wasm
     281             : }  // namespace internal
     282             : }  // namespace v8
     283             : 
     284             : #endif  // V8_WASM_INTERPRETER_H_

Generated by: LCOV version 1.10