staticConst I32(uint32_t val = 0, const Location& loc = Location()) { returnConst(Type::I32, val, loc);
} staticConst I64(uint64_t val = 0, const Location& loc = Location()) { returnConst(Type::I64, val, loc);
} staticConst F32(uint32_t val = 0, const Location& loc = Location()) { returnConst(Type::F32, val, loc);
} staticConst F64(uint64_t val = 0, const Location& loc = Location()) { returnConst(Type::F64, val, loc);
} staticConst V128(v128 val, const Location& loc = Location()) { returnConst(Type::V128, val, loc);
}
Type type() const { return type_; }
Type lane_type() const {
assert(type_ == Type::V128); return lane_type_;
}
int lane_count() const { switch (lane_type()) { case Type::I8: return16; case Type::I16: return8; case Type::I32: return4; case Type::I64: return2; case Type::F32: return4; case Type::F64: return2; default: WABT_UNREACHABLE;
}
}
// Some types can have names, for example (ref $foo) has type $foo. // So to use this type we need to translate its name into // a proper index from the module type section. // This is the mapping from parameter/result index to its name.
std::unordered_map<uint32_t, std::string> param_type_names;
std::unordered_map<uint32_t, std::string> result_type_names;
Index GetNumParams() const { return param_types.size(); }
Index GetNumResults() const { return result_types.size(); }
Type GetParamType(Index index) const { return param_types[index]; }
Type GetResultType(Index index) const { return result_types[index]; }
booloperator==(const FuncSignature&) const;
};
enum class TypeEntryKind {
Func, Struct,
Array,
};
class TypeEntry { public:
WABT_DISALLOW_COPY_AND_ASSIGN(TypeEntry);
virtual ~TypeEntry() = default;
TypeEntryKind kind() const { return kind_; }
Location loc;
std::string name;
protected:
explicit TypeEntry(TypeEntryKind kind,
std::string_view name = std::string_view(), const Location& loc = Location())
: loc(loc), name(name), kind_(kind) {}
TypeEntryKind kind_;
};
class FuncType : public TypeEntry { public: staticbool classof(const TypeEntry* entry) { return entry->kind() == TypeEntryKind::Func;
}
explicit FuncType(std::string_view name = std::string_view())
: TypeEntry(TypeEntryKind::Func, name) {}
Index GetNumParams() const { return sig.GetNumParams(); }
Index GetNumResults() const { return sig.GetNumResults(); }
Type GetParamType(Index index) const { return sig.GetParamType(index); }
Type GetResultType(Index index) const { return sig.GetResultType(index); }
FuncSignature sig;
// The BinaryReaderIR tracks whether a FuncType is the target of a tailcall // (via a return_call_indirect). wasm2c (CWriter) uses this information to // limit its output in some cases. struct { bool tailcall = false;
} features_used;
};
struct Field {
std::string name;
Type type = Type::Void; bool mutable_ = false;
};
class StructType : public TypeEntry { public: staticbool classof(const TypeEntry* entry) { return entry->kind() == TypeEntryKind::Struct;
}
explicit StructType(std::string_view name = std::string_view())
: TypeEntry(TypeEntryKind::Struct) {}
std::vector<Field> fields;
};
class ArrayType : public TypeEntry { public: staticbool classof(const TypeEntry* entry) { return entry->kind() == TypeEntryKind::Array;
}
explicit ArrayType(std::string_view name = std::string_view())
: TypeEntry(TypeEntryKind::Array) {}
Field field;
};
struct FuncDeclaration {
Index GetNumParams() const { return sig.GetNumParams(); }
Index GetNumResults() const { return sig.GetNumResults(); }
Type GetParamType(Index index) const { return sig.GetParamType(index); }
Type GetResultType(Index index) const { return sig.GetResultType(index); }
bool has_func_type = false;
Var type_var;
FuncSignature sig;
};
template <ExprType TypeEnum> class MemoryExpr : public ExprMixin<TypeEnum> { public:
MemoryExpr(Var memidx, const Location& loc = Location())
: ExprMixin<TypeEnum>(loc), memidx(memidx) {}
Var memidx;
};
template <ExprType TypeEnum> class MemoryBinaryExpr : public ExprMixin<TypeEnum> { public:
MemoryBinaryExpr(Var destmemidx,
Var srcmemidx, const Location& loc = Location())
: ExprMixin<TypeEnum>(loc),
destmemidx(destmemidx),
srcmemidx(srcmemidx) {}
Var destmemidx;
Var srcmemidx;
};
using DropExpr = ExprMixin<ExprType::Drop>; using NopExpr = ExprMixin<ExprType::Nop>; using ReturnExpr = ExprMixin<ExprType::Return>; using UnreachableExpr = ExprMixin<ExprType::Unreachable>;
using MemoryGrowExpr = MemoryExpr<ExprType::MemoryGrow>; using MemorySizeExpr = MemoryExpr<ExprType::MemorySize>; using MemoryFillExpr = MemoryExpr<ExprType::MemoryFill>;
using MemoryCopyExpr = MemoryBinaryExpr<ExprType::MemoryCopy>;
template <ExprType TypeEnum> class RefTypeExpr : public ExprMixin<TypeEnum> { public:
RefTypeExpr(Type type, const Location& loc = Location())
: ExprMixin<TypeEnum>(loc), type(type) {}
Type type;
};
using RefNullExpr = RefTypeExpr<ExprType::RefNull>; using RefIsNullExpr = ExprMixin<ExprType::RefIsNull>;
template <ExprType TypeEnum> class OpcodeExpr : public ExprMixin<TypeEnum> { public:
OpcodeExpr(Opcode opcode, const Location& loc = Location())
: ExprMixin<TypeEnum>(loc), opcode(opcode) {}
Opcode opcode;
};
using BinaryExpr = OpcodeExpr<ExprType::Binary>; using CompareExpr = OpcodeExpr<ExprType::Compare>; using ConvertExpr = OpcodeExpr<ExprType::Convert>; using UnaryExpr = OpcodeExpr<ExprType::Unary>; using TernaryExpr = OpcodeExpr<ExprType::Ternary>;
class SimdLaneOpExpr : public ExprMixin<ExprType::SimdLaneOp> { public:
SimdLaneOpExpr(Opcode opcode, uint64_t val, const Location& loc = Location())
: ExprMixin<ExprType::SimdLaneOp>(loc), opcode(opcode), val(val) {}
Opcode opcode;
uint64_t val;
};
class SimdLoadLaneExpr : public MemoryExpr<ExprType::SimdLoadLane> { public:
SimdLoadLaneExpr(Opcode opcode,
Var memidx,
Address align,
Address offset,
uint64_t val, const Location& loc = Location())
: MemoryExpr<ExprType::SimdLoadLane>(memidx, loc),
opcode(opcode),
align(align),
offset(offset),
val(val) {}
class SimdShuffleOpExpr : public ExprMixin<ExprType::SimdShuffleOp> { public:
SimdShuffleOpExpr(Opcode opcode, v128 val, const Location& loc = Location())
: ExprMixin<ExprType::SimdShuffleOp>(loc), opcode(opcode), val(val) {}
Opcode opcode;
v128 val;
};
template <ExprType TypeEnum> class VarExpr : public ExprMixin<TypeEnum> { public:
VarExpr(const Var& var, const Location& loc = Location())
: ExprMixin<TypeEnum>(loc), var(var) {}
Var var;
};
template <ExprType TypeEnum> class MemoryVarExpr : public MemoryExpr<TypeEnum> { public:
MemoryVarExpr(const Var& var, Var memidx, const Location& loc = Location())
: MemoryExpr<TypeEnum>(memidx, loc), var(var) {}
Var var;
};
using BrExpr = VarExpr<ExprType::Br>; using BrIfExpr = VarExpr<ExprType::BrIf>; using CallExpr = VarExpr<ExprType::Call>; using RefFuncExpr = VarExpr<ExprType::RefFunc>; using GlobalGetExpr = VarExpr<ExprType::GlobalGet>; using GlobalSetExpr = VarExpr<ExprType::GlobalSet>; using LocalGetExpr = VarExpr<ExprType::LocalGet>; using LocalSetExpr = VarExpr<ExprType::LocalSet>; using LocalTeeExpr = VarExpr<ExprType::LocalTee>; using ReturnCallExpr = VarExpr<ExprType::ReturnCall>; using ThrowExpr = VarExpr<ExprType::Throw>; using RethrowExpr = VarExpr<ExprType::Rethrow>;
using DataDropExpr = VarExpr<ExprType::DataDrop>; using ElemDropExpr = VarExpr<ExprType::ElemDrop>; using TableGetExpr = VarExpr<ExprType::TableGet>; using TableSetExpr = VarExpr<ExprType::TableSet>; using TableGrowExpr = VarExpr<ExprType::TableGrow>; using TableSizeExpr = VarExpr<ExprType::TableSize>; using TableFillExpr = VarExpr<ExprType::TableFill>;
using MemoryInitExpr = MemoryVarExpr<ExprType::MemoryInit>;
class SelectExpr : public ExprMixin<ExprType::Select> { public:
SelectExpr(TypeVector type, const Location& loc = Location())
: ExprMixin<ExprType::Select>(loc), result_type(type) {}
TypeVector result_type;
};
class TableInitExpr : public ExprMixin<ExprType::TableInit> { public:
TableInitExpr(const Var& segment_index, const Var& table_index, const Location& loc = Location())
: ExprMixin<ExprType::TableInit>(loc),
segment_index(segment_index),
table_index(table_index) {}
Var segment_index;
Var table_index;
};
class TableCopyExpr : public ExprMixin<ExprType::TableCopy> { public:
TableCopyExpr(const Var& dst, const Var& src, const Location& loc = Location())
: ExprMixin<ExprType::TableCopy>(loc), dst_table(dst), src_table(src) {}
Var dst_table;
Var src_table;
};
class CallIndirectExpr : public ExprMixin<ExprType::CallIndirect> { public:
explicit CallIndirectExpr(const Location& loc = Location())
: ExprMixin<ExprType::CallIndirect>(loc) {}
FuncDeclaration decl;
Var table;
};
class CodeMetadataExpr : public ExprMixin<ExprType::CodeMetadata> { public:
explicit CodeMetadataExpr(std::string_view name,
std::vector<uint8_t> data, const Location& loc = Location())
: ExprMixin<ExprType::CodeMetadata>(loc),
name(std::move(name)),
data(std::move(data)) {}
class TryExpr : public ExprMixin<ExprType::Try> { public:
explicit TryExpr(const Location& loc = Location())
: ExprMixin<ExprType::Try>(loc), kind(TryKind::Plain) {}
TryKind kind;
Block block;
CatchVector catches;
Var delegate_target;
};
class BrTableExpr : public ExprMixin<ExprType::BrTable> { public:
BrTableExpr(const Location& loc = Location())
: ExprMixin<ExprType::BrTable>(loc) {}
VarVector targets;
Var default_target;
};
class ConstExpr : public ExprMixin<ExprType::Const> { public:
ConstExpr(constConst& c, const Location& loc = Location())
: ExprMixin<ExprType::Const>(loc), const_(c) {}
Const const_;
};
// TODO(binji): Rename this, it is used for more than loads/stores now. template <ExprType TypeEnum> class LoadStoreExpr : public MemoryExpr<TypeEnum> { public:
LoadStoreExpr(Opcode opcode,
Var memidx,
Address align,
Address offset, const Location& loc = Location())
: MemoryExpr<TypeEnum>(memidx, loc),
opcode(opcode),
align(align),
offset(offset) {}
Opcode opcode;
Address align;
Address offset;
};
using LoadExpr = LoadStoreExpr<ExprType::Load>; using StoreExpr = LoadStoreExpr<ExprType::Store>;
using AtomicLoadExpr = LoadStoreExpr<ExprType::AtomicLoad>; using AtomicStoreExpr = LoadStoreExpr<ExprType::AtomicStore>; using AtomicRmwExpr = LoadStoreExpr<ExprType::AtomicRmw>; using AtomicRmwCmpxchgExpr = LoadStoreExpr<ExprType::AtomicRmwCmpxchg>; using AtomicWaitExpr = LoadStoreExpr<ExprType::AtomicWait>; using AtomicNotifyExpr = LoadStoreExpr<ExprType::AtomicNotify>; using LoadSplatExpr = LoadStoreExpr<ExprType::LoadSplat>; using LoadZeroExpr = LoadStoreExpr<ExprType::LoadZero>;
class AtomicFenceExpr : public ExprMixin<ExprType::AtomicFence> { public:
explicit AtomicFenceExpr(uint32_t consistency_model, const Location& loc = Location())
: ExprMixin<ExprType::AtomicFence>(loc),
consistency_model(consistency_model) {}
uint32_t consistency_model;
};
struct Tag {
explicit Tag(std::string_view name) : name(name) {}
std::string name;
FuncDeclaration decl;
};
class LocalTypes { public: using Decl = std::pair<Type, Index>; using Decls = std::vector<Decl>;
// For a subset of features, the BinaryReaderIR tracks whether they are // actually used by the function. wasm2c (CWriter) uses this information to // limit its output in some cases. struct { bool tailcall = false;
} features_used;
};
struct Global {
explicit Global(std::string_view name) : name(name) {}
std::string name;
Type type = Type::Void; bool mutable_ = false;
ExprList init_expr;
};
Index num_tag_imports = 0;
Index num_func_imports = 0;
Index num_table_imports = 0;
Index num_memory_imports = 0;
Index num_global_imports = 0;
// Cached for convenience; the pointers are shared with values that are // stored in either ModuleField or Import.
std::vector<Tag*> tags;
std::vector<Func*> funcs;
std::vector<Global*> globals;
std::vector<Import*> imports;
std::vector<Export*> exports;
std::vector<TypeEntry*> types;
std::vector<Table*> tables;
std::vector<ElemSegment*> elem_segments;
std::vector<Memory*> memories;
std::vector<DataSegment*> data_segments;
std::vector<Var*> starts;
std::vector<Custom> customs;
// For a subset of features, the BinaryReaderIR tracks whether they are // actually used by the module. wasm2c (CWriter) uses this information to // limit its output in some cases. struct { bool simd = false; bool exceptions = false; bool threads = false;
} features_used;
// The BinaryReaderIR tracks function references used by the module, whether // in element segment initializers, global initializers, or functions. wasm2c // needs to emit wrappers for any functions that might get used as function // references, and uses this information to limit its output.
std::set<Index> used_func_refs;
};
enum class ScriptModuleType {
Text,
Binary,
Quoted,
};
// A ScriptModule is a module that may not yet be decoded. This allows for text // and binary parsing errors to be deferred until validation time. class ScriptModule { public:
WABT_DISALLOW_COPY_AND_ASSIGN(ScriptModule);
ScriptModule() = delete; virtual ~ScriptModule() = default;
class ModuleCommand : public CommandMixin<CommandType::Module> { public:
Module module;
};
class ScriptModuleCommand : public CommandMixin<CommandType::ScriptModule> { public: // Both the module and the script_module need to be stored since the module // has the parsed information about the module, but the script_module has the // original contents (binary or quoted).
Module module;
std::unique_ptr<ScriptModule> script_module;
};
template <CommandType TypeEnum> class ActionCommandBase : public CommandMixin<TypeEnum> { public:
ActionPtr action;
};
using ActionCommand = ActionCommandBase<CommandType::Action>;
class RegisterCommand : public CommandMixin<CommandType::Register> { public:
RegisterCommand(std::string_view module_name, const Var& var)
: module_name(module_name), var(var) {}
std::string module_name;
Var var;
};
class AssertReturnCommand : public CommandMixin<CommandType::AssertReturn> { public:
ActionPtr action;
ExpectationPtr expected;
};
template <CommandType TypeEnum> class AssertTrapCommandBase : public CommandMixin<TypeEnum> { public:
ActionPtr action;
std::string text;
};
using AssertTrapCommand = AssertTrapCommandBase<CommandType::AssertTrap>; using AssertExhaustionCommand =
AssertTrapCommandBase<CommandType::AssertExhaustion>;
template <CommandType TypeEnum> class AssertModuleCommand : public CommandMixin<TypeEnum> { public:
std::unique_ptr<ScriptModule> module;
std::string text;
};
using AssertMalformedCommand =
AssertModuleCommand<CommandType::AssertMalformed>; using AssertInvalidCommand = AssertModuleCommand<CommandType::AssertInvalid>; using AssertUnlinkableCommand =
AssertModuleCommand<CommandType::AssertUnlinkable>; using AssertUninstantiableCommand =
AssertModuleCommand<CommandType::AssertUninstantiable>;
class AssertExceptionCommand
: public CommandMixin<CommandType::AssertException> { public:
ActionPtr action;
};
using CommandPtr = std::unique_ptr<Command>; using CommandPtrVector = std::vector<CommandPtr>;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.