Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/wabt/interp/istream.h
1 /* 2 * Copyright 2020 WebAssembly Community Group participants 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef WABT_INTERP_ISTREAM_H_ 18 #define WABT_INTERP_ISTREAM_H_ 19 20 #include <cstdint> 21 #include <string> 22 #include <vector> 23 24 #include "wabt/common.h" 25 #include "wabt/opcode.h" 26 #include "wabt/stream.h" 27 28 namespace wabt { 29 namespace interp { 30 31 using u8 = uint8_t; 32 using u16 = uint16_t; 33 using u32 = uint32_t; 34 using u64 = uint64_t; 35 using f32 = float; 36 using f64 = double; 37 38 using Buffer = std::vector<u8>; 39 40 using ValueType = wabt::Type; 41 42 // Group instructions based on their immediates their operands. This way we can 43 // simplify instruction decoding, disassembling, and tracing. There is an 44 // example of an instruction that uses this encoding on the right. 45 enum class InstrKind { 46 Imm_0_Op_0, // Nop 47 Imm_0_Op_1, // i32.eqz 48 Imm_0_Op_2, // i32.add 49 Imm_0_Op_3, // select 50 Imm_Jump_Op_0, // br 51 Imm_Jump_Op_1, // br_if 52 Imm_Index_Op_0, // global.get 53 Imm_Index_Op_1, // global.set 54 Imm_Index_Op_2, // table.set 55 Imm_Index_Op_3, // memory.fill 56 Imm_Index_Op_N, // call 57 Imm_Index_Index_Op_3, // memory.init 58 Imm_Index_Index_Op_N, // call_indirect 59 Imm_Index_Offset_Op_1, // i32.load 60 Imm_Index_Offset_Op_2, // i32.store 61 Imm_Index_Offset_Op_3, // i32.atomic.rmw.cmpxchg 62 Imm_Index_Offset_Lane_Op_2, // v128.load8_lane 63 Imm_I32_Op_0, // i32.const 64 Imm_I64_Op_0, // i64.const 65 Imm_F32_Op_0, // f32.const 66 Imm_F64_Op_0, // f64.const 67 Imm_I32_I32_Op_0, // drop_keep 68 Imm_I8_Op_1, // i32x4.extract_lane 69 Imm_I8_Op_2, // i32x4.replace_lane 70 Imm_V128_Op_0, // v128.const 71 Imm_V128_Op_2, // i8x16.shuffle 72 }; 73 74 struct Instr { 75 Opcode op; 76 InstrKind kind; 77 union { 78 u8 imm_u8; 79 u32 imm_u32; 80 f32 imm_f32; 81 u64 imm_u64; 82 f64 imm_f64; 83 v128 imm_v128; 84 struct { 85 u32 fst, snd; 86 } imm_u32x2; 87 struct { 88 u32 fst, snd; 89 u8 idx; 90 } imm_u32x2_u8; 91 }; 92 }; 93 94 class Istream { 95 public: 96 using SerializedOpcode = u32; // TODO: change to u16 97 using Offset = u32; 98 static constexpr Offset kInvalidOffset = ~0; 99 // Each br_table entry is made up of three instructions: 100 // 101 // interp_drop_keep $drop $keep 102 // interp_catch_drop $catches 103 // br $label 104 // 105 // Each opcode is a SerializedOpcode, and each immediate is a u32. 106 static constexpr Offset kBrTableEntrySize = 107 sizeof(SerializedOpcode) * 3 + 4 * sizeof(u32); 108 109 // Emit API. 110 void Emit(u32); 111 void Emit(Opcode::Enum); 112 void Emit(Opcode::Enum, u8); 113 void Emit(Opcode::Enum, u32); 114 void Emit(Opcode::Enum, u64); 115 void Emit(Opcode::Enum, v128); 116 void Emit(Opcode::Enum, u32, u32); 117 void Emit(Opcode::Enum, u32, u32, u8); 118 void EmitDropKeep(u32 drop, u32 keep); 119 void EmitCatchDrop(u32 drop); 120 121 Offset EmitFixupU32(); 122 void ResolveFixupU32(Offset); 123 124 Offset end() const; 125 126 // Read API. 127 Instr Read(Offset*) const; 128 129 // Disassemble/Trace API. 130 // TODO separate out disassembly/tracing? 131 struct TraceSource { 132 virtual ~TraceSource() {} 133 // Whatever content should go before the instruction on each line, e.g. the 134 // call stack size, value stack size, and istream offset. 135 virtual std::string Header(Offset) = 0; 136 virtual std::string Pick(Index, Instr) = 0; 137 }; 138 139 struct DisassemblySource : TraceSource { 140 std::string Header(Offset) override; 141 std::string Pick(Index, Instr) override; 142 }; 143 144 void Disassemble(Stream*) const; 145 Offset Disassemble(Stream*, Offset) const; 146 void Disassemble(Stream*, Offset from, Offset to) const; 147 148 Offset Trace(Stream*, Offset, TraceSource*) const; 149 150 private: 151 template <typename T> 152 void WABT_VECTORCALL EmitAt(Offset, T val); 153 template <typename T> 154 void WABT_VECTORCALL EmitInternal(T val); 155 156 template <typename T> 157 T WABT_VECTORCALL ReadAt(Offset*) const; 158 159 Buffer data_; 160 }; 161 162 } // namespace interp 163 } // namespace wabt 164 165 #endif // WABT_INTERP_ISTREAM_H_