summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/asmjs/asm_v_wasm.cpp4
-rw-r--r--src/binaryen-c.cpp7
-rw-r--r--src/passes/Asyncify.cpp15
-rw-r--r--src/passes/DeadArgumentElimination.cpp2
-rw-r--r--src/passes/FuncCastEmulation.cpp6
-rw-r--r--src/passes/I64ToI32Lowering.cpp2
-rw-r--r--src/passes/LegalizeJSInterface.cpp16
-rw-r--r--src/passes/Print.cpp32
-rw-r--r--src/shell-interface.h8
-rw-r--r--src/tools/execution-results.h2
-rw-r--r--src/tools/fuzzing.h23
-rw-r--r--src/tools/js-wrapper.h2
-rw-r--r--src/tools/spec-wrapper.h2
-rw-r--r--src/tools/wasm-shell.cpp2
-rw-r--r--src/tools/wasm2c-wrapper.h11
-rw-r--r--src/wasm-builder.h2
-rw-r--r--src/wasm-interpreter.h8
-rw-r--r--src/wasm-type.h59
-rw-r--r--src/wasm/literal.cpp2
-rw-r--r--src/wasm/wasm-binary.cpp18
-rw-r--r--src/wasm/wasm-emscripten.cpp21
-rw-r--r--src/wasm/wasm-s-parser.cpp6
-rw-r--r--src/wasm/wasm-stack.cpp9
-rw-r--r--src/wasm/wasm-type.cpp63
-rw-r--r--src/wasm/wasm-validator.cpp57
-rw-r--r--src/wasm/wasm.cpp4
26 files changed, 200 insertions, 183 deletions
diff --git a/src/asmjs/asm_v_wasm.cpp b/src/asmjs/asm_v_wasm.cpp
index 75fc0506b..fca6284c6 100644
--- a/src/asmjs/asm_v_wasm.cpp
+++ b/src/asmjs/asm_v_wasm.cpp
@@ -104,8 +104,8 @@ std::string getSig(Type results, Type params) {
assert(!results.isMulti());
std::string sig;
sig += getSig(results);
- for (Type t : params.expand()) {
- sig += getSig(t);
+ for (auto& param : params) {
+ sig += getSig(param);
}
return sig;
}
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index 2201f97bd..4d057d614 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -150,9 +150,10 @@ BinaryenType BinaryenTypeCreate(BinaryenType* types, uint32_t numTypes) {
uint32_t BinaryenTypeArity(BinaryenType t) { return Type(t).size(); }
void BinaryenTypeExpand(BinaryenType t, BinaryenType* buf) {
- const std::vector<Type>& types = Type(t).expand();
- for (size_t i = 0; i < types.size(); ++i) {
- buf[i] = types[i].getID();
+ Type types(t);
+ size_t i = 0;
+ for (auto& type : types) {
+ buf[i++] = type.getID();
}
}
diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp
index 2aca16942..1bbc89435 100644
--- a/src/passes/Asyncify.cpp
+++ b/src/passes/Asyncify.cpp
@@ -1304,10 +1304,9 @@ private:
if (!relevantLiveLocals.count(i)) {
continue;
}
- const auto& types = func->getLocalType(i).expand();
+ auto localType = func->getLocalType(i);
SmallVector<Expression*, 1> loads;
- for (Index j = 0; j < types.size(); j++) {
- auto type = types[j];
+ for (auto& type : localType) {
auto size = type.getByteSize();
assert(size % STACK_ALIGN == 0);
// TODO: higher alignment?
@@ -1323,7 +1322,7 @@ private:
Expression* load;
if (loads.size() == 1) {
load = loads[0];
- } else if (types.size() > 1) {
+ } else if (localType.size() > 1) {
load = builder->makeTupleMake(std::move(loads));
} else {
WASM_UNREACHABLE("Unexpected empty type");
@@ -1350,12 +1349,11 @@ private:
continue;
}
auto localType = func->getLocalType(i);
- const auto& types = localType.expand();
- for (Index j = 0; j < types.size(); j++) {
- auto type = types[j];
+ size_t j = 0;
+ for (auto& type : localType) {
auto size = type.getByteSize();
Expression* localGet = builder->makeLocalGet(i, localType);
- if (types.size() > 1) {
+ if (localType.size() > 1) {
localGet = builder->makeTupleExtract(localGet, j);
}
assert(size % STACK_ALIGN == 0);
@@ -1368,6 +1366,7 @@ private:
localGet,
type));
offset += size;
+ ++j;
}
}
block->list.push_back(builder->makeIncStackPos(offset));
diff --git a/src/passes/DeadArgumentElimination.cpp b/src/passes/DeadArgumentElimination.cpp
index a20ff1fb8..9fed4f1dc 100644
--- a/src/passes/DeadArgumentElimination.cpp
+++ b/src/passes/DeadArgumentElimination.cpp
@@ -409,7 +409,7 @@ private:
// Remove the parameter from the function. We must add a new local
// for uses of the parameter, but cannot make it use the same index
// (in general).
- std::vector<Type> params = func->sig.params.expand();
+ std::vector<Type> params(func->sig.params.begin(), func->sig.params.end());
auto type = params[i];
params.erase(params.begin() + i);
func->sig.params = Type(params);
diff --git a/src/passes/FuncCastEmulation.cpp b/src/passes/FuncCastEmulation.cpp
index 9e455b0c8..a2f47ca90 100644
--- a/src/passes/FuncCastEmulation.cpp
+++ b/src/passes/FuncCastEmulation.cpp
@@ -193,13 +193,13 @@ private:
}
// The item in the table may be a function or a function import.
auto* func = module->getFunction(name);
- const std::vector<Type>& params = func->sig.params.expand();
Type type = func->sig.results;
Builder builder(*module);
std::vector<Expression*> callOperands;
- for (Index i = 0; i < params.size(); i++) {
+ Index i = 0;
+ for (auto& param : func->sig.params) {
callOperands.push_back(
- fromABI(builder.makeLocalGet(i, Type::i64), params[i], module));
+ fromABI(builder.makeLocalGet(i++, Type::i64), param, module));
}
auto* call = builder.makeCall(name, callOperands, type);
std::vector<Type> thunkParams;
diff --git a/src/passes/I64ToI32Lowering.cpp b/src/passes/I64ToI32Lowering.cpp
index f66af87cc..41d0e799a 100644
--- a/src/passes/I64ToI32Lowering.cpp
+++ b/src/passes/I64ToI32Lowering.cpp
@@ -272,7 +272,7 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
visitGenericCall<CallIndirect>(
curr, [&](std::vector<Expression*>& args, Type results) {
std::vector<Type> params;
- for (auto param : curr->sig.params.expand()) {
+ for (auto& param : curr->sig.params) {
if (param == Type::i64) {
params.push_back(Type::i32);
params.push_back(Type::i32);
diff --git a/src/passes/LegalizeJSInterface.cpp b/src/passes/LegalizeJSInterface.cpp
index 659165306..9a4dc6b63 100644
--- a/src/passes/LegalizeJSInterface.cpp
+++ b/src/passes/LegalizeJSInterface.cpp
@@ -183,7 +183,7 @@ private:
std::map<Name, Name> illegalImportsToLegal;
template<typename T> bool isIllegal(T* t) {
- for (auto param : t->sig.params.expand()) {
+ for (auto& param : t->sig.params) {
if (param == Type::i64) {
return true;
}
@@ -222,9 +222,8 @@ private:
call->target = func->name;
call->type = func->sig.results;
- const std::vector<Type>& params = func->sig.params.expand();
std::vector<Type> legalParams;
- for (auto param : params) {
+ for (auto& param : func->sig.params) {
if (param == Type::i64) {
call->operands.push_back(I64Utilities::recreateI64(
builder, legalParams.size(), legalParams.size() + 1));
@@ -277,18 +276,19 @@ private:
auto* call = module->allocator.alloc<Call>();
call->target = legalIm->name;
- const std::vector<Type>& imParams = im->sig.params.expand();
std::vector<Type> params;
- for (size_t i = 0; i < imParams.size(); ++i) {
- if (imParams[i] == Type::i64) {
+ Index i = 0;
+ for (auto& param : im->sig.params) {
+ if (param == Type::i64) {
call->operands.push_back(I64Utilities::getI64Low(builder, i));
call->operands.push_back(I64Utilities::getI64High(builder, i));
params.push_back(Type::i32);
params.push_back(Type::i32);
} else {
- call->operands.push_back(builder.makeLocalGet(i, imParams[i]));
- params.push_back(imParams[i]);
+ call->operands.push_back(builder.makeLocalGet(i, param));
+ params.push_back(param);
}
+ ++i;
}
if (im->sig.results == Type::i64) {
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index d90e7f958..ba4e022e0 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -67,15 +67,16 @@ struct SExprType {
static std::ostream& operator<<(std::ostream& o, const SExprType& localType) {
Type type = localType.type;
if (type.isMulti()) {
- const std::vector<Type>& types = type.expand();
- o << '(' << types[0];
- for (size_t i = 1; i < types.size(); ++i) {
- o << ' ' << types[i];
+ o << '(';
+ auto sep = "";
+ for (auto& t : type) {
+ o << sep << t;
+ sep = " ";
}
o << ')';
- return o;
+ } else {
+ o << type;
}
- o << type;
return o;
}
@@ -90,12 +91,10 @@ std::ostream& operator<<(std::ostream& os, SigName sigName) {
if (type == Type::none) {
os << "none";
} else {
- const std::vector<Type>& types = type.expand();
- for (size_t i = 0; i < types.size(); ++i) {
- if (i != 0) {
- os << '_';
- }
- os << types[i];
+ auto sep = "";
+ for (auto& t : type) {
+ os << sep << t;
+ sep = "_";
}
}
};
@@ -2169,14 +2168,15 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> {
if (!printStackIR && curr->stackIR && !minify) {
o << " (; has Stack IR ;)";
}
- const std::vector<Type>& params = curr->sig.params.expand();
- if (params.size() > 0) {
- for (size_t i = 0; i < params.size(); i++) {
+ if (curr->sig.params.size() > 0) {
+ Index i = 0;
+ for (auto& param : curr->sig.params) {
o << maybeSpace;
o << '(';
printMinor(o, "param ");
printLocal(i, currFunction, o);
- o << ' ' << params[i] << ')';
+ o << ' ' << param << ')';
+ ++i;
}
}
if (curr->sig.results != Type::none) {
diff --git a/src/shell-interface.h b/src/shell-interface.h
index 963832fed..0667e43a1 100644
--- a/src/shell-interface.h
+++ b/src/shell-interface.h
@@ -165,12 +165,12 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface {
if (sig != func->sig) {
trap("callIndirect: function signatures don't match");
}
- const std::vector<Type>& params = func->sig.params.expand();
- if (params.size() != arguments.size()) {
+ if (func->sig.params.size() != arguments.size()) {
trap("callIndirect: bad # of arguments");
}
- for (size_t i = 0; i < params.size(); i++) {
- if (!Type::isSubType(arguments[i].type, params[i])) {
+ size_t i = 0;
+ for (auto& param : func->sig.params) {
+ if (!Type::isSubType(arguments[i++].type, param)) {
trap("callIndirect: bad argument type");
}
}
diff --git a/src/tools/execution-results.h b/src/tools/execution-results.h
index e5d4dab00..dc62bba38 100644
--- a/src/tools/execution-results.h
+++ b/src/tools/execution-results.h
@@ -144,7 +144,7 @@ struct ExecutionResults {
instance.callFunction(ex->value, arguments);
}
// call the method
- for (Type param : func->sig.params.expand()) {
+ for (auto& param : func->sig.params) {
// zeros in arguments TODO: more?
arguments.push_back(Literal::makeSingleZero(param));
}
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index 7fef9c208..c76b6e13a 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -308,7 +308,7 @@ private:
Type getSubType(Type type) {
if (type.isMulti()) {
std::vector<Type> types;
- for (auto t : type.expand()) {
+ for (auto& t : type) {
types.push_back(getSubType(t));
}
return Type(types);
@@ -770,7 +770,7 @@ private:
std::vector<Expression*> invocations;
while (oneIn(2) && !finishedInput) {
std::vector<Expression*> args;
- for (auto type : func->sig.params.expand()) {
+ for (auto& type : func->sig.params) {
args.push_back(makeConst(type));
}
Expression* invoke =
@@ -1166,7 +1166,7 @@ private:
}
// we found one!
std::vector<Expression*> args;
- for (auto argType : target->sig.params.expand()) {
+ for (auto& argType : target->sig.params) {
args.push_back(make(argType));
}
return builder.makeCall(target->name, args, type, isReturn);
@@ -1210,7 +1210,7 @@ private:
target = make(Type::i32);
}
std::vector<Expression*> args;
- for (auto type : targetFn->sig.params.expand()) {
+ for (auto& type : targetFn->sig.params) {
args.push_back(make(type));
}
return builder.makeCallIndirect(target, args, targetFn->sig, isReturn);
@@ -1267,7 +1267,7 @@ private:
assert(wasm.features.hasMultivalue());
assert(type.isMulti());
std::vector<Expression*> elements;
- for (auto t : type.expand()) {
+ for (auto& t : type) {
elements.push_back(make(t));
}
return builder.makeTupleMake(std::move(elements));
@@ -1277,20 +1277,21 @@ private:
assert(wasm.features.hasMultivalue());
assert(type.isSingle() && type.isConcrete());
Type tupleType = getTupleType();
- auto& elements = tupleType.expand();
// Find indices from which we can extract `type`
std::vector<size_t> extractIndices;
- for (size_t i = 0; i < elements.size(); ++i) {
- if (elements[i] == type) {
+ size_t i = 0;
+ for (auto& t : tupleType) {
+ if (t == type) {
extractIndices.push_back(i);
}
+ ++i;
}
// If there are none, inject one
if (extractIndices.size() == 0) {
- auto newElements = elements;
- size_t injected = upTo(elements.size());
+ std::vector<Type> newElements(tupleType.begin(), tupleType.end());
+ size_t injected = upTo(newElements.size());
newElements[injected] = type;
tupleType = Type(newElements);
extractIndices.push_back(injected);
@@ -1766,7 +1767,7 @@ private:
}
if (type.isMulti()) {
std::vector<Expression*> operands;
- for (auto t : type.expand()) {
+ for (auto& t : type) {
operands.push_back(makeConst(t));
}
return builder.makeTupleMake(std::move(operands));
diff --git a/src/tools/js-wrapper.h b/src/tools/js-wrapper.h
index 0a9b5925e..58e52b782 100644
--- a/src/tools/js-wrapper.h
+++ b/src/tools/js-wrapper.h
@@ -99,7 +99,7 @@ static std::string generateJSWrapper(Module& wasm) {
}
ret += std::string("instance.exports.") + exp->name.str + "(";
bool first = true;
- for (Type param : func->sig.params.expand()) {
+ for (auto& param : func->sig.params) {
// zeros in arguments TODO more?
if (first) {
first = false;
diff --git a/src/tools/spec-wrapper.h b/src/tools/spec-wrapper.h
index 3a674e495..513cc8bda 100644
--- a/src/tools/spec-wrapper.h
+++ b/src/tools/spec-wrapper.h
@@ -30,7 +30,7 @@ static std::string generateSpecWrapper(Module& wasm) {
}
ret += std::string("(invoke \"hangLimitInitializer\") (invoke \"") +
exp->name.str + "\" ";
- for (Type param : func->sig.params.expand()) {
+ for (auto& param : func->sig.params) {
// zeros in arguments TODO more?
TODO_SINGLE_COMPOUND(param);
switch (param.getBasic()) {
diff --git a/src/tools/wasm-shell.cpp b/src/tools/wasm-shell.cpp
index 1430c1891..1093ff85c 100644
--- a/src/tools/wasm-shell.cpp
+++ b/src/tools/wasm-shell.cpp
@@ -111,7 +111,7 @@ static void run_asserts(Name moduleName,
std::cerr << "Unknown entry " << entry << std::endl;
} else {
LiteralList arguments;
- for (Type param : function->sig.params.expand()) {
+ for (auto& param : function->sig.params) {
arguments.push_back(Literal(param));
}
try {
diff --git a/src/tools/wasm2c-wrapper.h b/src/tools/wasm2c-wrapper.h
index eae92ad60..0dd3c4381 100644
--- a/src/tools/wasm2c-wrapper.h
+++ b/src/tools/wasm2c-wrapper.h
@@ -144,7 +144,6 @@ int main(int argc, char** argv) {
// Emit the callee's name with wasm2c name mangling.
ret += std::string("(*Z_") + exp->name.str + "Z_";
- auto params = func->sig.params.expand();
auto wasm2cSignature = [](Type type) {
TODO_SINGLE_COMPOUND(type);
@@ -165,18 +164,18 @@ int main(int argc, char** argv) {
};
ret += wasm2cSignature(result);
- if (params.empty()) {
- ret += wasm2cSignature(Type::none);
- } else {
- for (auto param : params) {
+ if (func->sig.params.isMulti()) {
+ for (auto& param : func->sig.params) {
ret += wasm2cSignature(param);
}
+ } else {
+ ret += wasm2cSignature(func->sig.params);
}
ret += ")(";
// Emit the parameters (all 0s, like the other wrappers).
bool first = true;
- for (auto param : params) {
+ for (auto& param : func->sig.params) {
WASM_UNUSED(param);
if (!first) {
ret += ", ";
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index 9ee98949a..7cf8b4043 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -657,7 +657,7 @@ public:
// only ok to add a param if no vars, otherwise indices are invalidated
assert(func->localIndices.size() == func->sig.params.size());
assert(name.is());
- std::vector<Type> params = func->sig.params.expand();
+ std::vector<Type> params(func->sig.params.begin(), func->sig.params.end());
params.push_back(type);
func->sig.params = Type(params);
Index index = func->localNames.size();
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 4f0d22e58..baeda0612 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1890,14 +1890,12 @@ private:
WASM_UNREACHABLE("invalid param count");
}
locals.resize(function->getNumLocals());
- const std::vector<Type>& params = function->sig.params.expand();
for (size_t i = 0; i < function->getNumLocals(); i++) {
if (i < arguments.size()) {
- assert(i < params.size());
- if (!Type::isSubType(arguments[i].type, params[i])) {
+ if (!Type::isSubType(arguments[i].type, function->sig.params[i])) {
std::cerr << "Function `" << function->name << "` expects type "
- << params[i] << " for parameter " << i << ", got "
- << arguments[i].type << "." << std::endl;
+ << function->sig.params[i] << " for parameter " << i
+ << ", got " << arguments[i].type << "." << std::endl;
WASM_UNREACHABLE("invalid param count");
}
locals[i] = {arguments[i]};
diff --git a/src/wasm-type.h b/src/wasm-type.h
index 31c915620..29b251eeb 100644
--- a/src/wasm-type.h
+++ b/src/wasm-type.h
@@ -67,10 +67,6 @@ public:
Type(std::initializer_list<Type> types);
explicit Type(const std::vector<Type>& types);
- // Accessors
- size_t size() const;
- const std::vector<Type>& expand() const;
-
// Predicates
// Compound Concrete
// Type Basic │ Single│
@@ -116,8 +112,8 @@ public:
private:
template<bool (Type::*pred)() const> bool hasPredicate() {
- for (auto t : expand()) {
- if ((t.*pred)()) {
+ for (auto& type : *this) {
+ if ((type.*pred)()) {
return true;
}
}
@@ -177,6 +173,57 @@ public:
}
std::string toString() const;
+
+ struct Iterator
+ : std::iterator<std::random_access_iterator_tag, Type, long, Type*, Type&> {
+ const Type* parent;
+ size_t index;
+ Iterator(const Type* parent, size_t index) : parent(parent), index(index) {}
+ bool operator==(const Iterator& other) const {
+ return index == other.index && parent == other.parent;
+ }
+ bool operator!=(const Iterator& other) const { return !(*this == other); }
+ void operator++() { index++; }
+ Iterator& operator+=(difference_type off) {
+ index += off;
+ return *this;
+ }
+ const Iterator operator+(difference_type off) const {
+ return Iterator(*this) += off;
+ }
+ difference_type operator-(const Iterator& other) {
+ assert(parent == other.parent);
+ return index - other.index;
+ }
+ const value_type& operator*() const {
+ if (parent->isMulti()) {
+ return (*(std::vector<Type>*)parent->getID())[index];
+ } else {
+ // see TODO in Type::end()
+ assert(index == 0 && parent->id != Type::none && "Index out of bounds");
+ return *parent;
+ }
+ }
+ };
+
+ Iterator begin() const { return Iterator(this, 0); }
+ Iterator end() const {
+ if (isMulti()) {
+ return Iterator(this, (*(std::vector<Type>*)getID()).size());
+ } else {
+ // TODO: unreachable is special and expands to {unreachable} currently.
+ // see also: https://github.com/WebAssembly/binaryen/issues/3062
+ return Iterator(this, size_t(id != Type::none));
+ }
+ }
+ size_t size() const { return end() - begin(); }
+ const Type& operator[](size_t i) const {
+ if (isMulti()) {
+ return (*(std::vector<Type>*)getID())[i];
+ } else {
+ return *begin();
+ }
+ }
};
// Wrapper type for formatting types as "(param i32 i64 f32)"
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index 699d3ea63..11130bc18 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -102,7 +102,7 @@ Literal::Literal(const LaneArray<2>& lanes) : type(Type::v128) {
Literals Literal::makeZero(Type type) {
assert(type.isConcrete());
Literals zeroes;
- for (auto t : type.expand()) {
+ for (auto& t : type) {
zeroes.push_back(makeSingleZero(t));
}
return zeroes;
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index ddc4de36c..285fd578f 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -220,7 +220,7 @@ void WasmBinaryWriter::writeTypes() {
o << S32LEB(BinaryConsts::EncodedType::Func);
for (auto& sigType : {sig.params, sig.results}) {
o << U32LEB(sigType.size());
- for (auto type : sigType.expand()) {
+ for (auto& type : sigType) {
o << binaryType(type);
}
}
@@ -385,16 +385,17 @@ void WasmBinaryWriter::writeGlobals() {
o << U32LEB(num);
ModuleUtils::iterDefinedGlobals(*wasm, [&](Global* global) {
BYN_TRACE("write one\n");
- const auto& types = global->type.expand();
- for (size_t i = 0; i < types.size(); ++i) {
- o << binaryType(types[i]);
+ size_t i = 0;
+ for (auto& t : global->type) {
+ o << binaryType(t);
o << U32LEB(global->mutable_);
- if (types.size() == 1) {
+ if (global->type.size() == 1) {
writeExpression(global->init);
} else {
writeExpression(global->init->cast<TupleMake>()->operands[i]);
}
o << int8_t(BinaryConsts::End);
+ ++i;
}
});
finishSection(start);
@@ -1385,7 +1386,9 @@ void WasmBinaryBuilder::readImports() {
wasm.addEvent(curr);
break;
}
- default: { throwError("bad import kind"); }
+ default: {
+ throwError("bad import kind");
+ }
}
}
}
@@ -1795,8 +1798,7 @@ void WasmBinaryBuilder::pushExpression(Expression* curr) {
Builder builder(wasm);
Index tuple = builder.addVar(currFunction, curr->type);
expressionStack.push_back(builder.makeLocalSet(tuple, curr));
- const std::vector<Type> types = curr->type.expand();
- for (Index i = 0; i < types.size(); ++i) {
+ for (Index i = 0; i < curr->type.size(); ++i) {
expressionStack.push_back(
builder.makeTupleExtract(builder.makeLocalGet(tuple, curr->type), i));
}
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp
index f4da0e6e7..48cf4b6f1 100644
--- a/src/wasm/wasm-emscripten.cpp
+++ b/src/wasm/wasm-emscripten.cpp
@@ -154,15 +154,15 @@ void EmscriptenGlueGenerator::generateDynCallThunk(Signature sig) {
std::vector<NameType> params;
params.emplace_back("fptr", Type::i32); // function pointer param
int p = 0;
- const std::vector<Type>& paramTypes = sig.params.expand();
- for (const auto& ty : paramTypes) {
- params.emplace_back(std::to_string(p++), ty);
+ for (auto& param : sig.params) {
+ params.emplace_back(std::to_string(p++), param);
}
Function* f = builder.makeFunction(name, std::move(params), sig.results, {});
Expression* fptr = builder.makeLocalGet(0, Type::i32);
std::vector<Expression*> args;
- for (unsigned i = 0; i < paramTypes.size(); ++i) {
- args.push_back(builder.makeLocalGet(i + 1, paramTypes[i]));
+ Index i = 0;
+ for (auto& param : sig.params) {
+ args.push_back(builder.makeLocalGet(++i, param));
}
Expression* call = builder.makeCallIndirect(fptr, args, sig);
f->body = call;
@@ -493,12 +493,12 @@ AsmConstWalker::AsmConst& AsmConstWalker::createAsmConst(uint32_t id,
}
Signature AsmConstWalker::asmConstSig(Signature baseSig) {
- std::vector<Type> params = baseSig.params.expand();
- assert(params.size() >= 1);
+ assert(baseSig.params.size() >= 1);
// Omit the signature of the "code" parameter, taken as a string, as the
// first argument
- params.erase(params.begin());
- return Signature(Type(params), baseSig.results);
+ return Signature(
+ Type(std::vector<Type>(baseSig.params.begin() + 1, baseSig.params.end())),
+ baseSig.results);
}
Name AsmConstWalker::nameForImportWithSig(Signature sig, Proxying proxy) {
@@ -662,8 +662,7 @@ struct FixInvokeFunctionNamesWalker
return name;
}
- const std::vector<Type>& params = sig.params.expand();
- std::vector<Type> newParams(params.begin() + 1, params.end());
+ std::vector<Type> newParams(sig.params.begin() + 1, sig.params.end());
Signature sigWoOrigFunc = Signature(Type(newParams), sig.results);
invokeSigs.insert(sigWoOrigFunc);
return Name("invoke_" +
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 5e6008bca..15ec266b3 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -640,9 +640,9 @@ SExpressionWasmBuilder::parseTypeUse(Element& s,
// If only (type) is specified, populate `namedParams`
if (!paramsOrResultsExist) {
- const std::vector<Type>& funcParams = functionSignature.params.expand();
- for (size_t index = 0, e = funcParams.size(); index < e; index++) {
- namedParams.emplace_back(Name::fromInt(index), funcParams[index]);
+ size_t index = 0;
+ for (auto& param : functionSignature.params) {
+ namedParams.emplace_back(Name::fromInt(index++), param);
}
}
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 19a4590e3..e64e330e8 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -1808,17 +1808,16 @@ void BinaryInstWriter::mapLocalsAndEmitHeader() {
return;
}
for (auto type : func->vars) {
- for (auto t : type.expand()) {
+ for (auto& t : type) {
numLocalsByType[t]++;
}
}
countScratchLocals();
std::map<Type, size_t> currLocalsByType;
for (Index i = func->getVarIndexBase(); i < func->getNumLocals(); i++) {
- const std::vector<Type> types = func->getLocalType(i).expand();
- for (Index j = 0; j < types.size(); j++) {
- Type type = types[j];
- auto fullIndex = std::make_pair(i, j);
+ Index j = 0;
+ for (auto& type : func->getLocalType(i)) {
+ auto fullIndex = std::make_pair(i, j++);
Index index = func->getVarIndexBase();
for (auto& typeCount : numLocalsByType) {
if (type == typeCount.first) {
diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp
index 5db04b40d..6e887d742 100644
--- a/src/wasm/wasm-type.cpp
+++ b/src/wasm/wasm-type.cpp
@@ -56,19 +56,6 @@ namespace {
std::mutex mutex;
-std::array<std::vector<Type>, Type::_last_value_type + 1> basicTypes = {
- {{},
- {Type::unreachable},
- {Type::i32},
- {Type::i64},
- {Type::f32},
- {Type::f64},
- {Type::v128},
- {Type::funcref},
- {Type::externref},
- {Type::nullref},
- {Type::exnref}}};
-
// Track unique_ptrs for constructed types to avoid leaks
std::vector<std::unique_ptr<std::vector<Type>>> constructedTypes;
@@ -123,23 +110,11 @@ Type::Type(std::initializer_list<Type> types) { init(types); }
Type::Type(const std::vector<Type>& types) { init(types); }
-size_t Type::size() const { return expand().size(); }
-
-const std::vector<Type>& Type::expand() const {
- if (id <= _last_value_type) {
- return basicTypes[id];
- } else {
- return *(std::vector<Type>*)id;
- }
-}
-
bool Type::operator<(const Type& other) const {
- const std::vector<Type>& these = expand();
- const std::vector<Type>& others = other.expand();
- return std::lexicographical_compare(these.begin(),
- these.end(),
- others.begin(),
- others.end(),
+ return std::lexicographical_compare((*this).begin(),
+ (*this).end(),
+ other.begin(),
+ other.end(),
[](const Type& a, const Type& b) {
TODO_SINGLE_COMPOUND(a);
TODO_SINGLE_COMPOUND(b);
@@ -172,7 +147,7 @@ unsigned Type::getByteSize() const {
if (isMulti()) {
unsigned size = 0;
- for (auto t : expand()) {
+ for (auto& t : *this) {
size += getSingleByteSize(t);
}
return size;
@@ -181,7 +156,7 @@ unsigned Type::getByteSize() const {
}
Type Type::reinterpret() const {
- Type singleType = *expand().begin();
+ auto singleType = *(*this).begin();
switch (singleType.getBasic()) {
case Type::i32:
return f32;
@@ -222,7 +197,7 @@ FeatureSet Type::getFeatures() const {
if (isMulti()) {
FeatureSet feats = FeatureSet::Multivalue;
- for (Type t : expand()) {
+ for (auto& t : *this) {
feats |= getSingleFeatures(t);
}
return feats;
@@ -255,13 +230,11 @@ bool Type::isSubType(Type left, Type right) {
return true;
}
if (left.isMulti() && right.isMulti()) {
- const auto& leftElems = left.expand();
- const auto& rightElems = right.expand();
- if (leftElems.size() != rightElems.size()) {
+ if (left.size() != right.size()) {
return false;
}
- for (size_t i = 0; i < leftElems.size(); ++i) {
- if (!isSubType(leftElems[i], rightElems[i])) {
+ for (size_t i = 0; i < left.size(); ++i) {
+ if (!isSubType(left[i], right[i])) {
return false;
}
}
@@ -286,10 +259,8 @@ Type Type::getLeastUpperBound(Type a, Type b) {
if (a.isMulti()) {
std::vector<Type> types;
types.resize(a.size());
- const auto& as = a.expand();
- const auto& bs = b.expand();
for (size_t i = 0; i < types.size(); ++i) {
- types[i] = getLeastUpperBound(as[i], bs[i]);
+ types[i] = getLeastUpperBound(a[i], b[i]);
if (types[i] == Type::none) {
return Type::none;
}
@@ -313,7 +284,7 @@ namespace {
std::ostream&
printPrefixedTypes(std::ostream& os, const char* prefix, Type type) {
os << '(' << prefix;
- for (auto t : type.expand()) {
+ for (auto& t : type) {
os << " " << t;
}
os << ')';
@@ -347,12 +318,10 @@ bool Signature::operator<(const Signature& other) const {
std::ostream& operator<<(std::ostream& os, Type type) {
if (type.isMulti()) {
os << '(';
- const std::vector<Type>& types = type.expand();
- for (size_t i = 0; i < types.size(); ++i) {
- os << types[i];
- if (i < types.size() - 1) {
- os << ", ";
- }
+ auto sep = "";
+ for (auto& t : type) {
+ os << sep << t;
+ sep = ", ";
}
os << ')';
} else {
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 4921dafdd..1ff04906e 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -641,20 +641,21 @@ void FunctionValidator::visitCall(Call* curr) {
if (!shouldBeTrue(!!target, curr, "call target must exist")) {
return;
}
- const std::vector<Type> params = target->sig.params.expand();
- if (!shouldBeTrue(curr->operands.size() == params.size(),
+ if (!shouldBeTrue(curr->operands.size() == target->sig.params.size(),
curr,
"call param number must match")) {
return;
}
- for (size_t i = 0; i < curr->operands.size(); i++) {
+ size_t i = 0;
+ for (auto& param : target->sig.params) {
if (!shouldBeSubTypeOrFirstIsUnreachable(curr->operands[i]->type,
- params[i],
+ param,
curr,
"call param types must match") &&
!info.quiet) {
getStream() << "(on argument " << i << ")\n";
}
+ ++i;
}
if (curr->isReturn) {
shouldBeEqual(curr->type,
@@ -692,24 +693,25 @@ void FunctionValidator::visitCallIndirect(CallIndirect* curr) {
if (!info.validateGlobally) {
return;
}
- const std::vector<Type>& params = curr->sig.params.expand();
shouldBeEqualOrFirstIsUnreachable(curr->target->type,
Type(Type::i32),
curr,
"indirect call target must be an i32");
- if (!shouldBeTrue(curr->operands.size() == params.size(),
+ if (!shouldBeTrue(curr->operands.size() == curr->sig.params.size(),
curr,
"call param number must match")) {
return;
}
- for (size_t i = 0; i < curr->operands.size(); i++) {
+ size_t i = 0;
+ for (auto& param : curr->sig.params) {
if (!shouldBeSubTypeOrFirstIsUnreachable(curr->operands[i]->type,
- params[i],
+ param,
curr,
"call param types must match") &&
!info.quiet) {
getStream() << "(on argument " << i << ")\n";
}
+ ++i;
}
if (curr->isReturn) {
shouldBeEqual(curr->type,
@@ -1871,15 +1873,16 @@ void FunctionValidator::visitThrow(Throw* curr) {
"event's param numbers must match")) {
return;
}
- const std::vector<Type>& paramTypes = event->sig.params.expand();
- for (size_t i = 0; i < curr->operands.size(); i++) {
+ size_t i = 0;
+ for (auto& param : event->sig.params) {
if (!shouldBeSubTypeOrFirstIsUnreachable(curr->operands[i]->type,
- paramTypes[i],
+ param,
curr->operands[i],
"event param types must match") &&
!info.quiet) {
getStream() << "(on argument " << i << ")\n";
}
+ ++i;
}
}
@@ -1957,7 +1960,7 @@ void FunctionValidator::visitTupleExtract(TupleExtract* curr) {
shouldBeTrue(inBounds, curr, "tuple.extract index out of bounds");
if (inBounds) {
shouldBeSubType(
- curr->tuple->type.expand()[curr->index],
+ curr->tuple->type[curr->index],
curr->type,
curr,
"tuple.extract type does not match the type of the extracted element");
@@ -1972,17 +1975,17 @@ void FunctionValidator::visitFunction(Function* curr) {
"Multivalue function results (multivalue is not enabled)");
}
FeatureSet features;
- for (auto type : curr->sig.params.expand()) {
- features |= type.getFeatures();
- shouldBeTrue(type.isConcrete(), curr, "params must be concretely typed");
+ for (auto& param : curr->sig.params) {
+ features |= param.getFeatures();
+ shouldBeTrue(param.isConcrete(), curr, "params must be concretely typed");
}
- for (auto type : curr->sig.results.expand()) {
- features |= type.getFeatures();
- shouldBeTrue(type.isConcrete(), curr, "results must be concretely typed");
+ for (auto& result : curr->sig.results) {
+ features |= result.getFeatures();
+ shouldBeTrue(result.isConcrete(), curr, "results must be concretely typed");
}
- for (auto type : curr->vars) {
- features |= type.getFeatures();
- shouldBeTrue(type.isConcrete(), curr, "vars must be concretely typed");
+ for (auto& var : curr->vars) {
+ features |= var.getFeatures();
+ shouldBeTrue(var.isConcrete(), curr, "vars must be concretely typed");
}
shouldBeTrue(features <= getModule()->features,
curr,
@@ -2141,13 +2144,13 @@ static void validateImports(Module& module, ValidationInfo& info) {
"(multivalue is not enabled)");
}
if (info.validateWeb) {
- for (Type param : curr->sig.params.expand()) {
+ for (auto& param : curr->sig.params) {
info.shouldBeUnequal(param,
Type(Type::i64),
curr->name,
"Imported function must not have i64 parameters");
}
- for (Type result : curr->sig.results.expand()) {
+ for (auto& result : curr->sig.results) {
info.shouldBeUnequal(result,
Type(Type::i64),
curr->name,
@@ -2170,14 +2173,14 @@ static void validateExports(Module& module, ValidationInfo& info) {
if (curr->kind == ExternalKind::Function) {
if (info.validateWeb) {
Function* f = module.getFunction(curr->value);
- for (auto param : f->sig.params.expand()) {
+ for (auto& param : f->sig.params) {
info.shouldBeUnequal(
param,
Type(Type::i64),
f->name,
"Exported function must not have i64 parameters");
}
- for (auto result : f->sig.results.expand()) {
+ for (auto& result : f->sig.results) {
info.shouldBeUnequal(result,
Type(Type::i64),
f->name,
@@ -2349,8 +2352,8 @@ static void validateEvents(Module& module, ValidationInfo& info) {
curr->name,
"Multivalue event type (multivalue is not enabled)");
}
- for (auto type : curr->sig.params.expand()) {
- info.shouldBeTrue(type.isConcrete(),
+ for (auto& param : curr->sig.params) {
+ info.shouldBeTrue(param.isConcrete(),
curr->name,
"Values in an event should have concrete types");
}
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index be3ab6ccc..387ea577f 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -948,7 +948,7 @@ void TupleExtract::finalize() {
if (tuple->type == Type::unreachable) {
type = Type::unreachable;
} else {
- type = tuple->type.expand()[index];
+ type = tuple->type[index];
}
}
@@ -1006,7 +1006,7 @@ Index Function::getVarIndexBase() { return sig.params.size(); }
Type Function::getLocalType(Index index) {
auto numParams = sig.params.size();
if (index < numParams) {
- return sig.params.expand()[index];
+ return sig.params[index];
} else if (isVar(index)) {
return vars[index - numParams];
} else {