diff options
Diffstat (limited to 'src/wasm.h')
-rw-r--r-- | src/wasm.h | 155 |
1 files changed, 89 insertions, 66 deletions
diff --git a/src/wasm.h b/src/wasm.h index ee2f27388..62b551433 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -723,9 +723,14 @@ enum HostOp { // x->name = a; // x->leftOperand = b; // .. -// which is less compact but less ambiguous. But hopefully we can do better, -// suggestions for API improvements here are welcome. +// which is less compact but less ambiguous. See wasm-builder.h for a more +// friendly API for building nodes. // +// Most nodes have no need of internal allocation, and when arena-allocated +// they drop the provided arena on the floor. You can create random instances +// of those that are not in an arena without issue. However, the nodes that +// have internal allocation will need an allocator provided to them in order +// to be constructed. class Expression { public: @@ -757,22 +762,21 @@ public: WasmType type; // the type of the expression: its *output*, not necessarily its input(s) - Expression() : _id(InvalidId), type(none) {} Expression(Id id) : _id(id), type(none) {} - + template<class T> bool is() { - return _id == T()._id; + return int(_id) == int(T::SpecificId); } template<class T> T* dynCast() { - return _id == T()._id ? (T*)this : nullptr; + return int(_id) == int(T::SpecificId) ? (T*)this : nullptr; } template<class T> T* cast() { - assert(_id == T()._id); + assert(int(_id) == int(T::SpecificId)); return (T*)this; } }; @@ -804,18 +808,27 @@ inline const char *getExpressionName(Expression *curr) { } } -typedef std::vector<Expression*> ExpressionList; // TODO: optimize? +typedef ArenaVector<Expression*> ExpressionList; -class Nop : public Expression { +template<Expression::Id SID> +class SpecificExpression : public Expression { public: - Nop() : Expression(NopId) {} + enum { + SpecificId = SID // compile-time access to the type for the class + }; + + SpecificExpression() : Expression(SID) {} }; -class Block : public Expression { +class Nop : public SpecificExpression<Expression::NopId> { public: - Block() : Expression(BlockId) { - type = none; // blocks by default do not return, but if their last statement does, they might - } + Nop() {} + Nop(MixedArena& allocator) {} +}; + +class Block : public SpecificExpression<Expression::BlockId> { +public: + Block(MixedArena& allocator) : list(allocator) {} Name name; ExpressionList list; @@ -827,11 +840,10 @@ public: } }; -class If : public Expression { +class If : public SpecificExpression<Expression::IfId> { public: - If() : Expression(IfId), ifFalse(nullptr) { - type = none; // by default none; if-else can have one, though - } + If() : ifFalse(nullptr) {} + If(MixedArena& allocator) : If() {} Expression *condition, *ifTrue, *ifFalse; @@ -842,9 +854,10 @@ public: } }; -class Loop : public Expression { +class Loop : public SpecificExpression<Expression::LoopId> { public: - Loop() : Expression(LoopId) {} + Loop() {} + Loop(MixedArena& allocator) {} Name out, in; Expression *body; @@ -854,9 +867,10 @@ public: } }; -class Break : public Expression { +class Break : public SpecificExpression<Expression::BreakId> { public: - Break() : Expression(BreakId), value(nullptr), condition(nullptr) { + Break() : value(nullptr), condition(nullptr) {} + Break(MixedArena& allocator) : Break() { type = unreachable; } @@ -865,9 +879,10 @@ public: Expression *condition; }; -class Switch : public Expression { +class Switch : public SpecificExpression<Expression::SwitchId> { public: - Switch() : Expression(SwitchId), condition(nullptr), value(nullptr) { + Switch() : condition(nullptr), value(nullptr) {} + Switch(MixedArena& allocator) : Switch() { type = unreachable; } @@ -877,34 +892,29 @@ public: Expression *value; }; -class CallBase : public Expression { +class Call : public SpecificExpression<Expression::CallId> { public: - CallBase(Id which) : Expression(which) {} + Call(MixedArena& allocator) : operands(allocator) {} ExpressionList operands; + Name target; }; -class Call : public CallBase { +class CallImport : public SpecificExpression<Expression::CallImportId> { public: - Call() : CallBase(CallId) {} + CallImport(MixedArena& allocator) : operands(allocator) {} + ExpressionList operands; Name target; }; -class CallImport : public Call { -public: - CallImport() { - _id = CallImportId; - } -}; - class FunctionType { public: Name name; WasmType result; - std::vector<WasmType> params; + ArenaVector<WasmType> params; - FunctionType() : result(none) {} + FunctionType(MixedArena& allocator) : result(none), params(allocator) {} bool operator==(FunctionType& b) { if (name != b.name) return false; // XXX @@ -920,32 +930,36 @@ public: } }; -class CallIndirect : public CallBase { +class CallIndirect : public SpecificExpression<Expression::CallIndirectId> { public: - CallIndirect() : CallBase(CallIndirectId) {} + CallIndirect(MixedArena& allocator) : operands(allocator) {} + ExpressionList operands; FunctionType *fullType; Expression *target; }; -class GetLocal : public Expression { +class GetLocal : public SpecificExpression<Expression::GetLocalId> { public: - GetLocal() : Expression(GetLocalId) {} + GetLocal() {} + GetLocal(MixedArena& allocator) {} Index index; }; -class SetLocal : public Expression { +class SetLocal : public SpecificExpression<Expression::SetLocalId> { public: - SetLocal() : Expression(SetLocalId) {} + SetLocal() {} + SetLocal(MixedArena& allocator) {} Index index; Expression *value; }; -class Load : public Expression { +class Load : public SpecificExpression<Expression::LoadId> { public: - Load() : Expression(LoadId) {} + Load() {} + Load(MixedArena& allocator) {} uint32_t bytes; bool signed_; @@ -954,9 +968,10 @@ public: Expression *ptr; }; -class Store : public Expression { +class Store : public SpecificExpression<Expression::StoreId> { public: - Store() : Expression(StoreId) {} + Store() {} + Store(MixedArena& allocator) {} unsigned bytes; uint32_t offset; @@ -964,9 +979,10 @@ public: Expression *ptr, *value; }; -class Const : public Expression { +class Const : public SpecificExpression<Expression::ConstId> { public: - Const() : Expression(ConstId) {} + Const() {} + Const(MixedArena& allocator) {} Literal value; @@ -977,9 +993,10 @@ public: } }; -class Unary : public Expression { +class Unary : public SpecificExpression<Expression::UnaryId> { public: - Unary() : Expression(UnaryId) {} + Unary() {} + Unary(MixedArena& allocator) {} UnaryOp op; Expression *value; @@ -989,9 +1006,10 @@ public: // no finalize since some opcodes have more than one type, so user must set it anyhow }; -class Binary : public Expression { +class Binary : public SpecificExpression<Expression::BinaryId> { public: - Binary() : Expression(BinaryId) {} + Binary() {} + Binary(MixedArena& allocator) {} BinaryOp op; Expression *left, *right; @@ -1011,9 +1029,10 @@ public: } }; -class Select : public Expression { +class Select : public SpecificExpression<Expression::SelectId> { public: - Select() : Expression(SelectId) {} + Select() {} + Select(MixedArena& allocator) {} Expression *ifTrue, *ifFalse, *condition; @@ -1022,18 +1041,19 @@ public: } }; -class Return : public Expression { +class Return : public SpecificExpression<Expression::ReturnId> { public: - Expression *value; - - Return() : Expression(ReturnId), value(nullptr) { + Return() : value(nullptr) { type = unreachable; } + Return(MixedArena& allocator) : Return() {} + + Expression *value; }; -class Host : public Expression { +class Host : public SpecificExpression<Expression::HostId> { public: - Host() : Expression(HostId) {} + Host(MixedArena& allocator) : operands(allocator) {} HostOp op; Name nameOperand; @@ -1054,9 +1074,10 @@ public: } }; -class Unreachable : public Expression { +class Unreachable : public SpecificExpression<Expression::UnreachableId> { public: - Unreachable() : Expression(UnreachableId) { + Unreachable() {} + Unreachable(MixedArena& allocator) { type = unreachable; } }; @@ -1076,7 +1097,7 @@ public: std::vector<Name> localNames; std::map<Name, Index> localIndices; - Function() : result(none) {} + Function(MixedArena& allocator) : result(none) {} size_t getNumParams() { return params.size(); @@ -1126,14 +1147,16 @@ public: class Import { public: + Import(MixedArena& allocator) : type(nullptr) {} + Name name, module, base; // name = module.base FunctionType* type; - - Import() : type(nullptr) {} }; class Export { public: + Export(MixedArena& allocator) {} + Name name; // exported name Name value; // internal name }; |