summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/abi/js.h6
-rw-r--r--src/asm2wasm.h290
-rw-r--r--src/binaryen-c.cpp112
-rw-r--r--src/cfg/Relooper.cpp66
-rw-r--r--src/cfg/cfg-traversal.h18
-rw-r--r--src/cfg/liveness-traversal.h27
-rw-r--r--src/dataflow/graph.h45
-rw-r--r--src/dataflow/node.h12
-rw-r--r--src/dataflow/utils.h3
-rw-r--r--src/emscripten-optimizer/istring.h15
-rw-r--r--src/emscripten-optimizer/optimizer-shared.cpp50
-rw-r--r--src/emscripten-optimizer/optimizer.h3
-rw-r--r--src/emscripten-optimizer/parser.h148
-rw-r--r--src/emscripten-optimizer/simple_ast.cpp13
-rw-r--r--src/emscripten-optimizer/simple_ast.h222
-rw-r--r--src/ir/ExpressionAnalyzer.cpp80
-rw-r--r--src/ir/ExpressionManipulator.cpp6
-rw-r--r--src/ir/LocalGraph.cpp12
-rw-r--r--src/ir/ReFinalize.cpp3
-rw-r--r--src/ir/bits.h12
-rw-r--r--src/ir/branch-utils.h41
-rw-r--r--src/ir/cost.h9
-rw-r--r--src/ir/effects.h60
-rw-r--r--src/ir/equivalent_sets.h3
-rw-r--r--src/ir/function-utils.h15
-rw-r--r--src/ir/global-utils.h3
-rw-r--r--src/ir/hashed.h3
-rw-r--r--src/ir/load-utils.h3
-rw-r--r--src/ir/memory-utils.h21
-rw-r--r--src/ir/type-updating.h9
-rw-r--r--src/ir/utils.h9
-rw-r--r--src/literal.h6
-rw-r--r--src/mixed_arena.h9
-rw-r--r--src/parsing.h54
-rw-r--r--src/pass.h3
-rw-r--r--src/passes/CoalesceLocals.cpp21
-rw-r--r--src/passes/CodeFolding.cpp63
-rw-r--r--src/passes/CodePushing.cpp12
-rw-r--r--src/passes/ConstHoisting.cpp3
-rw-r--r--src/passes/DataFlowOpts.cpp9
-rw-r--r--src/passes/DeadArgumentElimination.cpp6
-rw-r--r--src/passes/DeadCodeElimination.cpp9
-rw-r--r--src/passes/Directize.cpp12
-rw-r--r--src/passes/DuplicateFunctionElimination.cpp9
-rw-r--r--src/passes/Flatten.cpp6
-rw-r--r--src/passes/I64ToI32Lowering.cpp66
-rw-r--r--src/passes/Inlining.cpp18
-rw-r--r--src/passes/LegalizeJSInterface.cpp15
-rw-r--r--src/passes/LoopInvariantCodeMotion.cpp6
-rw-r--r--src/passes/MemoryPacking.cpp3
-rw-r--r--src/passes/MergeBlocks.cpp41
-rw-r--r--src/passes/MergeLocals.cpp3
-rw-r--r--src/passes/Metrics.cpp3
-rw-r--r--src/passes/NoExitRuntime.cpp3
-rw-r--r--src/passes/OptimizeInstructions.cpp54
-rw-r--r--src/passes/PostEmscripten.cpp3
-rw-r--r--src/passes/Precompute.cpp18
-rw-r--r--src/passes/Print.cpp42
-rw-r--r--src/passes/PrintCallGraph.cpp3
-rw-r--r--src/passes/ReReloop.cpp3
-rw-r--r--src/passes/RedundantSetElimination.cpp6
-rw-r--r--src/passes/RelooperJumpThreading.cpp27
-rw-r--r--src/passes/RemoveNonJSOps.cpp6
-rw-r--r--src/passes/RemoveUnusedBrs.cpp84
-rw-r--r--src/passes/RemoveUnusedModuleElements.cpp3
-rw-r--r--src/passes/RemoveUnusedNames.cpp9
-rw-r--r--src/passes/ReorderLocals.cpp9
-rw-r--r--src/passes/SSAify.cpp3
-rw-r--r--src/passes/SafeHeap.cpp33
-rw-r--r--src/passes/SimplifyLocals.cpp30
-rw-r--r--src/passes/Souperify.cpp12
-rw-r--r--src/passes/SpillPointers.cpp12
-rw-r--r--src/passes/StackIR.cpp15
-rw-r--r--src/passes/Vacuum.cpp9
-rw-r--r--src/passes/pass.cpp3
-rw-r--r--src/shell-interface.h9
-rw-r--r--src/support/archive.cpp21
-rw-r--r--src/support/colors.cpp3
-rw-r--r--src/support/command-line.cpp18
-rw-r--r--src/support/file.cpp18
-rw-r--r--src/support/json.h15
-rw-r--r--src/support/path.cpp3
-rw-r--r--src/support/small_vector.h6
-rw-r--r--src/support/sorted_vector.h7
-rw-r--r--src/support/threads.cpp3
-rw-r--r--src/tools/asm2wasm.cpp12
-rw-r--r--src/tools/execution-results.h3
-rw-r--r--src/tools/fuzzing.h153
-rw-r--r--src/tools/js-wrapper.h3
-rw-r--r--src/tools/optimization-options.h3
-rw-r--r--src/tools/spec-wrapper.h3
-rw-r--r--src/tools/wasm-as.cpp15
-rw-r--r--src/tools/wasm-ctor-eval.cpp6
-rw-r--r--src/tools/wasm-dis.cpp9
-rw-r--r--src/tools/wasm-emscripten-finalize.cpp6
-rw-r--r--src/tools/wasm-metadce.cpp6
-rw-r--r--src/tools/wasm-opt.cpp18
-rw-r--r--src/tools/wasm-reduce.cpp120
-rw-r--r--src/tools/wasm-shell.cpp12
-rw-r--r--src/tools/wasm2js.cpp15
-rw-r--r--src/wasm-binary.h36
-rw-r--r--src/wasm-builder.h15
-rw-r--r--src/wasm-features.h18
-rw-r--r--src/wasm-interpreter.h255
-rw-r--r--src/wasm-module-building.h6
-rw-r--r--src/wasm-stack.h135
-rw-r--r--src/wasm-traversal.h21
-rw-r--r--src/wasm/literal.cpp120
-rw-r--r--src/wasm/wasm-binary.cpp651
-rw-r--r--src/wasm/wasm-emscripten.cpp32
-rw-r--r--src/wasm/wasm-io.cpp15
-rw-r--r--src/wasm/wasm-s-parser.cpp441
-rw-r--r--src/wasm/wasm-type.cpp12
-rw-r--r--src/wasm/wasm-validator.cpp72
-rw-r--r--src/wasm/wasm.cpp38
-rw-r--r--src/wasm2js.h16
116 files changed, 2945 insertions, 1508 deletions
diff --git a/src/abi/js.h b/src/abi/js.h
index 8391346c8..52ca5657f 100644
--- a/src/abi/js.h
+++ b/src/abi/js.h
@@ -54,10 +54,12 @@ ensureScratchMemoryHelpers(Module* wasm,
cashew::IString specific = cashew::IString()) {
auto ensureImport =
[&](Name name, const std::vector<Type> params, Type result) {
- if (wasm->getFunctionOrNull(name))
+ if (wasm->getFunctionOrNull(name)) {
return;
- if (specific.is() && name != specific)
+ }
+ if (specific.is() && name != specific) {
return;
+ }
auto func = make_unique<Function>();
func->name = name;
func->params = params;
diff --git a/src/asm2wasm.h b/src/asm2wasm.h
index ba6a3df57..a4598c556 100644
--- a/src/asm2wasm.h
+++ b/src/asm2wasm.h
@@ -167,12 +167,15 @@ std::vector<Ref> AstStackHelper::astStack;
static bool startsWith(const char* string, const char* prefix) {
while (1) {
- if (*prefix == 0)
+ if (*prefix == 0) {
return true;
- if (*string == 0)
+ }
+ if (*string == 0) {
return false;
- if (*string++ != *prefix++)
+ }
+ if (*string++ != *prefix++) {
return false;
+ }
}
};
@@ -191,8 +194,9 @@ struct Asm2WasmPreProcessor {
char* allocatedCopy = nullptr;
~Asm2WasmPreProcessor() {
- if (allocatedCopy)
+ if (allocatedCopy) {
free(allocatedCopy);
+ }
}
char* process(char* input) {
@@ -231,14 +235,18 @@ struct Asm2WasmPreProcessor {
memoryGrowth = true;
// clean out this function, we don't need it. first where it starts
char* growthFuncStart = growthSign;
- while (*growthFuncStart != '{')
+ while (*growthFuncStart != '{') {
growthFuncStart--; // skip body
- while (*growthFuncStart != '(')
+ }
+ while (*growthFuncStart != '(') {
growthFuncStart--; // skip params
- while (*growthFuncStart != ' ')
+ }
+ while (*growthFuncStart != ' ') {
growthFuncStart--; // skip function name
- while (*growthFuncStart != 'f')
+ }
+ while (*growthFuncStart != 'f') {
growthFuncStart--; // skip 'function'
+ }
assert(strstr(growthFuncStart, "function ") == growthFuncStart);
char* growthFuncEnd = strchr(growthSign, '}');
assert(growthFuncEnd > growthFuncStart + 5);
@@ -381,8 +389,9 @@ struct AdjustDebugInfo
void visitBlock(Block* curr) {
// look for a debug info call that is unreachable
- if (curr->list.size() == 0)
+ if (curr->list.size() == 0) {
return;
+ }
auto* back = curr->list.back();
for (Index i = 1; i < curr->list.size(); i++) {
if (checkDebugInfo(curr->list[i]) && !checkDebugInfo(curr->list[i - 1])) {
@@ -621,38 +630,49 @@ private:
Type leftType = leftWasm->type;
bool isInteger = leftType == Type::i32;
- if (op == PLUS)
+ if (op == PLUS) {
return isInteger ? BinaryOp::AddInt32
: (leftType == f32 ? BinaryOp::AddFloat32
: BinaryOp::AddFloat64);
- if (op == MINUS)
+ }
+ if (op == MINUS) {
return isInteger ? BinaryOp::SubInt32
: (leftType == f32 ? BinaryOp::SubFloat32
: BinaryOp::SubFloat64);
- if (op == MUL)
+ }
+ if (op == MUL) {
return isInteger ? BinaryOp::MulInt32
: (leftType == f32 ? BinaryOp::MulFloat32
: BinaryOp::MulFloat64);
- if (op == AND)
+ }
+ if (op == AND) {
return BinaryOp::AndInt32;
- if (op == OR)
+ }
+ if (op == OR) {
return BinaryOp::OrInt32;
- if (op == XOR)
+ }
+ if (op == XOR) {
return BinaryOp::XorInt32;
- if (op == LSHIFT)
+ }
+ if (op == LSHIFT) {
return BinaryOp::ShlInt32;
- if (op == RSHIFT)
+ }
+ if (op == RSHIFT) {
return BinaryOp::ShrSInt32;
- if (op == TRSHIFT)
+ }
+ if (op == TRSHIFT) {
return BinaryOp::ShrUInt32;
- if (op == EQ)
+ }
+ if (op == EQ) {
return isInteger
? BinaryOp::EqInt32
: (leftType == f32 ? BinaryOp::EqFloat32 : BinaryOp::EqFloat64);
- if (op == NE)
+ }
+ if (op == NE) {
return isInteger
? BinaryOp::NeInt32
: (leftType == f32 ? BinaryOp::NeFloat32 : BinaryOp::NeFloat64);
+ }
bool isUnsigned = isUnsignedCoercion(left) || isUnsignedCoercion(right);
@@ -728,10 +748,12 @@ private:
}
if (ast[1] == MINUS && ast[2]->isNumber()) {
double num = -ast[2]->getNumber();
- if (isSInteger32(num))
+ if (isSInteger32(num)) {
return Literal((int32_t)num);
- if (isUInteger32(num))
+ }
+ if (isUInteger32(num)) {
return Literal((uint32_t)num);
+ }
assert(false && "expected signed or unsigned int32");
}
if (ast[1] == PLUS && ast[2]->isArray(UNARY_PREFIX) &&
@@ -758,10 +780,11 @@ private:
}
void fixCallType(Expression* call, Type type) {
- if (call->is<Call>())
+ if (call->is<Call>()) {
call->cast<Call>()->type = type;
- else if (call->is<CallIndirect>())
+ } else if (call->is<CallIndirect>()) {
call->cast<CallIndirect>()->type = type;
+ }
}
FunctionType* getBuiltinFunctionType(Name module,
@@ -771,12 +794,15 @@ private:
if (base == ABS) {
assert(operands && operands->size() == 1);
Type type = (*operands)[0]->type;
- if (type == i32)
+ if (type == i32) {
return ensureFunctionType("ii", &wasm);
- if (type == f32)
+ }
+ if (type == f32) {
return ensureFunctionType("ff", &wasm);
- if (type == f64)
+ }
+ if (type == f64) {
return ensureFunctionType("dd", &wasm);
+ }
}
}
return nullptr;
@@ -784,8 +810,9 @@ private:
// ensure a nameless block
Block* blockify(Expression* expression) {
- if (expression->is<Block>() && !expression->cast<Block>()->name.is())
+ if (expression->is<Block>() && !expression->cast<Block>()->name.is()) {
return expression->dynCast<Block>();
+ }
auto ret = allocator.alloc<Block>();
ret->list.push_back(expression);
ret->finalize();
@@ -797,8 +824,9 @@ private:
}
Expression* truncateToInt32(Expression* value) {
- if (value->type == i64)
+ if (value->type == i64) {
return builder.makeUnary(UnaryOp::WrapInt64, value);
+ }
// either i32, or a call_import whose type we don't know yet (but would be
// legalized to i32 anyhow)
return value;
@@ -1024,8 +1052,9 @@ void Asm2WasmBuilder::processAsm(Ref ast) {
if (runOptimizationPasses) {
Index numFunctions = 0;
for (unsigned i = 1; i < body->size(); i++) {
- if (body[i][0] == DEFUN)
+ if (body[i][0] == DEFUN) {
numFunctions++;
+ }
}
optimizingBuilder = make_unique<OptimizingIncrementalModuleBuilder>(
&wasm,
@@ -1396,8 +1425,9 @@ void Asm2WasmBuilder::processAsm(Ref ast) {
numShown = make_unique<std::atomic<int>>();
numShown->store(0);
}
- if (numShown->load() >= MAX_SHOWN)
+ if (numShown->load() >= MAX_SHOWN) {
return;
+ }
std::cerr << why << " in call from " << getFunction()->name << " to "
<< calledFunc->name
<< " (this is likely due to undefined behavior in C, like "
@@ -1458,8 +1488,9 @@ void Asm2WasmBuilder::processAsm(Ref ast) {
// fill things out: add extra params as needed, etc. asm tolerates ffi
// overloading, wasm does not
auto iter = parent->importedFunctionTypes.find(curr->target);
- if (iter == parent->importedFunctionTypes.end())
+ if (iter == parent->importedFunctionTypes.end()) {
return; // one of our fake imports for callIndirect fixups
+ }
auto type = iter->second.get();
for (size_t i = 0; i < type->params.size(); i++) {
if (i >= curr->operands.size()) {
@@ -1539,31 +1570,36 @@ void Asm2WasmBuilder::processAsm(Ref ast) {
if (auto* call = target->dynCast<Call>()) {
auto tableName = call->target;
if (parent->functionTableStarts.find(tableName) ==
- parent->functionTableStarts.end())
+ parent->functionTableStarts.end()) {
return;
+ }
curr->target = parent->builder.makeConst(
Literal((int32_t)parent->functionTableStarts[tableName]));
return;
}
auto* add = target->dynCast<Binary>();
- if (!add)
+ if (!add) {
return;
+ }
if (add->right->is<Call>()) {
auto* offset = add->right->cast<Call>();
auto tableName = offset->target;
if (parent->functionTableStarts.find(tableName) ==
- parent->functionTableStarts.end())
+ parent->functionTableStarts.end()) {
return;
+ }
add->right = parent->builder.makeConst(
Literal((int32_t)parent->functionTableStarts[tableName]));
} else {
auto* offset = add->left->dynCast<Call>();
- if (!offset)
+ if (!offset) {
return;
+ }
auto tableName = offset->target;
if (parent->functionTableStarts.find(tableName) ==
- parent->functionTableStarts.end())
+ parent->functionTableStarts.end()) {
return;
+ }
add->left = parent->builder.makeConst(
Literal((int32_t)parent->functionTableStarts[tableName]));
}
@@ -1690,10 +1726,12 @@ void Asm2WasmBuilder::processAsm(Ref ast) {
Name tempRet0;
{
Expression* curr = wasm.getFunction(getTempRet0)->body;
- if (curr->is<Block>())
+ if (curr->is<Block>()) {
curr = curr->cast<Block>()->list.back();
- if (curr->is<Return>())
+ }
+ if (curr->is<Return>()) {
curr = curr->cast<Return>()->value;
+ }
auto* get = curr->cast<GetGlobal>();
tempRet0 = get->name;
}
@@ -1795,8 +1833,9 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
bool addedI32Temp = false;
auto ensureI32Temp = [&]() {
- if (addedI32Temp)
+ if (addedI32Temp) {
return;
+ }
addedI32Temp = true;
Builder::addVar(function, I32_TEMP, i32);
functionVariables.insert(I32_TEMP);
@@ -1878,8 +1917,9 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
// global.set does not return; if our value is trivially not used, don't
// emit a load (if nontrivially not used, opts get it later)
auto parent = astStackHelper.getParent();
- if (!parent || parent->isArray(BLOCK) || parent->isArray(IF))
+ if (!parent || parent->isArray(BLOCK) || parent->isArray(IF)) {
return ret;
+ }
return builder.makeSequence(
ret, builder.makeGetGlobal(name, ret->value->type));
}
@@ -2294,51 +2334,61 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
switch (name.str[0]) {
case 'l': {
auto align = num == 2 ? ast[2][1]->getInteger() : 0;
- if (name == LOAD1)
+ if (name == LOAD1) {
return builder.makeLoad(1, true, 0, 1, process(ast[2][0]), i32);
- if (name == LOAD2)
+ }
+ if (name == LOAD2) {
return builder.makeLoad(
2, true, 0, indexOr(align, 2), process(ast[2][0]), i32);
- if (name == LOAD4)
+ }
+ if (name == LOAD4) {
return builder.makeLoad(
4, true, 0, indexOr(align, 4), process(ast[2][0]), i32);
- if (name == LOAD8)
+ }
+ if (name == LOAD8) {
return builder.makeLoad(
8, true, 0, indexOr(align, 8), process(ast[2][0]), i64);
- if (name == LOADF)
+ }
+ if (name == LOADF) {
return builder.makeLoad(
4, true, 0, indexOr(align, 4), process(ast[2][0]), f32);
- if (name == LOADD)
+ }
+ if (name == LOADD) {
return builder.makeLoad(
8, true, 0, indexOr(align, 8), process(ast[2][0]), f64);
+ }
break;
}
case 's': {
auto align = num == 3 ? ast[2][2]->getInteger() : 0;
- if (name == STORE1)
+ if (name == STORE1) {
return builder.makeStore(
1, 0, 1, process(ast[2][0]), process(ast[2][1]), i32);
- if (name == STORE2)
+ }
+ if (name == STORE2) {
return builder.makeStore(2,
0,
indexOr(align, 2),
process(ast[2][0]),
process(ast[2][1]),
i32);
- if (name == STORE4)
+ }
+ if (name == STORE4) {
return builder.makeStore(4,
0,
indexOr(align, 4),
process(ast[2][0]),
process(ast[2][1]),
i32);
- if (name == STORE8)
+ }
+ if (name == STORE8) {
return builder.makeStore(8,
0,
indexOr(align, 8),
process(ast[2][0]),
process(ast[2][1]),
i64);
+ }
if (name == STOREF) {
auto* value = process(ast[2][1]);
if (value->type == f64) {
@@ -2349,13 +2399,14 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
return builder.makeStore(
4, 0, indexOr(align, 4), process(ast[2][0]), value, f32);
}
- if (name == STORED)
+ if (name == STORED) {
return builder.makeStore(8,
0,
indexOr(align, 8),
process(ast[2][0]),
process(ast[2][1]),
f64);
+ }
break;
}
case 'i': {
@@ -2372,33 +2423,44 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
return value;
}
}
- if (name == I32_CTTZ)
+ if (name == I32_CTTZ) {
return builder.makeUnary(UnaryOp::CtzInt32, value);
- if (name == I32_CTPOP)
+ }
+ if (name == I32_CTPOP) {
return builder.makeUnary(UnaryOp::PopcntInt32, value);
- if (name == I32_BC2F)
+ }
+ if (name == I32_BC2F) {
return builder.makeUnary(UnaryOp::ReinterpretInt32, value);
- if (name == I32_BC2I)
+ }
+ if (name == I32_BC2I) {
return builder.makeUnary(UnaryOp::ReinterpretFloat32, value);
+ }
- if (name == I64_TRUNC)
+ if (name == I64_TRUNC) {
return builder.makeUnary(UnaryOp::WrapInt64, value);
- if (name == I64_SEXT)
+ }
+ if (name == I64_SEXT) {
return builder.makeUnary(UnaryOp::ExtendSInt32, value);
- if (name == I64_ZEXT)
+ }
+ if (name == I64_ZEXT) {
return builder.makeUnary(UnaryOp::ExtendUInt32, value);
- if (name == I64_S2F)
+ }
+ if (name == I64_S2F) {
return builder.makeUnary(UnaryOp::ConvertSInt64ToFloat32,
value);
- if (name == I64_S2D)
+ }
+ if (name == I64_S2D) {
return builder.makeUnary(UnaryOp::ConvertSInt64ToFloat64,
value);
- if (name == I64_U2F)
+ }
+ if (name == I64_U2F) {
return builder.makeUnary(UnaryOp::ConvertUInt64ToFloat32,
value);
- if (name == I64_U2D)
+ }
+ if (name == I64_U2D) {
return builder.makeUnary(UnaryOp::ConvertUInt64ToFloat64,
value);
+ }
if (name == I64_F2S) {
Unary* conv =
builder.makeUnary(UnaryOp::TruncSFloat32ToInt64, value);
@@ -2419,30 +2481,40 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
builder.makeUnary(UnaryOp::TruncUFloat64ToInt64, value);
return makeTrappingUnary(conv, trappingFunctions);
}
- if (name == I64_BC2D)
+ if (name == I64_BC2D) {
return builder.makeUnary(UnaryOp::ReinterpretInt64, value);
- if (name == I64_BC2I)
+ }
+ if (name == I64_BC2I) {
return builder.makeUnary(UnaryOp::ReinterpretFloat64, value);
- if (name == I64_CTTZ)
+ }
+ if (name == I64_CTTZ) {
return builder.makeUnary(UnaryOp::CtzInt64, value);
- if (name == I64_CTLZ)
+ }
+ if (name == I64_CTLZ) {
return builder.makeUnary(UnaryOp::ClzInt64, value);
- if (name == I64_CTPOP)
+ }
+ if (name == I64_CTPOP) {
return builder.makeUnary(UnaryOp::PopcntInt64, value);
- if (name == I64_ATOMICS_LOAD)
+ }
+ if (name == I64_ATOMICS_LOAD) {
return builder.makeAtomicLoad(8, 0, value, i64);
+ }
} else if (num == 2) { // 2 params,binary
- if (name == I64_CONST)
+ if (name == I64_CONST) {
return builder.makeConst(getLiteral(ast));
+ }
auto* left = process(ast[2][0]);
auto* right = process(ast[2][1]);
// maths
- if (name == I64_ADD)
+ if (name == I64_ADD) {
return builder.makeBinary(BinaryOp::AddInt64, left, right);
- if (name == I64_SUB)
+ }
+ if (name == I64_SUB) {
return builder.makeBinary(BinaryOp::SubInt64, left, right);
- if (name == I64_MUL)
+ }
+ if (name == I64_MUL) {
return builder.makeBinary(BinaryOp::MulInt64, left, right);
+ }
if (name == I64_UDIV) {
Binary* div =
builder.makeBinary(BinaryOp::DivUInt64, left, right);
@@ -2463,39 +2535,55 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
builder.makeBinary(BinaryOp::RemSInt64, left, right);
return makeTrappingBinary(rem, trappingFunctions);
}
- if (name == I64_AND)
+ if (name == I64_AND) {
return builder.makeBinary(BinaryOp::AndInt64, left, right);
- if (name == I64_OR)
+ }
+ if (name == I64_OR) {
return builder.makeBinary(BinaryOp::OrInt64, left, right);
- if (name == I64_XOR)
+ }
+ if (name == I64_XOR) {
return builder.makeBinary(BinaryOp::XorInt64, left, right);
- if (name == I64_SHL)
+ }
+ if (name == I64_SHL) {
return builder.makeBinary(BinaryOp::ShlInt64, left, right);
- if (name == I64_ASHR)
+ }
+ if (name == I64_ASHR) {
return builder.makeBinary(BinaryOp::ShrSInt64, left, right);
- if (name == I64_LSHR)
+ }
+ if (name == I64_LSHR) {
return builder.makeBinary(BinaryOp::ShrUInt64, left, right);
+ }
// comps
- if (name == I64_EQ)
+ if (name == I64_EQ) {
return builder.makeBinary(BinaryOp::EqInt64, left, right);
- if (name == I64_NE)
+ }
+ if (name == I64_NE) {
return builder.makeBinary(BinaryOp::NeInt64, left, right);
- if (name == I64_ULE)
+ }
+ if (name == I64_ULE) {
return builder.makeBinary(BinaryOp::LeUInt64, left, right);
- if (name == I64_SLE)
+ }
+ if (name == I64_SLE) {
return builder.makeBinary(BinaryOp::LeSInt64, left, right);
- if (name == I64_UGE)
+ }
+ if (name == I64_UGE) {
return builder.makeBinary(BinaryOp::GeUInt64, left, right);
- if (name == I64_SGE)
+ }
+ if (name == I64_SGE) {
return builder.makeBinary(BinaryOp::GeSInt64, left, right);
- if (name == I64_ULT)
+ }
+ if (name == I64_ULT) {
return builder.makeBinary(BinaryOp::LtUInt64, left, right);
- if (name == I64_SLT)
+ }
+ if (name == I64_SLT) {
return builder.makeBinary(BinaryOp::LtSInt64, left, right);
- if (name == I64_UGT)
+ }
+ if (name == I64_UGT) {
return builder.makeBinary(BinaryOp::GtUInt64, left, right);
- if (name == I64_SGT)
+ }
+ if (name == I64_SGT) {
return builder.makeBinary(BinaryOp::GtSInt64, left, right);
+ }
// atomics
if (name == I64_ATOMICS_STORE) {
wasm.memory.shared = true;
@@ -2545,14 +2633,16 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
break;
}
case 'f': {
- if (name == F32_COPYSIGN)
+ if (name == F32_COPYSIGN) {
return builder.makeBinary(BinaryOp::CopySignFloat32,
process(ast[2][0]),
process(ast[2][1]));
- if (name == F64_COPYSIGN)
+ }
+ if (name == F64_COPYSIGN) {
return builder.makeBinary(BinaryOp::CopySignFloat64,
process(ast[2][0]),
process(ast[2][1]));
+ }
break;
}
default: {}
@@ -2960,10 +3050,12 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
min = index;
max = index;
} else {
- if (index < min)
+ if (index < min) {
min = index;
- if (index > max)
+ }
+ if (index > max) {
max = index;
+ }
}
}
}
@@ -3059,8 +3151,9 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
breakWhenNotMatching->name = br->default_;
}
for (size_t i = 0; i < br->targets.size(); i++) {
- if (br->targets[i].isNull())
+ if (br->targets[i].isNull()) {
br->targets[i] = br->default_;
+ }
}
} else {
// we can't switch, make an if-chain instead of br_table
@@ -3087,8 +3180,9 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
builder.makeBreak(name),
chain);
chain = iff;
- if (!first)
+ if (!first) {
first = iff;
+ }
}
auto next = allocator.alloc<Block>();
top->name = name;
@@ -3153,10 +3247,12 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
processStatements = [&](Ref ast, unsigned from) -> Expression* {
unsigned size = ast->size() - from;
- if (size == 0)
+ if (size == 0) {
return allocator.alloc<Nop>();
- if (size == 1)
+ }
+ if (size == 1) {
return process(ast[from]);
+ }
auto block = allocator.alloc<Block>();
for (unsigned i = from; i < ast->size(); i++) {
block->list.push_back(process(ast[i]));
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index 5842e5afe..b3b52bfcf 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -108,10 +108,11 @@ static PassOptions globalPassOptions =
static int tracing = 0;
void traceNameOrNULL(const char* name, std::ostream& out = std::cout) {
- if (name)
+ if (name) {
out << "\"" << name << "\"";
- else
+ } else {
out << "NULL";
+ }
}
std::map<BinaryenFunctionTypeRef, size_t> functionTypes;
@@ -400,10 +401,11 @@ BinaryenFunctionTypeRef BinaryenAddFunctionType(BinaryenModuleRef module,
BinaryenIndex numParams) {
auto* wasm = (Module*)module;
auto ret = make_unique<FunctionType>();
- if (name)
+ if (name) {
ret->name = name;
- else
+ } else {
ret->name = Name::fromInt(wasm->functionTypes.size());
+ }
ret->result = Type(result);
for (BinaryenIndex i = 0; i < numParams; i++) {
ret->params.push_back(Type(paramTypes[i]));
@@ -413,13 +415,15 @@ BinaryenFunctionTypeRef BinaryenAddFunctionType(BinaryenModuleRef module,
std::cout << " {\n";
std::cout << " BinaryenType paramTypes[] = { ";
for (BinaryenIndex i = 0; i < numParams; i++) {
- if (i > 0)
+ if (i > 0) {
std::cout << ", ";
+ }
std::cout << paramTypes[i];
}
- if (numParams == 0)
+ if (numParams == 0) {
// ensure the array is not empty, otherwise a compiler error on VS
std::cout << "0";
+ }
std::cout << " };\n";
size_t id = functionTypes.size();
std::cout << " functionTypes[" << id
@@ -811,29 +815,34 @@ BinaryenExpressionRef BinaryenBlock(BinaryenModuleRef module,
BinaryenIndex numChildren,
BinaryenType type) {
auto* ret = ((Module*)module)->allocator.alloc<Block>();
- if (name)
+ if (name) {
ret->name = name;
+ }
for (BinaryenIndex i = 0; i < numChildren; i++) {
ret->list.push_back((Expression*)children[i]);
}
- if (type != BinaryenTypeAuto())
+ if (type != BinaryenTypeAuto()) {
ret->finalize(Type(type));
- else
+ } else {
ret->finalize();
+ }
if (tracing) {
std::cout << " {\n";
std::cout << " BinaryenExpressionRef children[] = { ";
for (BinaryenIndex i = 0; i < numChildren; i++) {
- if (i > 0)
+ if (i > 0) {
std::cout << ", ";
- if (i % 6 == 5)
+ }
+ if (i % 6 == 5) {
std::cout << "\n "; // don't create hugely long lines
+ }
std::cout << "expressions[" << expressions[children[i]] << "]";
}
- if (numChildren == 0)
+ if (numChildren == 0) {
// ensure the array is not empty, otherwise a compiler error on VS
std::cout << "0";
+ }
std::cout << " };\n ";
traceExpression(
ret, "BinaryenBlock", StringLit(name), "children", numChildren, type);
@@ -895,13 +904,15 @@ BinaryenExpressionRef BinaryenSwitch(BinaryenModuleRef module,
std::cout << " {\n";
std::cout << " const char* names[] = { ";
for (BinaryenIndex i = 0; i < numNames; i++) {
- if (i > 0)
+ if (i > 0) {
std::cout << ", ";
+ }
std::cout << "\"" << names[i] << "\"";
}
- if (numNames == 0)
- std::cout << "0"; // ensure the array is not empty, otherwise a compiler
- // error on VS
+ if (numNames == 0) {
+ // ensure the array is not empty, otherwise a compiler error on VS
+ std::cout << "0";
+ }
std::cout << " };\n ";
traceExpression(ret,
"BinaryenSwitch",
@@ -933,13 +944,15 @@ BinaryenExpressionRef BinaryenCall(BinaryenModuleRef module,
std::cout << " {\n";
std::cout << " BinaryenExpressionRef operands[] = { ";
for (BinaryenIndex i = 0; i < numOperands; i++) {
- if (i > 0)
+ if (i > 0) {
std::cout << ", ";
+ }
std::cout << "expressions[" << expressions[operands[i]] << "]";
}
- if (numOperands == 0)
+ if (numOperands == 0) {
// ensure the array is not empty, otherwise a compiler error on VS
std::cout << "0";
+ }
std::cout << " };\n ";
traceExpression(ret,
"BinaryenCall",
@@ -970,13 +983,15 @@ BinaryenExpressionRef BinaryenCallIndirect(BinaryenModuleRef module,
std::cout << " {\n";
std::cout << " BinaryenExpressionRef operands[] = { ";
for (BinaryenIndex i = 0; i < numOperands; i++) {
- if (i > 0)
+ if (i > 0) {
std::cout << ", ";
+ }
std::cout << "expressions[" << expressions[operands[i]] << "]";
}
- if (numOperands == 0)
+ if (numOperands == 0) {
// ensure the array is not empty, otherwise a compiler error on VS
std::cout << "0";
+ }
std::cout << " };\n ";
traceExpression(ret,
"BinaryenCallIndirect",
@@ -1197,13 +1212,15 @@ BinaryenExpressionRef BinaryenHost(BinaryenModuleRef module,
std::cout << " {\n";
std::cout << " BinaryenExpressionRef operands[] = { ";
for (BinaryenIndex i = 0; i < numOperands; i++) {
- if (i > 0)
+ if (i > 0) {
std::cout << ", ";
+ }
std::cout << "expressions[" << expressions[operands[i]] << "]";
}
- if (numOperands == 0)
+ if (numOperands == 0) {
// ensure the array is not empty, otherwise a compiler error on VS
std::cout << "0";
+ }
std::cout << " };\n ";
traceExpression(
ret, "BinaryenHost", StringLit(name), "operands", numOperands);
@@ -1211,8 +1228,9 @@ BinaryenExpressionRef BinaryenHost(BinaryenModuleRef module,
}
ret->op = HostOp(op);
- if (name)
+ if (name) {
ret->nameOperand = name;
+ }
for (BinaryenIndex i = 0; i < numOperands; i++) {
ret->operands.push_back((Expression*)operands[i]);
}
@@ -2619,13 +2637,15 @@ BinaryenFunctionRef BinaryenAddFunction(BinaryenModuleRef module,
std::cout << " {\n";
std::cout << " BinaryenType varTypes[] = { ";
for (BinaryenIndex i = 0; i < numVarTypes; i++) {
- if (i > 0)
+ if (i > 0) {
std::cout << ", ";
+ }
std::cout << varTypes[i];
}
- if (numVarTypes == 0)
+ if (numVarTypes == 0) {
// ensure the array is not empty, otherwise a compiler error on VS
std::cout << "0";
+ }
std::cout << " };\n";
auto id = functions.size();
functions[ret] = id;
@@ -2887,8 +2907,9 @@ void BinaryenSetFunctionTable(BinaryenModuleRef module,
std::cout << " {\n";
std::cout << " const char* funcNames[] = { ";
for (BinaryenIndex i = 0; i < numFuncNames; i++) {
- if (i > 0)
+ if (i > 0) {
std::cout << ", ";
+ }
std::cout << "\"" << funcNames[i] << "\"";
}
std::cout << " };\n";
@@ -2926,51 +2947,60 @@ void BinaryenSetMemory(BinaryenModuleRef module,
for (BinaryenIndex i = 0; i < numSegments; i++) {
std::cout << " const char segment" << i << "[] = { ";
for (BinaryenIndex j = 0; j < segmentSizes[i]; j++) {
- if (j > 0)
+ if (j > 0) {
std::cout << ", ";
+ }
std::cout << int(segments[i][j]);
}
std::cout << " };\n";
}
std::cout << " const char* segments[] = { ";
for (BinaryenIndex i = 0; i < numSegments; i++) {
- if (i > 0)
+ if (i > 0) {
std::cout << ", ";
+ }
std::cout << "segment" << i;
}
- if (numSegments == 0)
+ if (numSegments == 0) {
// ensure the array is not empty, otherwise a compiler error on VS
std::cout << "0";
+ }
std::cout << " };\n";
std::cout << " int8_t segmentPassive[] = { ";
for (BinaryenIndex i = 0; i < numSegments; i++) {
- if (i > 0)
+ if (i > 0) {
std::cout << ", ";
+ }
std::cout << int(segmentPassive[i]);
}
- if (numSegments == 0)
+ if (numSegments == 0) {
// ensure the array is not empty, otherwise a compiler error on VS
std::cout << "0";
+ }
std::cout << " };\n";
std::cout << " BinaryenExpressionRef segmentOffsets[] = { ";
for (BinaryenIndex i = 0; i < numSegments; i++) {
- if (i > 0)
+ if (i > 0) {
std::cout << ", ";
+ }
std::cout << "expressions[" << expressions[segmentOffsets[i]] << "]";
}
- if (numSegments == 0)
+ if (numSegments == 0) {
// ensure the array is not empty, otherwise a compiler error on VS
std::cout << "0";
+ }
std::cout << " };\n";
std::cout << " BinaryenIndex segmentSizes[] = { ";
for (BinaryenIndex i = 0; i < numSegments; i++) {
- if (i > 0)
+ if (i > 0) {
std::cout << ", ";
+ }
std::cout << segmentSizes[i];
}
- if (numSegments == 0)
+ if (numSegments == 0) {
// ensure the array is not empty, otherwise a compiler error on VS
std::cout << "0";
+ }
std::cout << " };\n";
std::cout << " BinaryenSetMemory(the_module, " << initial << ", "
<< maximum << ", ";
@@ -3137,8 +3167,9 @@ void BinaryenModuleRunPasses(BinaryenModuleRef module,
std::cout << " {\n";
std::cout << " const char* passes[] = { ";
for (BinaryenIndex i = 0; i < numPasses; i++) {
- if (i > 0)
+ if (i > 0) {
std::cout << ", ";
+ }
std::cout << "\"" << passes[i] << "\"";
}
std::cout << " };\n";
@@ -3439,8 +3470,9 @@ void BinaryenFunctionRunPasses(BinaryenFunctionRef func,
std::cout << " {\n";
std::cout << " const char* passes[] = { ";
for (BinaryenIndex i = 0; i < numPasses; i++) {
- if (i > 0)
+ if (i > 0) {
std::cout << ", ";
+ }
std::cout << "\"" << passes[i] << "\"";
}
std::cout << " };\n";
@@ -3638,13 +3670,15 @@ void RelooperAddBranchForSwitch(RelooperBlockRef from,
std::cout << " {\n";
std::cout << " BinaryenIndex indexes[] = { ";
for (BinaryenIndex i = 0; i < numIndexes; i++) {
- if (i > 0)
+ if (i > 0) {
std::cout << ", ";
+ }
std::cout << indexes[i];
}
- if (numIndexes == 0)
+ if (numIndexes == 0) {
// ensure the array is not empty, otherwise a compiler error on VS
std::cout << "0";
+ }
std::cout << " };\n";
std::cout << " RelooperAddBranchForSwitch(relooperBlocks["
<< relooperBlocks[from] << "], relooperBlocks["
diff --git a/src/cfg/Relooper.cpp b/src/cfg/Relooper.cpp
index 8a15fe75c..87dd4e379 100644
--- a/src/cfg/Relooper.cpp
+++ b/src/cfg/Relooper.cpp
@@ -48,8 +48,9 @@ static wasm::Expression* HandleFollowupMultiples(wasm::Expression* Ret,
Shape* Parent,
RelooperBuilder& Builder,
bool InLoop) {
- if (!Parent->Next)
+ if (!Parent->Next) {
return Ret;
+ }
auto* Curr = Ret->dynCast<wasm::Block>();
if (!Curr || Curr->name.is()) {
@@ -58,8 +59,9 @@ static wasm::Expression* HandleFollowupMultiples(wasm::Expression* Ret,
// for each multiple after us, we create a block target for breaks to reach
while (Parent->Next) {
auto* Multiple = Shape::IsMultiple(Parent->Next);
- if (!Multiple)
+ if (!Multiple) {
break;
+ }
for (auto& iter : Multiple->InnerMap) {
int Id = iter.first;
Shape* Body = iter.second;
@@ -120,10 +122,12 @@ Branch::Branch(std::vector<wasm::Index>&& ValuesInit,
wasm::Expression*
Branch::Render(RelooperBuilder& Builder, Block* Target, bool SetLabel) {
auto* Ret = Builder.makeBlock();
- if (Code)
+ if (Code) {
Ret->list.push_back(Code);
- if (SetLabel)
+ }
+ if (SetLabel) {
Ret->list.push_back(Builder.makeSetLabel(Target->Id));
+ }
if (Type == Break) {
Ret->list.push_back(Builder.makeBlockBreak(Target->Id));
} else if (Type == Continue) {
@@ -170,8 +174,9 @@ wasm::Expression* Block::Render(RelooperBuilder& Builder, bool InLoop) {
if (IsCheckedMultipleEntry && InLoop) {
Ret->list.push_back(Builder.makeSetLabel(0));
}
- if (Code)
+ if (Code) {
Ret->list.push_back(Code);
+ }
if (!ProcessedBranchesOut.size()) {
Ret->finalize();
@@ -254,8 +259,9 @@ wasm::Expression* Block::Render(RelooperBuilder& Builder, bool InLoop) {
Branch* Details;
if (iter != ProcessedBranchesOut.end()) {
Target = iter->first;
- if (Target == DefaultTarget)
+ if (Target == DefaultTarget) {
continue; // done at the end
+ }
Details = iter->second;
// must have a condition if this is not the default target
assert(Details->Condition);
@@ -318,8 +324,9 @@ wasm::Expression* Block::Render(RelooperBuilder& Builder, bool InLoop) {
RemainingConditions = Now;
}
}
- if (IsDefault)
+ if (IsDefault) {
break;
+ }
}
// finalize the if-chains
@@ -385,16 +392,18 @@ wasm::Expression* Block::Render(RelooperBuilder& Builder, bool InLoop) {
// this is the default, and it has no content. So make the default be
// the leave
for (auto& Value : Table) {
- if (Value == SwitchDefault)
+ if (Value == SwitchDefault) {
Value = SwitchLeave;
+ }
}
SwitchDefault = SwitchLeave;
}
}
if (Details->SwitchValues) {
for (auto Value : *Details->SwitchValues) {
- while (Table.size() <= Value)
+ while (Table.size() <= Value) {
Table.push_back(SwitchDefault);
+ }
Table[Value] = CurrName;
}
}
@@ -478,10 +487,12 @@ Relooper::Relooper(wasm::Module* ModuleInit)
}
Relooper::~Relooper() {
- for (unsigned i = 0; i < Blocks.size(); i++)
+ for (unsigned i = 0; i < Blocks.size(); i++) {
delete Blocks[i];
- for (unsigned i = 0; i < Shapes.size(); i++)
+ }
+ for (unsigned i = 0; i < Shapes.size(); i++) {
delete Shapes[i];
+ }
}
void Relooper::AddBlock(Block* New, int Id) {
@@ -508,8 +519,9 @@ struct Liveness : public RelooperRecursor {
while (ToInvestigate.size() > 0) {
Block* Curr = ToInvestigate.front();
ToInvestigate.pop_front();
- if (contains(Live, Curr))
+ if (contains(Live, Curr)) {
continue;
+ }
Live.insert(Curr);
for (auto& iter : Curr->BranchesOut) {
ToInvestigate.push_back(iter.first);
@@ -905,20 +917,24 @@ private:
template<typename T>
static bool IsPossibleUniquePtrEquivalent(std::unique_ptr<T>& A,
std::unique_ptr<T>& B) {
- if (A == B)
+ if (A == B) {
return true;
- if (!A || !B)
+ }
+ if (!A || !B) {
return false;
+ }
return *A == *B;
}
// Checks if code is equivalent, allowing the code to also be nullptr
static bool IsPossibleCodeEquivalent(wasm::Expression* A,
wasm::Expression* B) {
- if (A == B)
+ if (A == B) {
return true;
- if (!A || !B)
+ }
+ if (!A || !B) {
return false;
+ }
return IsCodeEquivalent(A, B);
}
@@ -1025,8 +1041,9 @@ void Relooper::Calculate(Block* Entry) {
// Add incoming branches from live blocks, ignoring dead code
for (unsigned i = 0; i < Blocks.size(); i++) {
Block* Curr = Blocks[i];
- if (!contains(Live.Live, Curr))
+ if (!contains(Live.Live, Curr)) {
continue;
+ }
for (auto& iter : Curr->BranchesOut) {
iter.first->BranchesIn.insert(Curr);
}
@@ -1282,10 +1299,11 @@ void Relooper::Calculate(Block* Entry) {
Queue.pop_front();
// Curr must be in the ownership map if we are in the queue
Block* Owner = Helper.Ownership[Curr];
- if (!Owner)
+ if (!Owner) {
// we have been invalidated meanwhile after being reached from two
// entries
continue;
+ }
// Add all children
for (auto& iter : Curr->BranchesOut) {
Block* New = iter.first;
@@ -1298,8 +1316,9 @@ void Relooper::Calculate(Block* Entry) {
continue;
}
Block* NewOwner = Known->second;
- if (!NewOwner)
+ if (!NewOwner) {
continue; // We reached an invalidated node
+ }
if (NewOwner != Owner) {
// Invalidate this and all reachable that we have seen - we reached
// this from two locations
@@ -1321,8 +1340,9 @@ void Relooper::Calculate(Block* Entry) {
BlockList ToInvalidate;
for (auto* Child : CurrGroup) {
for (auto* Parent : Child->BranchesIn) {
- if (Ignore && contains(*Ignore, Parent))
+ if (Ignore && contains(*Ignore, Parent)) {
continue;
+ }
if (Helper.Ownership[Parent] != Helper.Ownership[Child]) {
ToInvalidate.push_back(Child);
}
@@ -1436,8 +1456,9 @@ void Relooper::Calculate(Block* Entry) {
NextEntries = &TempEntries[CurrTempIndex];
NextEntries->clear();
- if (Entries->size() == 0)
+ if (Entries->size() == 0) {
return Ret;
+ }
if (Entries->size() == 1) {
Block* Curr = *(Entries->begin());
if (Curr->BranchesIn.size() == 0) {
@@ -1525,8 +1546,9 @@ void Relooper::Calculate(Block* Entry) {
break;
}
}
- if (!DeadEnd)
+ if (!DeadEnd) {
break;
+ }
}
if (DeadEnd) {
PrintDebug("Removing nesting by not handling large group "
diff --git a/src/cfg/cfg-traversal.h b/src/cfg/cfg-traversal.h
index abaf63c5b..79c561de0 100644
--- a/src/cfg/cfg-traversal.h
+++ b/src/cfg/cfg-traversal.h
@@ -79,22 +79,26 @@ struct CFGWalker : public ControlFlowWalker<SubType, VisitorType> {
}
void link(BasicBlock* from, BasicBlock* to) {
- if (!from || !to)
+ if (!from || !to) {
return; // if one of them is not reachable, ignore
+ }
from->out.push_back(to);
to->in.push_back(from);
}
static void doEndBlock(SubType* self, Expression** currp) {
auto* curr = (*currp)->cast<Block>();
- if (!curr->name.is())
+ if (!curr->name.is()) {
return;
+ }
auto iter = self->branches.find(curr);
- if (iter == self->branches.end())
+ if (iter == self->branches.end()) {
return;
+ }
auto& origins = iter->second;
- if (origins.size() == 0)
+ if (origins.size() == 0) {
return;
+ }
// we have branches to here, so we need a new block
auto* last = self->currBasicBlock;
self->startBasicBlock();
@@ -270,8 +274,9 @@ struct CFGWalker : public ControlFlowWalker<SubType, VisitorType> {
queue.erase(iter);
alive.insert(curr);
for (auto* out : curr->out) {
- if (!alive.count(out))
+ if (!alive.count(out)) {
queue.insert(out);
+ }
}
}
return alive;
@@ -305,8 +310,9 @@ struct CFGWalker : public ControlFlowWalker<SubType, VisitorType> {
std::map<BasicBlock*, size_t> debugIds;
void generateDebugIds() {
- if (debugIds.size() > 0)
+ if (debugIds.size() > 0) {
return;
+ }
for (auto& block : basicBlocks) {
debugIds[block.get()] = debugIds.size();
}
diff --git a/src/cfg/liveness-traversal.h b/src/cfg/liveness-traversal.h
index b26898460..a0ce214bc 100644
--- a/src/cfg/liveness-traversal.h
+++ b/src/cfg/liveness-traversal.h
@@ -50,10 +50,12 @@ struct LivenessAction {
LivenessAction(What what, Index index, Expression** origin)
: what(what), index(index), origin(origin), effective(false) {
assert(what != Other);
- if (what == Get)
+ if (what == Get) {
assert((*origin)->is<GetLocal>());
- if (what == Set)
+ }
+ if (what == Set) {
assert((*origin)->is<SetLocal>());
+ }
}
LivenessAction(Expression** origin) : what(Other), origin(origin) {}
@@ -153,14 +155,17 @@ struct LivenessWalker : public CFGWalker<SubType, VisitorType, Liveness> {
// need to count to see if worth it.
// TODO: an if can have two copies
GetLocal* getCopy(SetLocal* set) {
- if (auto* get = set->value->dynCast<GetLocal>())
+ if (auto* get = set->value->dynCast<GetLocal>()) {
return get;
+ }
if (auto* iff = set->value->dynCast<If>()) {
- if (auto* get = iff->ifTrue->dynCast<GetLocal>())
+ if (auto* get = iff->ifTrue->dynCast<GetLocal>()) {
return get;
+ }
if (iff->ifFalse) {
- if (auto* get = iff->ifFalse->dynCast<GetLocal>())
+ if (auto* get = iff->ifFalse->dynCast<GetLocal>()) {
return get;
+ }
}
}
return nullptr;
@@ -188,8 +193,9 @@ struct LivenessWalker : public CFGWalker<SubType, VisitorType, Liveness> {
// keep working while stuff is flowing
std::unordered_set<BasicBlock*> queue;
for (auto& curr : CFGWalker<SubType, VisitorType, Liveness>::basicBlocks) {
- if (liveBlocks.count(curr.get()) == 0)
+ if (liveBlocks.count(curr.get()) == 0) {
continue; // ignore dead blocks
+ }
queue.insert(curr.get());
// do the first scan through the block, starting with nothing live at the
// end, and updating the liveness at the start
@@ -203,15 +209,17 @@ struct LivenessWalker : public CFGWalker<SubType, VisitorType, Liveness> {
auto* curr = *iter;
queue.erase(iter);
LocalSet live;
- if (!mergeStartsAndCheckChange(curr->out, curr->contents.end, live))
+ if (!mergeStartsAndCheckChange(curr->out, curr->contents.end, live)) {
continue;
+ }
assert(curr->contents.end.size() < live.size());
curr->contents.end = live;
scanLivenessThroughActions(curr->contents.actions, live);
// liveness is now calculated at the start. if something
// changed, all predecessor blocks need recomputation
- if (curr->contents.start == live)
+ if (curr->contents.start == live) {
continue;
+ }
assert(curr->contents.start.size() < live.size());
curr->contents.start = live;
for (auto* in : curr->in) {
@@ -226,8 +234,9 @@ struct LivenessWalker : public CFGWalker<SubType, VisitorType, Liveness> {
bool mergeStartsAndCheckChange(std::vector<BasicBlock*>& blocks,
LocalSet& old,
LocalSet& ret) {
- if (blocks.size() == 0)
+ if (blocks.size() == 0) {
return false;
+ }
ret = blocks[0]->contents.start;
if (blocks.size() > 1) {
// more than one, so we must merge
diff --git a/src/dataflow/graph.h b/src/dataflow/graph.h
index f93621a91..f41346857 100644
--- a/src/dataflow/graph.h
+++ b/src/dataflow/graph.h
@@ -110,13 +110,15 @@ struct Graph : public UnifiedExpressionVisitor<Graph, Node*> {
module = moduleInit;
auto numLocals = func->getNumLocals();
- if (numLocals == 0)
+ if (numLocals == 0) {
return; // nothing to do
+ }
// Set up initial local state IR.
setInReachable();
for (Index i = 0; i < numLocals; i++) {
- if (!isRelevantType(func->getLocalType(i)))
+ if (!isRelevantType(func->getLocalType(i))) {
continue;
+ }
Node* node;
auto type = func->getLocalType(i);
if (func->isParam(i)) {
@@ -167,8 +169,9 @@ struct Graph : public UnifiedExpressionVisitor<Graph, Node*> {
assert(!node->isBad());
Builder builder(*module);
auto type = node->getWasmType();
- if (!isConcreteType(type))
+ if (!isConcreteType(type)) {
return &bad;
+ }
auto* zero = makeZero(type);
auto* expr = builder.makeBinary(
Abstract::getBinary(type, equal ? Abstract::Eq : Abstract::Ne),
@@ -313,8 +316,9 @@ struct Graph : public UnifiedExpressionVisitor<Graph, Node*> {
auto& breaks = breakStates[curr->name];
// Phis are possible, check for them.
for (Index i = 0; i < numLocals; i++) {
- if (!isRelevantType(func->getLocalType(i)))
+ if (!isRelevantType(func->getLocalType(i))) {
continue;
+ }
bool needPhi = false;
// We replaced the proper value with a Var. If it's still that
// Var - or it's the original proper value, which can happen with
@@ -420,8 +424,9 @@ struct Graph : public UnifiedExpressionVisitor<Graph, Node*> {
// These are ok as-is.
// Check if our child is supported.
auto* value = expandFromI1(visit(curr->value), curr);
- if (value->isBad())
+ if (value->isBad()) {
return value;
+ }
// Great, we are supported!
auto* ret = addNode(Node::makeExpr(curr, curr));
ret->addValue(value);
@@ -432,8 +437,9 @@ struct Graph : public UnifiedExpressionVisitor<Graph, Node*> {
// These can be implemented using a binary.
// Check if our child is supported.
auto* value = expandFromI1(visit(curr->value), curr);
- if (value->isBad())
+ if (value->isBad()) {
return value;
+ }
// Great, we are supported!
return makeZeroComp(value, true, curr);
}
@@ -491,11 +497,13 @@ struct Graph : public UnifiedExpressionVisitor<Graph, Node*> {
// These are ok as-is.
// Check if our children are supported.
auto* left = expandFromI1(visit(curr->left), curr);
- if (left->isBad())
+ if (left->isBad()) {
return left;
+ }
auto* right = expandFromI1(visit(curr->right), curr);
- if (right->isBad())
+ if (right->isBad()) {
return right;
+ }
// Great, we are supported!
auto* ret = addNode(Node::makeExpr(curr, curr));
ret->addValue(left);
@@ -556,14 +564,17 @@ struct Graph : public UnifiedExpressionVisitor<Graph, Node*> {
}
Node* doVisitSelect(Select* curr) {
auto* ifTrue = expandFromI1(visit(curr->ifTrue), curr);
- if (ifTrue->isBad())
+ if (ifTrue->isBad()) {
return ifTrue;
+ }
auto* ifFalse = expandFromI1(visit(curr->ifFalse), curr);
- if (ifFalse->isBad())
+ if (ifFalse->isBad()) {
return ifFalse;
+ }
auto* condition = ensureI1(visit(curr->condition), curr);
- if (condition->isBad())
+ if (condition->isBad()) {
return condition;
+ }
// Great, we are supported!
auto* ret = addNode(Node::makeExpr(curr, curr));
ret->addValue(condition);
@@ -661,8 +672,9 @@ struct Graph : public UnifiedExpressionVisitor<Graph, Node*> {
Index numLocals = func->getNumLocals();
Node* block = nullptr;
for (Index i = 0; i < numLocals; i++) {
- if (!isRelevantType(func->getLocalType(i)))
+ if (!isRelevantType(func->getLocalType(i))) {
continue;
+ }
// Process the inputs. If any is bad, the phi is bad.
bool bad = false;
for (auto& state : states) {
@@ -673,8 +685,9 @@ struct Graph : public UnifiedExpressionVisitor<Graph, Node*> {
break;
}
}
- if (bad)
+ if (bad) {
continue;
+ }
// Nothing is bad, proceed.
Node* first = nullptr;
for (auto& state : states) {
@@ -724,16 +737,18 @@ struct Graph : public UnifiedExpressionVisitor<Graph, Node*> {
// the set.
SetLocal* getSet(Node* node) {
auto iter = nodeParentMap.find(node);
- if (iter == nodeParentMap.end())
+ if (iter == nodeParentMap.end()) {
return nullptr;
+ }
return iter->second->dynCast<SetLocal>();
}
// Given an expression, return the parent if such exists.
Expression* getParent(Expression* curr) {
auto iter = expressionParentMap.find(curr);
- if (iter == expressionParentMap.end())
+ if (iter == expressionParentMap.end()) {
return nullptr;
+ }
return iter->second;
}
diff --git a/src/dataflow/node.h b/src/dataflow/node.h
index 8977ab41c..2966034ac 100644
--- a/src/dataflow/node.h
+++ b/src/dataflow/node.h
@@ -170,8 +170,9 @@ struct Node {
}
bool operator==(const Node& other) {
- if (type != other.type)
+ if (type != other.type) {
return false;
+ }
switch (type) {
case Var:
case Block:
@@ -183,15 +184,18 @@ struct Node {
break;
}
case Cond:
- if (index != other.index)
+ if (index != other.index) {
return false;
+ }
default: {}
}
- if (values.size() != other.values.size())
+ if (values.size() != other.values.size()) {
return false;
+ }
for (Index i = 0; i < values.size(); i++) {
- if (*(values[i]) != *(other.values[i]))
+ if (*(values[i]) != *(other.values[i])) {
return false;
+ }
}
return true;
}
diff --git a/src/dataflow/utils.h b/src/dataflow/utils.h
index 337dfec5e..4408c6080 100644
--- a/src/dataflow/utils.h
+++ b/src/dataflow/utils.h
@@ -35,8 +35,9 @@ namespace DataFlow {
inline std::ostream& dump(Node* node, std::ostream& o, size_t indent = 0) {
auto doIndent = [&]() {
- for (size_t i = 0; i < indent; i++)
+ for (size_t i = 0; i < indent; i++) {
o << ' ';
+ }
};
doIndent();
o << '[' << node << ' ';
diff --git a/src/emscripten-optimizer/istring.h b/src/emscripten-optimizer/istring.h
index 320a3e590..21f94fcb9 100644
--- a/src/emscripten-optimizer/istring.h
+++ b/src/emscripten-optimizer/istring.h
@@ -136,12 +136,15 @@ struct IString {
const char* stripPrefix(const char* prefix) const {
const char* ptr = str;
while (true) {
- if (*prefix == 0)
+ if (*prefix == 0) {
return ptr;
- if (*ptr == 0)
+ }
+ if (*ptr == 0) {
return nullptr;
- if (*ptr++ != *prefix++)
+ }
+ if (*ptr++ != *prefix++) {
return nullptr;
+ }
}
}
@@ -191,11 +194,13 @@ public:
strncpy(curr, init, size);
while (1) {
char* end = strchr(curr, ' ');
- if (end)
+ if (end) {
*end = 0;
+ }
insert(curr);
- if (!end)
+ if (!end) {
break;
+ }
curr = end + 1;
}
}
diff --git a/src/emscripten-optimizer/optimizer-shared.cpp b/src/emscripten-optimizer/optimizer-shared.cpp
index 3ac3ca7ea..172b9f45f 100644
--- a/src/emscripten-optimizer/optimizer-shared.cpp
+++ b/src/emscripten-optimizer/optimizer-shared.cpp
@@ -61,27 +61,32 @@ AsmType detectType(Ref node,
if (node->isString()) {
if (asmData) {
AsmType ret = asmData->getType(node->getCString());
- if (ret != ASM_NONE)
+ if (ret != ASM_NONE) {
return ret;
+ }
}
if (!inVarDef) {
- if (node == INF || node == NaN)
+ if (node == INF || node == NaN) {
return ASM_DOUBLE;
- if (node == TEMP_RET0)
+ }
+ if (node == TEMP_RET0) {
return ASM_INT;
+ }
return ASM_NONE;
}
// We are in a variable definition, where Math_fround(0) optimized into a
// global constant becomes f0 = Math_fround(0)
- if (ASM_FLOAT_ZERO.isNull())
+ if (ASM_FLOAT_ZERO.isNull()) {
ASM_FLOAT_ZERO = node->getIString();
- else
+ } else {
assert(node == ASM_FLOAT_ZERO);
+ }
return ASM_FLOAT;
}
if (node->isNumber()) {
- if (!wasm::isInteger(node->getNumber()))
+ if (!wasm::isInteger(node->getNumber())) {
return ASM_DOUBLE;
+ }
return ASM_INT;
}
switch (node[0]->getCString()[0]) {
@@ -105,20 +110,21 @@ AsmType detectType(Ref node,
if (node[0] == CALL) {
if (node[1]->isString()) {
IString name = node[1]->getIString();
- if (name == MATH_FROUND || name == minifiedFround)
+ if (name == MATH_FROUND || name == minifiedFround) {
return ASM_FLOAT;
- else if (allowI64 && (name == INT64 || name == INT64_CONST))
+ } else if (allowI64 && (name == INT64 || name == INT64_CONST)) {
return ASM_INT64;
- else if (name == SIMD_FLOAT32X4 || name == SIMD_FLOAT32X4_CHECK)
+ } else if (name == SIMD_FLOAT32X4 || name == SIMD_FLOAT32X4_CHECK) {
return ASM_FLOAT32X4;
- else if (name == SIMD_FLOAT64X2 || name == SIMD_FLOAT64X2_CHECK)
+ } else if (name == SIMD_FLOAT64X2 || name == SIMD_FLOAT64X2_CHECK) {
return ASM_FLOAT64X2;
- else if (name == SIMD_INT8X16 || name == SIMD_INT8X16_CHECK)
+ } else if (name == SIMD_INT8X16 || name == SIMD_INT8X16_CHECK) {
return ASM_INT8X16;
- else if (name == SIMD_INT16X8 || name == SIMD_INT16X8_CHECK)
+ } else if (name == SIMD_INT16X8 || name == SIMD_INT16X8_CHECK) {
return ASM_INT16X8;
- else if (name == SIMD_INT32X4 || name == SIMD_INT32X4_CHECK)
+ } else if (name == SIMD_INT32X4 || name == SIMD_INT32X4_CHECK) {
return ASM_INT32X4;
+ }
}
return ASM_NONE;
} else if (node[0] == CONDITIONAL) {
@@ -155,8 +161,9 @@ AsmType detectType(Ref node,
} else if (node[0] == SUB) {
assert(node[1]->isString());
HeapInfo info = parseHeap(node[1][1]->getCString());
- if (info.valid)
+ if (info.valid) {
return ASM_NONE;
+ }
return info.floaty ? ASM_DOUBLE : ASM_INT; // XXX ASM_FLOAT?
}
break;
@@ -179,12 +186,15 @@ AsmSign detectSign(Ref node, IString minifiedFround) {
}
if (node->isNumber()) {
double value = node->getNumber();
- if (value < 0)
+ if (value < 0) {
return ASM_SIGNED;
- if (value > uint32_t(-1) || fmod(value, 1) != 0)
+ }
+ if (value > uint32_t(-1) || fmod(value, 1) != 0) {
return ASM_NONSIGNED;
- if (wasm::isSInteger32(value))
+ }
+ if (wasm::isSInteger32(value)) {
return ASM_FLEXIBLE;
+ }
return ASM_UNSIGNED;
}
IString type = node[0]->getIString();
@@ -192,8 +202,9 @@ AsmSign detectSign(Ref node, IString minifiedFround) {
IString op = node[1]->getIString();
switch (op.str[0]) {
case '>': {
- if (op == TRSHIFT)
+ if (op == TRSHIFT) {
return ASM_UNSIGNED;
+ }
} // fallthrough
case '|':
case '&':
@@ -228,8 +239,9 @@ AsmSign detectSign(Ref node, IString minifiedFround) {
return detectSign(node[2], minifiedFround);
} else if (type == CALL) {
if (node[1]->isString() &&
- (node[1] == MATH_FROUND || node[1] == minifiedFround))
+ (node[1] == MATH_FROUND || node[1] == minifiedFround)) {
return ASM_NONSIGNED;
+ }
} else if (type == SEQ) {
return detectSign(node[2], minifiedFround);
}
diff --git a/src/emscripten-optimizer/optimizer.h b/src/emscripten-optimizer/optimizer.h
index 36a9322fd..e30347025 100644
--- a/src/emscripten-optimizer/optimizer.h
+++ b/src/emscripten-optimizer/optimizer.h
@@ -64,8 +64,9 @@ struct AsmData {
AsmType getType(const cashew::IString& name) {
auto ret = locals.find(name);
- if (ret != locals.end())
+ if (ret != locals.end()) {
return ret->second.type;
+ }
return ASM_NONE;
}
void setType(const cashew::IString& name, AsmType type) {
diff --git a/src/emscripten-optimizer/parser.h b/src/emscripten-optimizer/parser.h
index d180ea12c..1d4cda79b 100644
--- a/src/emscripten-optimizer/parser.h
+++ b/src/emscripten-optimizer/parser.h
@@ -160,16 +160,19 @@ template<class NodeRef, class Builder> class Parser {
}
if (curr[0] == '/' && curr[1] == '/') {
curr += 2;
- while (*curr && *curr != '\n')
+ while (*curr && *curr != '\n') {
curr++;
- if (*curr)
+ }
+ if (*curr) {
curr++;
+ }
continue;
}
if (curr[0] == '/' && curr[1] == '*') {
curr += 2;
- while (*curr && (curr[0] != '*' || curr[1] != '/'))
+ while (*curr && (curr[0] != '*' || curr[1] != '/')) {
curr++;
+ }
curr += 2;
continue;
}
@@ -180,9 +183,11 @@ template<class NodeRef, class Builder> class Parser {
static bool isDigit(char x) { return x >= '0' && x <= '9'; }
static bool hasChar(const char* list, char x) {
- while (*list)
- if (*list++ == x)
+ while (*list) {
+ if (*list++ == x) {
return true;
+ }
+ }
return false;
}
@@ -247,8 +252,9 @@ template<class NodeRef, class Builder> class Parser {
} else if (*src >= 'A' && *src <= 'F') {
num *= 16;
num += *src - 'A' + 10;
- } else
+ } else {
break;
+ }
src++;
}
} else {
@@ -402,12 +408,15 @@ template<class NodeRef, class Builder> class Parser {
return parseExpression(parseFrag(frag), src, seps);
}
case SEPARATOR: {
- if (frag.str == OPEN_PAREN)
+ if (frag.str == OPEN_PAREN) {
return parseExpression(parseAfterParen(src), src, seps);
- if (frag.str == OPEN_BRACE)
+ }
+ if (frag.str == OPEN_BRACE) {
return parseExpression(parseAfterBrace(src), src, seps);
- if (frag.str == OPEN_CURLY)
+ }
+ if (frag.str == OPEN_CURLY) {
return parseExpression(parseAfterCurly(src), src, seps);
+ }
abort();
}
case OPERATOR: {
@@ -439,30 +448,31 @@ template<class NodeRef, class Builder> class Parser {
NodeRef parseAfterKeyword(Frag& frag, char*& src, const char* seps) {
skipSpace(src);
- if (frag.str == FUNCTION)
+ if (frag.str == FUNCTION) {
return parseFunction(src, seps);
- else if (frag.str == VAR)
+ } else if (frag.str == VAR) {
return parseVar(src, seps, false);
- else if (frag.str == CONST)
+ } else if (frag.str == CONST) {
return parseVar(src, seps, true);
- else if (frag.str == RETURN)
+ } else if (frag.str == RETURN) {
return parseReturn(src, seps);
- else if (frag.str == IF)
+ } else if (frag.str == IF) {
return parseIf(src, seps);
- else if (frag.str == DO)
+ } else if (frag.str == DO) {
return parseDo(src, seps);
- else if (frag.str == WHILE)
+ } else if (frag.str == WHILE) {
return parseWhile(src, seps);
- else if (frag.str == BREAK)
+ } else if (frag.str == BREAK) {
return parseBreak(src, seps);
- else if (frag.str == CONTINUE)
+ } else if (frag.str == CONTINUE) {
return parseContinue(src, seps);
- else if (frag.str == SWITCH)
+ } else if (frag.str == SWITCH) {
return parseSwitch(src, seps);
- else if (frag.str == NEW)
+ } else if (frag.str == NEW) {
return parseNew(src, seps);
- else if (frag.str == FOR)
+ } else if (frag.str == FOR) {
return parseFor(src, seps);
+ }
dump(frag.str.str, src);
abort();
return nullptr;
@@ -482,15 +492,17 @@ template<class NodeRef, class Builder> class Parser {
src++;
while (1) {
skipSpace(src);
- if (*src == ')')
+ if (*src == ')') {
break;
+ }
Frag arg(src);
assert(arg.type == IDENT);
src += arg.size;
Builder::appendArgumentToFunction(ret, arg.str);
skipSpace(src);
- if (*src == ')')
+ if (*src == ')') {
break;
+ }
if (*src == ',') {
src++;
continue;
@@ -507,8 +519,9 @@ template<class NodeRef, class Builder> class Parser {
NodeRef ret = Builder::makeVar(is_const);
while (1) {
skipSpace(src);
- if (*src == ';')
+ if (*src == ';') {
break;
+ }
Frag name(src);
assert(name.type == IDENT);
NodeRef value;
@@ -521,8 +534,9 @@ template<class NodeRef, class Builder> class Parser {
}
Builder::appendToVar(ret, name.str, value);
skipSpace(src);
- if (*src == ';')
+ if (*src == ';') {
break;
+ }
if (*src == ',') {
src++;
continue;
@@ -538,8 +552,9 @@ template<class NodeRef, class Builder> class Parser {
NodeRef value = !hasChar(seps, *src) ? parseElement(src, seps) : nullptr;
skipSpace(src);
assert(hasChar(seps, *src));
- if (*src == ';')
+ if (*src == ';') {
src++;
+ }
return Builder::makeReturn(value);
}
@@ -597,16 +612,18 @@ template<class NodeRef, class Builder> class Parser {
NodeRef parseBreak(char*& src, const char* seps) {
skipSpace(src);
Frag next(src);
- if (next.type == IDENT)
+ if (next.type == IDENT) {
src += next.size;
+ }
return Builder::makeBreak(next.type == IDENT ? next.str : IString());
}
NodeRef parseContinue(char*& src, const char* seps) {
skipSpace(src);
Frag next(src);
- if (next.type == IDENT)
+ if (next.type == IDENT) {
src += next.size;
+ }
return Builder::makeContinue(next.type == IDENT ? next.str : IString());
}
@@ -618,8 +635,9 @@ template<class NodeRef, class Builder> class Parser {
while (1) {
// find all cases and possibly a default
skipSpace(src);
- if (*src == '}')
+ if (*src == '}') {
break;
+ }
Frag next(src);
if (next.type == KEYWORD) {
if (next.str == CASE) {
@@ -681,10 +699,12 @@ template<class NodeRef, class Builder> class Parser {
NodeRef parseAfterIdent(Frag& frag, char*& src, const char* seps) {
skipSpace(src);
- if (*src == '(')
+ if (*src == '(') {
return parseExpression(parseCall(parseFrag(frag), src), src, seps);
- if (*src == '[')
+ }
+ if (*src == '[') {
return parseExpression(parseIndexing(parseFrag(frag), src), src, seps);
+ }
if (*src == ':' && expressionPartsStack.back().size() == 0) {
src++;
skipSpace(src);
@@ -697,8 +717,9 @@ template<class NodeRef, class Builder> class Parser {
}
return Builder::makeLabel(frag.str, inner);
}
- if (*src == '.')
+ if (*src == '.') {
return parseExpression(parseDotting(parseFrag(frag), src), src, seps);
+ }
return parseExpression(parseFrag(frag), src, seps);
}
@@ -709,12 +730,14 @@ template<class NodeRef, class Builder> class Parser {
NodeRef ret = Builder::makeCall(target);
while (1) {
skipSpace(src);
- if (*src == ')')
+ if (*src == ')') {
break;
+ }
Builder::appendToCall(ret, parseElement(src, ",)"));
skipSpace(src);
- if (*src == ')')
+ if (*src == ')') {
break;
+ }
if (*src == ',') {
src++;
continue;
@@ -767,13 +790,15 @@ template<class NodeRef, class Builder> class Parser {
while (1) {
skipSpace(src);
assert(*src);
- if (*src == ']')
+ if (*src == ']') {
break;
+ }
NodeRef element = parseElement(src, ",]");
Builder::appendToArray(ret, element);
skipSpace(src);
- if (*src == ']')
+ if (*src == ']') {
break;
+ }
if (*src == ',') {
src++;
continue;
@@ -790,8 +815,9 @@ template<class NodeRef, class Builder> class Parser {
while (1) {
skipSpace(src);
assert(*src);
- if (*src == '}')
+ if (*src == '}') {
break;
+ }
Frag key(src);
assert(key.type == IDENT || key.type == STRING);
src += key.size;
@@ -801,8 +827,9 @@ template<class NodeRef, class Builder> class Parser {
NodeRef value = parseElement(src, ",}");
Builder::appendToObject(ret, key.str, value);
skipSpace(src);
- if (*src == '}')
+ if (*src == '}') {
break;
+ }
if (*src == ',') {
src++;
continue;
@@ -868,8 +895,9 @@ template<class NodeRef, class Builder> class Parser {
parts.push_back(initial);
}
NodeRef last = parseElement(src, seps);
- if (!top)
+ if (!top) {
return last;
+ }
{
// |parts| may have been invalidated by that call
ExpressionParts& parts = expressionPartsStack.back();
@@ -880,11 +908,13 @@ template<class NodeRef, class Builder> class Parser {
if (ops.rtl) {
// right to left
for (int i = parts.size() - 1; i >= 0; i--) {
- if (parts[i].isNode)
+ if (parts[i].isNode) {
continue;
+ }
IString op = parts[i].getOp();
- if (!ops.ops.has(op))
+ if (!ops.ops.has(op)) {
continue;
+ }
if (ops.type == OperatorClass::Binary && i > 0 &&
i < (int)parts.size() - 1) {
parts[i] =
@@ -893,20 +923,23 @@ template<class NodeRef, class Builder> class Parser {
parts.erase(parts.begin() + i - 1);
} else if (ops.type == OperatorClass::Prefix &&
i < (int)parts.size() - 1) {
- if (i > 0 && parts[i - 1].isNode)
+ if (i > 0 && parts[i - 1].isNode) {
// cannot apply prefix operator if it would join two nodes
continue;
+ }
parts[i] = Builder::makePrefix(op, parts[i + 1].getNode());
parts.erase(parts.begin() + i + 1);
} else if (ops.type == OperatorClass::Tertiary) {
// we must be at X ? Y : Z
// ^
// dumpParts(parts, i);
- if (op != COLON)
+ if (op != COLON) {
continue;
+ }
assert(i < (int)parts.size() - 1 && i >= 3);
- if (parts[i - 2].getOp() != QUESTION)
+ if (parts[i - 2].getOp() != QUESTION) {
continue; // e.g. x ? y ? 1 : 0 : 2
+ }
parts[i - 3] = Builder::makeConditional(parts[i - 3].getNode(),
parts[i - 1].getNode(),
parts[i + 1].getNode());
@@ -918,11 +951,13 @@ template<class NodeRef, class Builder> class Parser {
} else {
// left to right
for (int i = 0; i < (int)parts.size(); i++) {
- if (parts[i].isNode)
+ if (parts[i].isNode) {
continue;
+ }
IString op = parts[i].getOp();
- if (!ops.ops.has(op))
+ if (!ops.ops.has(op)) {
continue;
+ }
if (ops.type == OperatorClass::Binary && i > 0 &&
i < (int)parts.size() - 1) {
parts[i] =
@@ -932,9 +967,10 @@ template<class NodeRef, class Builder> class Parser {
i--;
} else if (ops.type == OperatorClass::Prefix &&
i < (int)parts.size() - 1) {
- if (i > 0 && parts[i - 1].isNode)
+ if (i > 0 && parts[i - 1].isNode) {
// cannot apply prefix operator if it would join two nodes
continue;
+ }
parts[i] = Builder::makePrefix(op, parts[i + 1].getNode());
parts.erase(parts.begin() + i + 1);
// allow a previous prefix operator to cascade
@@ -960,23 +996,27 @@ template<class NodeRef, class Builder> class Parser {
// dump("parseBlock", src);
while (1) {
skipSpace(src);
- if (*src == 0)
+ if (*src == 0) {
break;
+ }
if (*src == ';') {
src++; // skip a statement in this block
continue;
}
- if (hasChar(seps, *src))
+ if (hasChar(seps, *src)) {
break;
+ }
if (!!keywordSep1) {
Frag next(src);
- if (next.type == KEYWORD && next.str == keywordSep1)
+ if (next.type == KEYWORD && next.str == keywordSep1) {
break;
+ }
}
if (!!keywordSep2) {
Frag next(src);
- if (next.type == KEYWORD && next.str == keywordSep2)
+ if (next.type == KEYWORD && next.str == keywordSep2) {
break;
+ }
}
NodeRef element = parseElementOrStatement(src, seps);
Builder::appendToBlock(block, element);
@@ -1061,12 +1101,14 @@ template<class NodeRef, class Builder> class Parser {
while (*curr) {
if (*curr == '\n') {
newlinesLeft--;
- if (newlinesLeft == 0)
+ if (newlinesLeft == 0) {
break;
+ }
}
charsLeft--;
- if (charsLeft == 0)
+ if (charsLeft == 0) {
break;
+ }
fprintf(stderr, "%c", *curr++);
}
fprintf(stderr, "\n\n");
diff --git a/src/emscripten-optimizer/simple_ast.cpp b/src/emscripten-optimizer/simple_ast.cpp
index 5853b3289..6afa0a66e 100644
--- a/src/emscripten-optimizer/simple_ast.cpp
+++ b/src/emscripten-optimizer/simple_ast.cpp
@@ -105,10 +105,11 @@ void Value::stringify(std::ostream& os, bool pretty) {
}
for (size_t i = 0; i < arr->size(); i++) {
if (i > 0) {
- if (pretty)
+ if (pretty) {
os << "," << std::endl;
- else
+ } else {
os << ", ";
+ }
}
indentify();
(*arr)[i]->stringify(os, pretty);
@@ -141,8 +142,9 @@ void Value::stringify(std::ostream& os, bool pretty) {
first = false;
} else {
os << ", ";
- if (pretty)
+ if (pretty) {
os << std::endl;
+ }
}
indentify();
os << '"' << i.first.c_str() << "\": ";
@@ -178,10 +180,11 @@ void Value::stringify(std::ostream& os, bool pretty) {
void dump(const char* str, Ref node, bool pretty) {
std::cerr << str << ": ";
- if (!!node)
+ if (!!node) {
node->stringify(std::cerr, pretty);
- else
+ } else {
std::cerr << "(nullptr)";
+ }
std::cerr << std::endl;
}
diff --git a/src/emscripten-optimizer/simple_ast.h b/src/emscripten-optimizer/simple_ast.h
index e4f2c1f86..bcfce9712 100644
--- a/src/emscripten-optimizer/simple_ast.h
+++ b/src/emscripten-optimizer/simple_ast.h
@@ -153,8 +153,9 @@ struct Value {
void free() {
if (type == Array) {
arr->clear();
- } else if (type == Object)
+ } else if (type == Object) {
delete obj;
+ }
type = Null;
num = 0;
}
@@ -286,8 +287,9 @@ struct Value {
}
bool operator==(const Value& other) {
- if (type != other.type)
+ if (type != other.type) {
return false;
+ }
switch (other.type) {
case String:
return str == other.str;
@@ -334,8 +336,9 @@ struct Value {
arr->push_back(temp);
curr = temp->parse(curr);
skip();
- if (*curr == ']')
+ if (*curr == ']') {
break;
+ }
assert(*curr == ',');
curr++;
skip();
@@ -377,8 +380,9 @@ struct Value {
curr = value->parse(curr);
(*obj)[key] = value;
skip();
- if (*curr == '}')
+ if (*curr == '}') {
break;
+ }
assert(*curr == ',');
curr++;
skip();
@@ -411,8 +415,9 @@ struct Value {
void setSize(size_t size) {
assert(isArray());
auto old = arr->size();
- if (old != size)
+ if (old != size) {
arr->resize(size);
+ }
if (old < size) {
for (auto i = old; i < size; i++) {
(*arr)[i] = arena.alloc<Value>();
@@ -439,8 +444,9 @@ struct Value {
Ref back() {
assert(isArray());
- if (arr->size() == 0)
+ if (arr->size() == 0) {
return nullptr;
+ }
return arr->back();
}
@@ -452,8 +458,9 @@ struct Value {
int indexOf(Ref other) {
assert(isArray());
for (size_t i = 0; i < arr->size(); i++) {
- if (other == (*arr)[i])
+ if (other == (*arr)[i]) {
return i;
+ }
}
return -1;
}
@@ -474,8 +481,9 @@ struct Value {
ret->setArray();
for (size_t i = 0; i < arr->size(); i++) {
Ref curr = (*arr)[i];
- if (func(curr))
+ if (func(curr)) {
ret->push_back(curr);
+ }
}
return ret;
}
@@ -586,8 +594,9 @@ struct JSPrinter {
void emit(char c) {
maybeSpace(c);
- if (!pretty && c == '}' && buffer[used - 1] == ';')
+ if (!pretty && c == '}' && buffer[used - 1] == ';') {
used--; // optimize ;} into }, the ; is not separating anything
+ }
ensure(1);
buffer[used++] = c;
}
@@ -601,30 +610,35 @@ struct JSPrinter {
}
void newline() {
- if (!pretty)
+ if (!pretty) {
return;
+ }
emit('\n');
- for (int i = 0; i < indent; i++)
+ for (int i = 0; i < indent; i++) {
emit(' ');
+ }
}
void space() {
- if (pretty)
+ if (pretty) {
emit(' ');
+ }
}
void safeSpace() {
- if (pretty)
+ if (pretty) {
emit(' ');
- else
+ } else {
possibleSpace = true;
+ }
}
void maybeSpace(char s) {
if (possibleSpace) {
possibleSpace = false;
- if (isIdentPart(s))
+ if (isIdentPart(s)) {
emit(' ');
+ }
}
}
@@ -635,15 +649,18 @@ struct JSPrinter {
bool isDefun(Ref node) { return node->isArray() && node[0] == DEFUN; }
bool endsInBlock(Ref node) {
- if (node->isArray() && node[0] == BLOCK)
+ if (node->isArray() && node[0] == BLOCK) {
return true;
+ }
// Check for a label on a block
- if (node->isArray() && node[0] == LABEL && endsInBlock(node[2]))
+ if (node->isArray() && node[0] == LABEL && endsInBlock(node[2])) {
return true;
+ }
// Check for an if
if (node->isArray() && node[0] == IF &&
- endsInBlock(ifHasElse(node) ? node[3] : node[2]))
+ endsInBlock(ifHasElse(node) ? node[3] : node[2])) {
return true;
+ }
return false;
}
@@ -670,119 +687,133 @@ struct JSPrinter {
IString type = node[0]->getIString();
switch (type.str[0]) {
case 'a': {
- if (type == ARRAY)
+ if (type == ARRAY) {
printArray(node);
- else
+ } else {
abort();
+ }
break;
}
case 'b': {
- if (type == BINARY)
+ if (type == BINARY) {
printBinary(node);
- else if (type == BLOCK)
+ } else if (type == BLOCK) {
printBlock(node);
- else if (type == BREAK)
+ } else if (type == BREAK) {
printBreak(node);
- else
+ } else {
abort();
+ }
break;
}
case 'c': {
- if (type == CALL)
+ if (type == CALL) {
printCall(node);
- else if (type == CONDITIONAL)
+ } else if (type == CONDITIONAL) {
printConditional(node);
- else if (type == CONTINUE)
+ } else if (type == CONTINUE) {
printContinue(node);
- else
+ } else {
abort();
+ }
break;
}
case 'd': {
- if (type == DEFUN)
+ if (type == DEFUN) {
printDefun(node);
- else if (type == DO)
+ } else if (type == DO) {
printDo(node);
- else if (type == DOT)
+ } else if (type == DOT) {
printDot(node);
- else
+ } else {
abort();
+ }
break;
}
case 'i': {
- if (type == IF)
+ if (type == IF) {
printIf(node);
- else
+ } else {
abort();
+ }
break;
}
case 'l': {
- if (type == LABEL)
+ if (type == LABEL) {
printLabel(node);
- else
+ } else {
abort();
+ }
break;
}
case 'n': {
- if (type == NEW)
+ if (type == NEW) {
printNew(node);
- else
+ } else {
abort();
+ }
break;
}
case 'o': {
- if (type == OBJECT)
+ if (type == OBJECT) {
printObject(node);
+ }
break;
}
case 'r': {
- if (type == RETURN)
+ if (type == RETURN) {
printReturn(node);
- else
+ } else {
abort();
+ }
break;
}
case 's': {
- if (type == SUB)
+ if (type == SUB) {
printSub(node);
- else if (type == SEQ)
+ } else if (type == SEQ) {
printSeq(node);
- else if (type == SWITCH)
+ } else if (type == SWITCH) {
printSwitch(node);
- else if (type == STRING)
+ } else if (type == STRING) {
printString(node);
- else
+ } else {
abort();
+ }
break;
}
case 't': {
- if (type == TOPLEVEL)
+ if (type == TOPLEVEL) {
printToplevel(node);
- else if (type == TRY)
+ } else if (type == TRY) {
printTry(node);
- else
+ } else {
abort();
+ }
break;
}
case 'u': {
- if (type == UNARY_PREFIX)
+ if (type == UNARY_PREFIX) {
printUnaryPrefix(node);
- else
+ } else {
abort();
+ }
break;
}
case 'v': {
- if (type == VAR)
+ if (type == VAR) {
printVar(node);
- else
+ } else {
abort();
+ }
break;
}
case 'w': {
- if (type == WHILE)
+ if (type == WHILE) {
printWhile(node);
- else
+ } else {
abort();
+ }
break;
}
default: {
@@ -796,8 +827,9 @@ struct JSPrinter {
void print(Ref node, const char* otherwise) {
auto last = used;
print(node);
- if (used == last)
+ if (used == last) {
emit(otherwise);
+ }
}
void printStats(Ref stats) {
@@ -805,10 +837,11 @@ struct JSPrinter {
for (size_t i = 0; i < stats->size(); i++) {
Ref curr = stats[i];
if (!isNothing(curr)) {
- if (first)
+ if (first) {
first = false;
- else
+ } else {
newline();
+ }
print(curr);
if (!isDefun(curr) && !endsInBlock(curr) && !isIf(curr)) {
emit(';');
@@ -843,8 +876,9 @@ struct JSPrinter {
emit('(');
Ref args = node[2];
for (size_t i = 0; i < args->size(); i++) {
- if (i > 0)
+ if (i > 0) {
(pretty ? emit(", ") : emit(','));
+ }
emit(args[i]->getCString());
}
emit(')');
@@ -906,8 +940,9 @@ struct JSPrinter {
}
}
bool neg = d < 0;
- if (neg)
+ if (neg) {
d = -d;
+ }
// try to emit the fewest necessary characters
bool integer = fmod(d, 1) == 0;
#define BUFFERSIZE 1000
@@ -940,8 +975,9 @@ struct JSPrinter {
sscanf(buffer, "%lf", &temp);
// errv("%.18f, %.18e => %s => %.18f, %.18e (%d), ", d, d,
// buffer, temp, temp, temp == d);
- if (temp == d)
+ if (temp == d) {
break;
+ }
}
} else {
// integer
@@ -973,8 +1009,9 @@ struct JSPrinter {
if (dot) {
// remove trailing zeros
char* end = dot + 1;
- while (*end >= '0' && *end <= '9')
+ while (*end >= '0' && *end <= '9') {
end++;
+ }
end--;
while (*end == '0') {
char* copy = end;
@@ -999,8 +1036,9 @@ struct JSPrinter {
char* test = end;
// remove zeros, and also doubles can use at most 24 digits, we can
// truncate any extras even if not zero
- while ((*test == '0' || test - buffer > 24) && test > buffer)
+ while ((*test == '0' || test - buffer > 24) && test > buffer) {
test--;
+ }
int num = end - test;
if (num >= 3) {
test++;
@@ -1092,10 +1130,12 @@ struct JSPrinter {
int parentPrecedence = getPrecedence(parent, true);
int childPrecedence = getPrecedence(child, false);
- if (childPrecedence > parentPrecedence)
+ if (childPrecedence > parentPrecedence) {
return true; // child is definitely a danger
- if (childPrecedence < parentPrecedence)
+ }
+ if (childPrecedence < parentPrecedence) {
return false; // definitely cool
+ }
// equal precedence, so associativity (rtl/ltr) is what matters
// (except for some exceptions, where multiple operators can combine into
// confusion)
@@ -1106,24 +1146,29 @@ struct JSPrinter {
return true;
}
}
- if (childPosition == 0)
+ if (childPosition == 0) {
return true; // child could be anywhere, so always paren
- if (childPrecedence < 0)
+ }
+ if (childPrecedence < 0) {
return false; // both precedences are safe
+ }
// check if child is on the dangerous side
- if (OperatorClass::getRtl(parentPrecedence))
+ if (OperatorClass::getRtl(parentPrecedence)) {
return childPosition < 0;
- else
+ } else {
return childPosition > 0;
+ }
}
void printChild(Ref child, Ref parent, int childPosition = 0) {
bool parens = needParens(parent, child, childPosition);
- if (parens)
+ if (parens) {
emit('(');
+ }
print(child);
- if (parens)
+ if (parens) {
emit(')');
+ }
}
void printBinary(Ref node) {
@@ -1145,12 +1190,15 @@ struct JSPrinter {
ensure(1); // we temporarily append a 0
char* curr = buffer + last; // ensure might invalidate
buffer[used] = 0;
- if (strstr(curr, "infinity"))
+ if (strstr(curr, "infinity")) {
return;
- if (strstr(curr, "nan"))
+ }
+ if (strstr(curr, "nan")) {
return;
- if (strchr(curr, '.'))
+ }
+ if (strchr(curr, '.')) {
return; // already a decimal point, all good
+ }
char* e = strchr(curr, 'e');
if (!e) {
emit(".0");
@@ -1193,8 +1241,9 @@ struct JSPrinter {
emit('(');
Ref args = node[2];
for (size_t i = 0; i < args->size(); i++) {
- if (i > 0)
+ if (i > 0) {
(pretty ? emit(", ") : emit(','));
+ }
printChild(args[i], node, 0);
}
emit(')');
@@ -1238,10 +1287,11 @@ struct JSPrinter {
auto curr = used;
printStats(c[1]);
indent--;
- if (curr != used)
+ if (curr != used) {
newline();
- else
+ } else {
used--; // avoid the extra indentation we added tentatively
+ }
} else {
newline();
}
@@ -1269,8 +1319,9 @@ struct JSPrinter {
emit("var ");
Ref args = node[1];
for (size_t i = 0; i < args->size(); i++) {
- if (i > 0)
+ if (i > 0) {
(pretty ? emit(", ") : emit(','));
+ }
emit(args[i][0]->getCString());
if (args[i]->size() > 1) {
space();
@@ -1377,8 +1428,9 @@ struct JSPrinter {
emit('[');
Ref args = node[1];
for (size_t i = 0; i < args->size(); i++) {
- if (i > 0)
+ if (i > 0) {
(pretty ? emit(", ") : emit(','));
+ }
print(args[i]);
}
emit(']');
@@ -1413,11 +1465,13 @@ struct JSPrinter {
}
check++;
}
- if (needQuote)
+ if (needQuote) {
emit('"');
+ }
emit(str);
- if (needQuote)
+ if (needQuote) {
emit('"');
+ }
emit(":");
space();
print(args[i][1]);
@@ -1467,8 +1521,9 @@ public:
target[1]->setArray(block[1]->getArray());
} else if (target[0] == DEFUN) {
target[3]->setArray(block[1]->getArray());
- } else
+ } else {
abort();
+ }
}
static void appendToBlock(Ref block, Ref element) {
@@ -1583,8 +1638,9 @@ public:
static void appendToVar(Ref var, IString name, Ref value) {
assert(var[0] == VAR);
Ref array = &makeRawArray(1)->push_back(makeRawString(name));
- if (!!value)
+ if (!!value) {
array->push_back(value);
+ }
var[1]->push_back(array);
}
diff --git a/src/ir/ExpressionAnalyzer.cpp b/src/ir/ExpressionAnalyzer.cpp
index aaab9050c..de37cd08b 100644
--- a/src/ir/ExpressionAnalyzer.cpp
+++ b/src/ir/ExpressionAnalyzer.cpp
@@ -35,22 +35,26 @@ bool ExpressionAnalyzer::isResultUsed(ExpressionStack& stack, Function* func) {
if (curr->is<Block>()) {
auto* block = curr->cast<Block>();
for (size_t j = 0; j < block->list.size() - 1; j++) {
- if (block->list[j] == above)
+ if (block->list[j] == above) {
return false;
+ }
}
assert(block->list.back() == above);
// continue down
} else if (curr->is<If>()) {
auto* iff = curr->cast<If>();
- if (above == iff->condition)
+ if (above == iff->condition) {
return true;
- if (!iff->ifFalse)
+ }
+ if (!iff->ifFalse) {
return false;
+ }
assert(above == iff->ifTrue || above == iff->ifFalse);
// continue down
} else {
- if (curr->is<Drop>())
+ if (curr->is<Drop>()) {
return false;
+ }
return true; // all other node types use the result
}
}
@@ -66,23 +70,27 @@ bool ExpressionAnalyzer::isResultDropped(ExpressionStack& stack) {
if (curr->is<Block>()) {
auto* block = curr->cast<Block>();
for (size_t j = 0; j < block->list.size() - 1; j++) {
- if (block->list[j] == above)
+ if (block->list[j] == above) {
return false;
+ }
}
assert(block->list.back() == above);
// continue down
} else if (curr->is<If>()) {
auto* iff = curr->cast<If>();
- if (above == iff->condition)
+ if (above == iff->condition) {
return false;
- if (!iff->ifFalse)
+ }
+ if (!iff->ifFalse) {
return false;
+ }
assert(above == iff->ifTrue || above == iff->ifFalse);
// continue down
} else {
- if (curr->is<Drop>())
+ if (curr->is<Drop>()) {
return true; // dropped
- return false; // all other node types use the result
+ }
+ return false; // all other node types use the result
}
}
return false;
@@ -238,8 +246,9 @@ bool ExpressionAnalyzer::flexibleEqual(Expression* left,
// Comparison is by value, except for names, which must match.
bool operator==(const Immediates& other) {
- if (scopeNames.size() != other.scopeNames.size())
+ if (scopeNames.size() != other.scopeNames.size()) {
return false;
+ }
for (Index i = 0; i < scopeNames.size(); i++) {
auto leftName = scopeNames[i];
auto rightName = other.scopeNames[i];
@@ -254,18 +263,24 @@ bool ExpressionAnalyzer::flexibleEqual(Expression* left,
return false;
}
}
- if (nonScopeNames != other.nonScopeNames)
+ if (nonScopeNames != other.nonScopeNames) {
return false;
- if (ints != other.ints)
+ }
+ if (ints != other.ints) {
return false;
- if (literals != other.literals)
+ }
+ if (literals != other.literals) {
return false;
- if (types != other.types)
+ }
+ if (types != other.types) {
return false;
- if (indexes != other.indexes)
+ }
+ if (indexes != other.indexes) {
return false;
- if (addresses != other.addresses)
+ }
+ if (addresses != other.addresses) {
return false;
+ }
return true;
}
@@ -283,8 +298,9 @@ bool ExpressionAnalyzer::flexibleEqual(Expression* left,
};
bool noteNames(Name left, Name right) {
- if (left.is() != right.is())
+ if (left.is() != right.is()) {
return false;
+ }
if (left.is()) {
assert(rightNames.find(left) == rightNames.end());
rightNames[left] = right;
@@ -306,28 +322,35 @@ bool ExpressionAnalyzer::flexibleEqual(Expression* left,
leftStack.pop_back();
right = rightStack.back();
rightStack.pop_back();
- if (!left != !right)
+ if (!left != !right) {
return false;
- if (!left)
+ }
+ if (!left) {
continue;
- if (comparer(left, right))
+ }
+ if (comparer(left, right)) {
continue; // comparison hook, before all the rest
+ }
// continue with normal structural comparison
- if (left->_id != right->_id)
+ if (left->_id != right->_id) {
return false;
+ }
// Blocks and loops introduce scoping.
if (auto* block = left->dynCast<Block>()) {
- if (!noteNames(block->name, right->cast<Block>()->name))
+ if (!noteNames(block->name, right->cast<Block>()->name)) {
return false;
+ }
} else if (auto* loop = left->dynCast<Loop>()) {
- if (!noteNames(loop->name, right->cast<Loop>()->name))
+ if (!noteNames(loop->name, right->cast<Loop>()->name)) {
return false;
+ }
} else {
// For all other nodes, compare their immediate values
visitImmediates(left, leftImmediates);
visitImmediates(right, rightImmediates);
- if (leftImmediates != rightImmediates)
+ if (leftImmediates != rightImmediates) {
return false;
+ }
leftImmediates.clear();
rightImmediates.clear();
}
@@ -343,11 +366,13 @@ bool ExpressionAnalyzer::flexibleEqual(Expression* left,
}
// The number of child nodes must match (e.g. return has an optional
// one).
- if (counter != 0)
+ if (counter != 0) {
return false;
+ }
}
- if (leftStack.size() > 0 || rightStack.size() > 0)
+ if (leftStack.size() > 0 || rightStack.size() > 0) {
return false;
+ }
return true;
}
};
@@ -377,8 +402,9 @@ HashType ExpressionAnalyzer::hash(Expression* curr) {
while (stack.size() > 0) {
curr = stack.back();
stack.pop_back();
- if (!curr)
+ if (!curr) {
continue;
+ }
hash(curr->_id);
// we often don't need to hash the type, as it is tied to other values
// we are hashing anyhow, but there are exceptions: for example, a
diff --git a/src/ir/ExpressionManipulator.cpp b/src/ir/ExpressionManipulator.cpp
index 6d35ef97f..fcdfdf152 100644
--- a/src/ir/ExpressionManipulator.cpp
+++ b/src/ir/ExpressionManipulator.cpp
@@ -34,11 +34,13 @@ flexibleCopy(Expression* original, Module& wasm, CustomCopier custom) {
: wasm(wasm), custom(custom), builder(wasm) {}
Expression* copy(Expression* curr) {
- if (!curr)
+ if (!curr) {
return nullptr;
+ }
auto* ret = custom(curr);
- if (ret)
+ if (ret) {
return ret;
+ }
return Visitor<Copier, Expression*>::visit(curr);
}
diff --git a/src/ir/LocalGraph.cpp b/src/ir/LocalGraph.cpp
index 1a2ccc0a2..a66009ec2 100644
--- a/src/ir/LocalGraph.cpp
+++ b/src/ir/LocalGraph.cpp
@@ -58,8 +58,9 @@ struct Flower : public CFGWalker<Flower, Visitor<Flower>, Info> {
static void doVisitGetLocal(Flower* self, Expression** currp) {
auto* curr = (*currp)->cast<GetLocal>();
// if in unreachable code, skip
- if (!self->currBasicBlock)
+ if (!self->currBasicBlock) {
return;
+ }
self->currBasicBlock->contents.actions.emplace_back(curr);
self->locations[curr] = currp;
}
@@ -67,8 +68,9 @@ struct Flower : public CFGWalker<Flower, Visitor<Flower>, Info> {
static void doVisitSetLocal(Flower* self, Expression** currp) {
auto* curr = (*currp)->cast<SetLocal>();
// if in unreachable code, skip
- if (!self->currBasicBlock)
+ if (!self->currBasicBlock) {
return;
+ }
self->currBasicBlock->contents.actions.emplace_back(curr);
self->currBasicBlock->contents.lastSets[curr->index] = curr;
self->locations[curr] = currp;
@@ -119,8 +121,9 @@ struct Flower : public CFGWalker<Flower, Visitor<Flower>, Info> {
auto& block = basicBlocks[i];
auto& flowBlock = flowBlocks[i];
// Get the equivalent block to entry in the flow list
- if (block.get() == entry)
+ if (block.get() == entry) {
entryFlowBlock = &flowBlock;
+ }
flowBlock.lastTraversedIteration = NULL_ITERATION;
flowBlock.actions.swap(block->contents.actions);
// Map in block to flow blocks
@@ -171,8 +174,9 @@ struct Flower : public CFGWalker<Flower, Visitor<Flower>, Info> {
// can do that for all gets as a whole, they will get the same results.
for (Index index = 0; index < numLocals; index++) {
auto& gets = allGets[index];
- if (gets.empty())
+ if (gets.empty()) {
continue;
+ }
work.push_back(&block);
// Note that we may need to revisit the later parts of this initial
// block, if we are in a loop, so don't mark it as seen.
diff --git a/src/ir/ReFinalize.cpp b/src/ir/ReFinalize.cpp
index 2bf68970d..ca058e2be 100644
--- a/src/ir/ReFinalize.cpp
+++ b/src/ir/ReFinalize.cpp
@@ -91,8 +91,9 @@ void ReFinalize::visitBlock(Block* curr) {
return;
}
}
- if (curr->type == unreachable)
+ if (curr->type == unreachable) {
return;
+ }
// type is none, but we might be unreachable
if (curr->type == none) {
for (auto* child : curr->list) {
diff --git a/src/ir/bits.h b/src/ir/bits.h
index a2b8fcde4..faae4c723 100644
--- a/src/ir/bits.h
+++ b/src/ir/bits.h
@@ -27,8 +27,9 @@ struct Bits {
// get a mask to keep only the low # of bits
static int32_t lowBitMask(int32_t bits) {
uint32_t ret = -1;
- if (bits >= 32)
+ if (bits >= 32) {
return ret;
+ }
return ret >> (32 - bits);
}
@@ -36,14 +37,17 @@ struct Bits {
// bit, and all zeros from there. returns the number of masked bits, or 0 if
// this is not such a mask
static uint32_t getMaskedBits(uint32_t mask) {
- if (mask == uint32_t(-1))
+ if (mask == uint32_t(-1)) {
return 32; // all the bits
- if (mask == 0)
+ }
+ if (mask == 0) {
return 0; // trivially not a mask
+ }
// otherwise, see if adding one turns this into a 1-bit thing, 00011111 + 1
// => 00100000
- if (PopCount(mask + 1) != 1)
+ if (PopCount(mask + 1) != 1) {
return 0;
+ }
// this is indeed a mask
return 32 - CountLeadingZeroes(mask);
}
diff --git a/src/ir/branch-utils.h b/src/ir/branch-utils.h
index f62941e15..ce7d7b0f6 100644
--- a/src/ir/branch-utils.h
+++ b/src/ir/branch-utils.h
@@ -155,47 +155,57 @@ struct BranchSeeker : public PostWalker<BranchSeeker> {
void noteFound(Expression* value) {
found++;
- if (found == 1)
+ if (found == 1) {
valueType = unreachable;
- if (!value)
+ }
+ if (!value) {
valueType = none;
- else if (value->type != unreachable)
+ } else if (value->type != unreachable) {
valueType = value->type;
+ }
}
void visitBreak(Break* curr) {
if (!named) {
// ignore an unreachable break
- if (curr->condition && curr->condition->type == unreachable)
+ if (curr->condition && curr->condition->type == unreachable) {
return;
- if (curr->value && curr->value->type == unreachable)
+ }
+ if (curr->value && curr->value->type == unreachable) {
return;
+ }
}
// check the break
- if (curr->name == target)
+ if (curr->name == target) {
noteFound(curr->value);
+ }
}
void visitSwitch(Switch* curr) {
if (!named) {
// ignore an unreachable switch
- if (curr->condition->type == unreachable)
+ if (curr->condition->type == unreachable) {
return;
- if (curr->value && curr->value->type == unreachable)
+ }
+ if (curr->value && curr->value->type == unreachable) {
return;
+ }
}
// check the switch
for (auto name : curr->targets) {
- if (name == target)
+ if (name == target) {
noteFound(curr->value);
+ }
}
- if (curr->default_ == target)
+ if (curr->default_ == target) {
noteFound(curr->value);
+ }
}
static bool hasReachable(Expression* tree, Name target) {
- if (!target.is())
+ if (!target.is()) {
return false;
+ }
BranchSeeker seeker(target);
seeker.named = false;
seeker.walk(tree);
@@ -203,8 +213,9 @@ struct BranchSeeker : public PostWalker<BranchSeeker> {
}
static Index countReachable(Expression* tree, Name target) {
- if (!target.is())
+ if (!target.is()) {
return 0;
+ }
BranchSeeker seeker(target);
seeker.named = false;
seeker.walk(tree);
@@ -212,16 +223,18 @@ struct BranchSeeker : public PostWalker<BranchSeeker> {
}
static bool hasNamed(Expression* tree, Name target) {
- if (!target.is())
+ if (!target.is()) {
return false;
+ }
BranchSeeker seeker(target);
seeker.walk(tree);
return seeker.found > 0;
}
static Index countNamed(Expression* tree, Name target) {
- if (!target.is())
+ if (!target.is()) {
return 0;
+ }
BranchSeeker seeker(target);
seeker.walk(tree);
return seeker.found;
diff --git a/src/ir/cost.h b/src/ir/cost.h
index 95c2178d9..5e09ee90e 100644
--- a/src/ir/cost.h
+++ b/src/ir/cost.h
@@ -33,8 +33,9 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
Index visitBlock(Block* curr) {
Index ret = 0;
- for (auto* child : curr->list)
+ for (auto* child : curr->list) {
ret += visit(child);
+ }
return ret;
}
Index visitIf(If* curr) {
@@ -52,14 +53,16 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
// XXX this does not take into account if the call is to an import, which
// may be costlier in general
Index ret = 4;
- for (auto* child : curr->operands)
+ for (auto* child : curr->operands) {
ret += visit(child);
+ }
return ret;
}
Index visitCallIndirect(CallIndirect* curr) {
Index ret = 6 + visit(curr->target);
- for (auto* child : curr->operands)
+ for (auto* child : curr->operands) {
ret += visit(child);
+ }
return ret;
}
Index visitGetLocal(GetLocal* curr) { return 0; }
diff --git a/src/ir/effects.h b/src/ir/effects.h
index 9a3f29d8a..bbcce07de 100644
--- a/src/ir/effects.h
+++ b/src/ir/effects.h
@@ -30,8 +30,9 @@ struct EffectAnalyzer
EffectAnalyzer(PassOptions& passOptions, Expression* ast = nullptr) {
ignoreImplicitTraps = passOptions.ignoreImplicitTraps;
debugInfo = passOptions.debugInfo;
- if (ast)
+ if (ast) {
analyze(ast);
+ }
}
bool ignoreImplicitTraps;
@@ -41,8 +42,9 @@ struct EffectAnalyzer
breakNames.clear();
walk(ast);
// if we are left with breaks, they are external
- if (breakNames.size() > 0)
+ if (breakNames.size() > 0) {
branches = true;
+ }
}
// Core effect tracking
@@ -115,8 +117,9 @@ struct EffectAnalyzer
}
}
for (auto local : localsRead) {
- if (other.localsWritten.count(local))
+ if (other.localsWritten.count(local)) {
return true;
+ }
}
if ((accessesGlobal() && other.calls) ||
(other.accessesGlobal() && calls)) {
@@ -129,8 +132,9 @@ struct EffectAnalyzer
}
}
for (auto global : globalsRead) {
- if (other.globalsWritten.count(global))
+ if (other.globalsWritten.count(global)) {
return true;
+ }
}
// we are ok to reorder implicit traps, but not conditionalize them
if ((implicitTrap && other.branches) || (other.implicitTrap && branches)) {
@@ -151,14 +155,18 @@ struct EffectAnalyzer
writesMemory = writesMemory || other.writesMemory;
implicitTrap = implicitTrap || other.implicitTrap;
isAtomic = isAtomic || other.isAtomic;
- for (auto i : other.localsRead)
+ for (auto i : other.localsRead) {
localsRead.insert(i);
- for (auto i : other.localsWritten)
+ }
+ for (auto i : other.localsWritten) {
localsWritten.insert(i);
- for (auto i : other.globalsRead)
+ }
+ for (auto i : other.globalsRead) {
globalsRead.insert(i);
- for (auto i : other.globalsWritten)
+ }
+ for (auto i : other.globalsWritten) {
globalsWritten.insert(i);
+ }
}
// the checks above happen after the node's children were processed, in the
@@ -183,13 +191,15 @@ struct EffectAnalyzer
std::set<Name> breakNames;
void visitBlock(Block* curr) {
- if (curr->name.is())
+ if (curr->name.is()) {
breakNames.erase(curr->name); // these were internal breaks
+ }
}
void visitIf(If* curr) {}
void visitLoop(Loop* curr) {
- if (curr->name.is())
+ if (curr->name.is()) {
breakNames.erase(curr->name); // these were internal breaks
+ }
// if the loop is unreachable, then there is branching control flow:
// (1) if the body is unreachable because of a (return), uncaught (br)
// etc., then we already noted branching, so it is ok to mark it again
@@ -228,28 +238,32 @@ struct EffectAnalyzer
void visitLoad(Load* curr) {
readsMemory = true;
isAtomic |= curr->isAtomic;
- if (!ignoreImplicitTraps)
+ if (!ignoreImplicitTraps) {
implicitTrap = true;
+ }
}
void visitStore(Store* curr) {
writesMemory = true;
isAtomic |= curr->isAtomic;
- if (!ignoreImplicitTraps)
+ if (!ignoreImplicitTraps) {
implicitTrap = true;
+ }
}
void visitAtomicRMW(AtomicRMW* curr) {
readsMemory = true;
writesMemory = true;
isAtomic = true;
- if (!ignoreImplicitTraps)
+ if (!ignoreImplicitTraps) {
implicitTrap = true;
+ }
}
void visitAtomicCmpxchg(AtomicCmpxchg* curr) {
readsMemory = true;
writesMemory = true;
isAtomic = true;
- if (!ignoreImplicitTraps)
+ if (!ignoreImplicitTraps) {
implicitTrap = true;
+ }
}
void visitAtomicWait(AtomicWait* curr) {
readsMemory = true;
@@ -258,8 +272,9 @@ struct EffectAnalyzer
// write.
writesMemory = true;
isAtomic = true;
- if (!ignoreImplicitTraps)
+ if (!ignoreImplicitTraps) {
implicitTrap = true;
+ }
}
void visitAtomicNotify(AtomicNotify* curr) {
// AtomicNotify doesn't strictly write memory, but it does modify the
@@ -268,8 +283,9 @@ struct EffectAnalyzer
readsMemory = true;
writesMemory = true;
isAtomic = true;
- if (!ignoreImplicitTraps)
+ if (!ignoreImplicitTraps) {
implicitTrap = true;
+ }
};
void visitSIMDExtract(SIMDExtract* curr) {}
void visitSIMDReplace(SIMDReplace* curr) {}
@@ -278,25 +294,29 @@ struct EffectAnalyzer
void visitSIMDShift(SIMDShift* curr) {}
void visitMemoryInit(MemoryInit* curr) {
writesMemory = true;
- if (!ignoreImplicitTraps)
+ if (!ignoreImplicitTraps) {
implicitTrap = true;
+ }
}
void visitDataDrop(DataDrop* curr) {
// prevent reordering with memory.init
readsMemory = true;
- if (!ignoreImplicitTraps)
+ if (!ignoreImplicitTraps) {
implicitTrap = true;
+ }
}
void visitMemoryCopy(MemoryCopy* curr) {
readsMemory = true;
writesMemory = true;
- if (!ignoreImplicitTraps)
+ if (!ignoreImplicitTraps) {
implicitTrap = true;
+ }
}
void visitMemoryFill(MemoryFill* curr) {
writesMemory = true;
- if (!ignoreImplicitTraps)
+ if (!ignoreImplicitTraps) {
implicitTrap = true;
+ }
}
void visitConst(Const* curr) {}
void visitUnary(Unary* curr) {
diff --git a/src/ir/equivalent_sets.h b/src/ir/equivalent_sets.h
index fc4b1db3d..657ff9894 100644
--- a/src/ir/equivalent_sets.h
+++ b/src/ir/equivalent_sets.h
@@ -67,8 +67,9 @@ struct EquivalentSets {
// Checks whether two indexes contain the same data.
bool check(Index a, Index b) {
- if (a == b)
+ if (a == b) {
return true;
+ }
if (auto* set = getEquivalents(a)) {
if (set->find(b) != set->end()) {
return true;
diff --git a/src/ir/function-utils.h b/src/ir/function-utils.h
index 446bcc8bb..61af153a0 100644
--- a/src/ir/function-utils.h
+++ b/src/ir/function-utils.h
@@ -28,18 +28,23 @@ namespace FunctionUtils {
// everything but their name (which can't be the same, in the same
// module!) - same params, vars, body, result, etc.
inline bool equal(Function* left, Function* right) {
- if (left->getNumParams() != right->getNumParams())
+ if (left->getNumParams() != right->getNumParams()) {
return false;
- if (left->getNumVars() != right->getNumVars())
+ }
+ if (left->getNumVars() != right->getNumVars()) {
return false;
+ }
for (Index i = 0; i < left->getNumLocals(); i++) {
- if (left->getLocalType(i) != right->getLocalType(i))
+ if (left->getLocalType(i) != right->getLocalType(i)) {
return false;
+ }
}
- if (left->result != right->result)
+ if (left->result != right->result) {
return false;
- if (left->type != right->type)
+ }
+ if (left->type != right->type) {
return false;
+ }
if (!left->imported() && !right->imported()) {
return ExpressionAnalyzer::equal(left->body, right->body);
}
diff --git a/src/ir/global-utils.h b/src/ir/global-utils.h
index b32605805..113a37f31 100644
--- a/src/ir/global-utils.h
+++ b/src/ir/global-utils.h
@@ -38,8 +38,9 @@ getGlobalInitializedToImport(Module& wasm, Name module, Name base) {
imported = import->name;
}
});
- if (imported.isNull())
+ if (imported.isNull()) {
return nullptr;
+ }
// find a global inited to it
Global* ret = nullptr;
ModuleUtils::iterDefinedGlobals(wasm, [&](Global* defined) {
diff --git a/src/ir/hashed.h b/src/ir/hashed.h
index 676b82cb4..a3d285cf5 100644
--- a/src/ir/hashed.h
+++ b/src/ir/hashed.h
@@ -44,8 +44,9 @@ struct ExpressionHasher {
struct ExpressionComparer {
bool operator()(const HashedExpression a, const HashedExpression b) const {
- if (a.hash != b.hash)
+ if (a.hash != b.hash) {
return false;
+ }
return ExpressionAnalyzer::equal(a.expr, b.expr);
}
};
diff --git a/src/ir/load-utils.h b/src/ir/load-utils.h
index 36e94d0af..c7e9bad99 100644
--- a/src/ir/load-utils.h
+++ b/src/ir/load-utils.h
@@ -28,8 +28,9 @@ namespace LoadUtils {
// fill in bits either signed or unsigned wise)
inline bool isSignRelevant(Load* load) {
auto type = load->type;
- if (load->type == unreachable)
+ if (load->type == unreachable) {
return false;
+ }
return !isFloatType(type) && load->bytes < getTypeSize(type);
}
diff --git a/src/ir/memory-utils.h b/src/ir/memory-utils.h
index c1edc8ce9..fd4b865f4 100644
--- a/src/ir/memory-utils.h
+++ b/src/ir/memory-utils.h
@@ -29,16 +29,18 @@ namespace wasm {
namespace MemoryUtils {
// flattens memory into a single data segment. returns true if successful
inline bool flatten(Memory& memory) {
- if (memory.segments.size() == 0)
+ if (memory.segments.size() == 0) {
return true;
+ }
std::vector<char> data;
for (auto& segment : memory.segments) {
if (segment.isPassive) {
return false;
}
auto* offset = segment.offset->dynCast<Const>();
- if (!offset)
+ if (!offset) {
return false;
+ }
}
for (auto& segment : memory.segments) {
auto* offset = segment.offset->dynCast<Const>();
@@ -121,10 +123,12 @@ inline bool ensureLimitedSegments(Module& module) {
// drop empty segments and pass through dynamic-offset segments
for (auto& segment : memory.segments) {
- if (isEmpty(segment))
+ if (isEmpty(segment)) {
continue;
- if (isConstantOffset(segment))
+ }
+ if (isConstantOffset(segment)) {
continue;
+ }
mergedSegments.push_back(segment);
}
@@ -135,8 +139,9 @@ inline bool ensureLimitedSegments(Module& module) {
};
for (Index i = 0; i < memory.segments.size(); i++) {
auto& segment = memory.segments[i];
- if (!isRelevant(segment))
+ if (!isRelevant(segment)) {
continue;
+ }
if (mergedSegments.size() + 2 < WebLimitations::MaxDataSegments) {
mergedSegments.push_back(segment);
continue;
@@ -146,8 +151,9 @@ inline bool ensureLimitedSegments(Module& module) {
auto start = segment.offset->cast<Const>()->value.getInteger();
for (Index j = i + 1; j < memory.segments.size(); j++) {
auto& segment = memory.segments[j];
- if (!isRelevant(segment))
+ if (!isRelevant(segment)) {
continue;
+ }
auto offset = segment.offset->cast<Const>()->value.getInteger();
start = std::min(start, offset);
}
@@ -159,8 +165,9 @@ inline bool ensureLimitedSegments(Module& module) {
Memory::Segment combined(c);
for (Index j = i; j < memory.segments.size(); j++) {
auto& segment = memory.segments[j];
- if (!isRelevant(segment))
+ if (!isRelevant(segment)) {
continue;
+ }
auto offset = segment.offset->cast<Const>()->value.getInteger();
auto needed = offset + segment.data.size() - start;
if (combined.data.size() < needed) {
diff --git a/src/ir/type-updating.h b/src/ir/type-updating.h
index e387483ee..ef9fe78e9 100644
--- a/src/ir/type-updating.h
+++ b/src/ir/type-updating.h
@@ -194,8 +194,9 @@ struct TypeUpdater
// alters the type of a node to a new type.
// this propagates the type change through all the parents.
void changeTypeTo(Expression* curr, Type newType) {
- if (curr->type == newType)
+ if (curr->type == newType) {
return; // nothing to do
+ }
curr->type = newType;
propagateTypesUp(curr);
}
@@ -208,13 +209,15 @@ struct TypeUpdater
// the one thing we need to do here is propagate unreachability,
// no other change is possible
void propagateTypesUp(Expression* curr) {
- if (curr->type != unreachable)
+ if (curr->type != unreachable) {
return;
+ }
while (1) {
auto* child = curr;
curr = parents[child];
- if (!curr)
+ if (!curr) {
return;
+ }
// get ready to apply unreachability to this node
if (curr->type == unreachable) {
return; // already unreachable, stop here
diff --git a/src/ir/utils.h b/src/ir/utils.h
index 9be8947a1..4e941b8d0 100644
--- a/src/ir/utils.h
+++ b/src/ir/utils.h
@@ -248,8 +248,9 @@ struct AutoDrop : public WalkerPass<ExpressionStackWalker<AutoDrop>> {
void reFinalize() { ReFinalizeNode::updateStack(expressionStack); }
void visitBlock(Block* curr) {
- if (curr->list.size() == 0)
+ if (curr->list.size() == 0) {
return;
+ }
for (Index i = 0; i < curr->list.size() - 1; i++) {
auto* child = curr->list[i];
if (isConcreteType(child->type)) {
@@ -264,11 +265,13 @@ struct AutoDrop : public WalkerPass<ExpressionStackWalker<AutoDrop>> {
void visitIf(If* curr) {
bool acted = false;
- if (maybeDrop(curr->ifTrue))
+ if (maybeDrop(curr->ifTrue)) {
acted = true;
+ }
if (curr->ifFalse) {
- if (maybeDrop(curr->ifFalse))
+ if (maybeDrop(curr->ifFalse)) {
acted = true;
+ }
}
if (acted) {
reFinalize();
diff --git a/src/literal.h b/src/literal.h
index ff50b2e61..9ffa79032 100644
--- a/src/literal.h
+++ b/src/literal.h
@@ -412,10 +412,12 @@ template<> struct hash<wasm::Literal> {
};
template<> struct less<wasm::Literal> {
bool operator()(const wasm::Literal& a, const wasm::Literal& b) const {
- if (a.type < b.type)
+ if (a.type < b.type) {
return true;
- if (a.type > b.type)
+ }
+ if (a.type > b.type) {
return false;
+ }
switch (a.type) {
case wasm::Type::i32:
return a.geti32() < b.geti32();
diff --git a/src/mixed_arena.h b/src/mixed_arena.h
index 36bf22a5e..079ce9028 100644
--- a/src/mixed_arena.h
+++ b/src/mixed_arena.h
@@ -113,8 +113,9 @@ struct MixedArena {
// otherwise, the cmpxchg updated seen, and we continue to loop
curr = seen;
}
- if (allocated)
+ if (allocated) {
delete allocated;
+ }
return curr->allocSpace(size, align);
}
// First, move the current index in the last chunk to an aligned position.
@@ -125,8 +126,9 @@ struct MixedArena {
assert(size <= numChunks * CHUNK_SIZE);
auto* allocation =
wasm::aligned_malloc(MAX_ALIGN, numChunks * CHUNK_SIZE);
- if (!allocation)
+ if (!allocation) {
abort();
+ }
chunks.push_back(allocation);
index = 0;
}
@@ -155,8 +157,9 @@ struct MixedArena {
~MixedArena() {
clear();
- if (next.load())
+ if (next.load()) {
delete next.load();
+ }
}
};
diff --git a/src/parsing.h b/src/parsing.h
index 8432b41f2..9b2cb490b 100644
--- a/src/parsing.h
+++ b/src/parsing.h
@@ -143,16 +143,19 @@ parseConst(cashew::IString s, Type type, MixedArena& allocator) {
if (modifier) {
std::istringstream istr(modifier);
istr >> std::hex >> pattern;
- if (istr.fail())
+ if (istr.fail()) {
throw ParseException("invalid f32 format");
+ }
pattern |= 0x7f800000U;
} else {
pattern = 0x7fc00000U;
}
- if (negative)
+ if (negative) {
pattern |= 0x80000000U;
- if (!std::isnan(bit_cast<float>(pattern)))
+ }
+ if (!std::isnan(bit_cast<float>(pattern))) {
pattern |= 1U;
+ }
ret->value = Literal(pattern).castToF32();
break;
}
@@ -161,16 +164,19 @@ parseConst(cashew::IString s, Type type, MixedArena& allocator) {
if (modifier) {
std::istringstream istr(modifier);
istr >> std::hex >> pattern;
- if (istr.fail())
+ if (istr.fail()) {
throw ParseException("invalid f64 format");
+ }
pattern |= 0x7ff0000000000000ULL;
} else {
pattern = 0x7ff8000000000000UL;
}
- if (negative)
+ if (negative) {
pattern |= 0x8000000000000000ULL;
- if (!std::isnan(bit_cast<double>(pattern)))
+ }
+ if (!std::isnan(bit_cast<double>(pattern))) {
pattern |= 1ULL;
+ }
ret->value = Literal(pattern).castToF64();
break;
}
@@ -200,20 +206,23 @@ parseConst(cashew::IString s, Type type, MixedArena& allocator) {
if ((str[0] == '0' && str[1] == 'x') ||
(str[0] == '-' && str[1] == '0' && str[2] == 'x')) {
bool negative = str[0] == '-';
- if (negative)
+ if (negative) {
str++;
+ }
std::istringstream istr(str);
uint32_t temp;
istr >> std::hex >> temp;
- if (istr.fail())
+ if (istr.fail()) {
throw ParseException("invalid i32 format");
+ }
ret->value = Literal(negative ? -temp : temp);
} else {
std::istringstream istr(str[0] == '-' ? str + 1 : str);
uint32_t temp;
istr >> temp;
- if (istr.fail())
+ if (istr.fail()) {
throw ParseException("invalid i32 format");
+ }
ret->value = Literal(str[0] == '-' ? -temp : temp);
}
break;
@@ -222,20 +231,23 @@ parseConst(cashew::IString s, Type type, MixedArena& allocator) {
if ((str[0] == '0' && str[1] == 'x') ||
(str[0] == '-' && str[1] == '0' && str[2] == 'x')) {
bool negative = str[0] == '-';
- if (negative)
+ if (negative) {
str++;
+ }
std::istringstream istr(str);
uint64_t temp;
istr >> std::hex >> temp;
- if (istr.fail())
+ if (istr.fail()) {
throw ParseException("invalid i64 format");
+ }
ret->value = Literal(negative ? -temp : temp);
} else {
std::istringstream istr(str[0] == '-' ? str + 1 : str);
uint64_t temp;
istr >> temp;
- if (istr.fail())
+ if (istr.fail()) {
throw ParseException("invalid i64 format");
+ }
ret->value = Literal(str[0] == '-' ? -temp : temp);
}
break;
@@ -275,13 +287,15 @@ struct UniqueNameMapper {
Index otherIndex = 0;
Name getPrefixedName(Name prefix) {
- if (reverseLabelMapping.find(prefix) == reverseLabelMapping.end())
+ if (reverseLabelMapping.find(prefix) == reverseLabelMapping.end()) {
return prefix;
+ }
// make sure to return a unique name not already on the stack
while (1) {
Name ret = Name(prefix.str + std::to_string(otherIndex++));
- if (reverseLabelMapping.find(ret) == reverseLabelMapping.end())
+ if (reverseLabelMapping.find(ret) == reverseLabelMapping.end()) {
return ret;
+ }
}
}
@@ -331,21 +345,25 @@ struct UniqueNameMapper {
static void doPreVisitControlFlow(Walker* self, Expression** currp) {
auto* curr = *currp;
if (auto* block = curr->dynCast<Block>()) {
- if (block->name.is())
+ if (block->name.is()) {
block->name = self->mapper.pushLabelName(block->name);
+ }
} else if (auto* loop = curr->dynCast<Loop>()) {
- if (loop->name.is())
+ if (loop->name.is()) {
loop->name = self->mapper.pushLabelName(loop->name);
+ }
}
}
static void doPostVisitControlFlow(Walker* self, Expression** currp) {
auto* curr = *currp;
if (auto* block = curr->dynCast<Block>()) {
- if (block->name.is())
+ if (block->name.is()) {
self->mapper.popLabelName(block->name);
+ }
} else if (auto* loop = curr->dynCast<Loop>()) {
- if (loop->name.is())
+ if (loop->name.is()) {
self->mapper.popLabelName(loop->name);
+ }
}
}
diff --git a/src/pass.h b/src/pass.h
index 720e5c992..3917c8908 100644
--- a/src/pass.h
+++ b/src/pass.h
@@ -133,8 +133,9 @@ struct PassRunner {
void add(std::string passName) {
auto pass = PassRegistry::get()->createPass(passName);
- if (!pass)
+ if (!pass) {
Fatal() << "Could not find pass: " << passName << "\n";
+ }
doAdd(pass);
}
diff --git a/src/passes/CoalesceLocals.cpp b/src/passes/CoalesceLocals.cpp
index a085b61fb..af13419d3 100644
--- a/src/passes/CoalesceLocals.cpp
+++ b/src/passes/CoalesceLocals.cpp
@@ -70,8 +70,9 @@ struct CoalesceLocals
std::vector<bool> interferences;
void interfere(Index i, Index j) {
- if (i == j)
+ if (i == j) {
return;
+ }
interferences[std::min(i, j) * numLocals + std::max(i, j)] = 1;
}
@@ -112,10 +113,11 @@ void CoalesceLocals::increaseBackEdgePriorities() {
auto& in = loopTop->in;
for (Index i = 1; i < in.size(); i++) {
auto* arrivingBlock = in[i];
- if (arrivingBlock->out.size() > 1)
+ if (arrivingBlock->out.size() > 1) {
// we just want unconditional branches to the loop top, true phi
// fragments
continue;
+ }
for (auto& action : arrivingBlock->contents.actions) {
if (action.isSet()) {
auto* set = (*action.origin)->cast<SetLocal>();
@@ -134,8 +136,9 @@ void CoalesceLocals::calculateInterferences() {
interferences.resize(numLocals * numLocals);
std::fill(interferences.begin(), interferences.end(), false);
for (auto& curr : basicBlocks) {
- if (liveBlocks.count(curr.get()) == 0)
+ if (liveBlocks.count(curr.get()) == 0) {
continue; // ignore dead blocks
+ }
// everything coming in might interfere, as it might come from a different
// block
auto live = curr->contents.end;
@@ -306,8 +309,9 @@ std::vector<Index> adjustOrderByPriorities(std::vector<Index>& baseline,
}
void CoalesceLocals::pickIndices(std::vector<Index>& indices) {
- if (numLocals == 0)
+ if (numLocals == 0) {
return;
+ }
if (numLocals == 1) {
indices.push_back(0);
return;
@@ -420,8 +424,9 @@ void CoalesceLocalsWithLearning::pickIndices(std::vector<Index>& indices) {
double getFitness() { return fitness; }
void dump(std::string text) {
std::cout << text + ": ( ";
- for (Index i = 0; i < size(); i++)
+ for (Index i = 0; i < size(); i++) {
std::cout << (*this)[i] << " ";
+ }
std::cout << ")\n";
std::cout << "of quality: " << getFitness() << "\n";
}
@@ -445,8 +450,9 @@ void CoalesceLocalsWithLearning::pickIndices(std::vector<Index>& indices) {
// secondarily, it is nice to not reorder locals unnecessarily
double fragment = 1.0 / (2.0 * parent->numLocals);
for (Index i = 0; i < parent->numLocals; i++) {
- if ((*order)[i] == i)
+ if ((*order)[i] == i) {
fitness += fragment; // boost for each that wasn't moved
+ }
}
// removing copies is a secondary concern
fitness = (100 * fitness) + removedCopies;
@@ -534,8 +540,9 @@ void CoalesceLocalsWithLearning::pickIndices(std::vector<Index>& indices) {
while (1) {
learner.runGeneration();
auto newBest = learner.getBest()->getFitness();
- if (newBest == oldBest)
+ if (newBest == oldBest) {
break; // unlikely we can improve
+ }
oldBest = newBest;
#ifdef CFG_LEARN_DEBUG
learner.getBest()->dump("current best");
diff --git a/src/passes/CodeFolding.cpp b/src/passes/CodeFolding.cpp
index 0479472d8..d60bc76d1 100644
--- a/src/passes/CodeFolding.cpp
+++ b/src/passes/CodeFolding.cpp
@@ -179,19 +179,23 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> {
}
void visitBlock(Block* curr) {
- if (curr->list.empty())
+ if (curr->list.empty()) {
return;
- if (!curr->name.is())
+ }
+ if (!curr->name.is()) {
return;
- if (unoptimizables.count(curr->name) > 0)
+ }
+ if (unoptimizables.count(curr->name) > 0) {
return;
+ }
// we can't optimize a fallthrough value
if (isConcreteType(curr->list.back()->type)) {
return;
}
auto iter = breakTails.find(curr->name);
- if (iter == breakTails.end())
+ if (iter == breakTails.end()) {
return;
+ }
// looks promising
auto& tails = iter->second;
// see if there is a fallthrough
@@ -208,8 +212,9 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> {
}
void visitIf(If* curr) {
- if (!curr->ifFalse)
+ if (!curr->ifFalse) {
return;
+ }
// if both sides are identical, this is easy to fold
if (ExpressionAnalyzer::equal(curr->ifTrue, curr->ifFalse)) {
Builder builder(*getModule());
@@ -304,14 +309,17 @@ private:
// identical in all paths leading to the block exit can be merged.
template<typename T>
void optimizeExpressionTails(std::vector<Tail>& tails, T* curr) {
- if (tails.size() < 2)
+ if (tails.size() < 2) {
return;
+ }
// see if anything is untoward, and we should not do this
for (auto& tail : tails) {
- if (tail.expr && modifieds.count(tail.expr) > 0)
+ if (tail.expr && modifieds.count(tail.expr) > 0) {
return;
- if (modifieds.count(tail.block) > 0)
+ }
+ if (modifieds.count(tail.block) > 0) {
return;
+ }
// if we were not modified, then we should be valid for processing
tail.validate();
}
@@ -345,8 +353,9 @@ private:
break;
}
}
- if (stop)
+ if (stop) {
break;
+ }
auto* item = getMergeable(tails[0], num);
for (auto& tail : tails) {
if (!ExpressionAnalyzer::equal(item, getMergeable(tail, num))) {
@@ -355,18 +364,21 @@ private:
break;
}
}
- if (stop)
+ if (stop) {
break;
+ }
// we may have found another one we can merge - can we move it?
- if (!canMove({item}, curr))
+ if (!canMove({item}, curr)) {
break;
+ }
// we found another one we can merge
mergeable.push_back(item);
num++;
saved += Measurer::measure(item);
}
- if (saved == 0)
+ if (saved == 0) {
return;
+ }
// we may be able to save enough.
if (saved < WORTH_ADDING_BLOCK_TO_REMOVE_THIS_MUCH) {
// it's not obvious we can save enough. see if we get rid
@@ -463,17 +475,20 @@ private:
// deeper merges first.
// returns whether we optimized something.
bool optimizeTerminatingTails(std::vector<Tail>& tails, Index num = 0) {
- if (tails.size() < 2)
+ if (tails.size() < 2) {
return false;
+ }
// remove things that are untoward and cannot be optimized
tails.erase(
std::remove_if(tails.begin(),
tails.end(),
[&](Tail& tail) {
- if (tail.expr && modifieds.count(tail.expr) > 0)
+ if (tail.expr && modifieds.count(tail.expr) > 0) {
return true;
- if (tail.block && modifieds.count(tail.block) > 0)
+ }
+ if (tail.block && modifieds.count(tail.block) > 0) {
return true;
+ }
// if we were not modified, then we should be valid for
// processing
tail.validate();
@@ -544,8 +559,9 @@ private:
next.erase(std::remove_if(next.begin(),
next.end(),
[&](Tail& tail) {
- if (effectiveSize(tail) < num + 1)
+ if (effectiveSize(tail) < num + 1) {
return true;
+ }
auto* newItem = getItem(tail, num);
// ignore tails that break to outside blocks. we
// want to move code to the very outermost
@@ -578,12 +594,14 @@ private:
for (auto& tail : next) {
auto* item = getItem(tail, num);
auto hash = hashes[item];
- if (seen.count(hash))
+ if (seen.count(hash)) {
continue;
+ }
seen.insert(hash);
auto& items = hashed[hash];
- if (items.size() == 1)
+ if (items.size() == 1) {
continue;
+ }
assert(items.size() > 0);
// look for an item that has another match.
while (items.size() >= 2) {
@@ -632,11 +650,13 @@ private:
// we explored deeper (higher num) options, but perhaps there
// was nothing there while there is something we can do at this level
// but if we are at num == 0, then we found nothing at all
- if (num == 0)
+ if (num == 0) {
return false;
+ }
// if not worth it, stop
- if (!worthIt(num, tails))
+ if (!worthIt(num, tails)) {
return false;
+ }
// this is worth doing, do it!
auto mergeable = getTailItems(num, tails); // the elements we can merge
// since we managed a merge, then it might open up more opportunities later
@@ -680,8 +700,9 @@ private:
// rules, and now it won't be toplevel in the function, it can
// change)
auto* toplevel = old->dynCast<Block>();
- if (toplevel)
+ if (toplevel) {
toplevel->finalize();
+ }
if (old->type != unreachable) {
inner->list.push_back(builder.makeReturn(old));
} else {
diff --git a/src/passes/CodePushing.cpp b/src/passes/CodePushing.cpp
index 342cb5182..88e363541 100644
--- a/src/passes/CodePushing.cpp
+++ b/src/passes/CodePushing.cpp
@@ -50,8 +50,9 @@ struct LocalAnalyzer : public PostWalker<LocalAnalyzer> {
std::fill(sfa.begin() + func->getNumParams(), sfa.end(), true);
walk(func->body);
for (Index i = 0; i < num; i++) {
- if (numSets[i] == 0)
+ if (numSets[i] == 0) {
sfa[i] = false;
+ }
}
}
@@ -117,8 +118,9 @@ public:
private:
SetLocal* isPushable(Expression* curr) {
auto* set = curr->dynCast<SetLocal>();
- if (!set)
+ if (!set) {
return nullptr;
+ }
auto index = set->index;
// to be pushable, this must be SFA and the right # of gets,
// but also have no side effects, as it may not execute if pushed.
@@ -137,8 +139,9 @@ private:
if (auto* drop = curr->dynCast<Drop>()) {
curr = drop->value;
}
- if (curr->is<If>())
+ if (curr->is<If>()) {
return true;
+ }
if (auto* br = curr->dynCast<Break>()) {
return !!br->condition;
}
@@ -249,8 +252,9 @@ struct CodePushing : public WalkerPass<PostWalker<CodePushing>> {
// Pushing code only makes sense if we are size 3 or above: we need
// one element to push, an element to push it past, and an element to use
// what we pushed.
- if (curr->list.size() < 3)
+ if (curr->list.size() < 3) {
return;
+ }
// At this point in the postorder traversal we have gone through all our
// children. Therefore any variable whose gets seen so far is equal to the
// total gets must have no further users after this block. And therefore
diff --git a/src/passes/ConstHoisting.cpp b/src/passes/ConstHoisting.cpp
index f67a48645..749a3361f 100644
--- a/src/passes/ConstHoisting.cpp
+++ b/src/passes/ConstHoisting.cpp
@@ -72,8 +72,9 @@ struct ConstHoisting : public WalkerPass<PostWalker<ConstHoisting>> {
private:
bool worthHoisting(Literal value, Index num) {
- if (num < MIN_USES)
+ if (num < MIN_USES) {
return false;
+ }
// measure the size of the constant
Index size = 0;
switch (value.type) {
diff --git a/src/passes/DataFlowOpts.cpp b/src/passes/DataFlowOpts.cpp
index 3391359ef..62d2e5f24 100644
--- a/src/passes/DataFlowOpts.cpp
+++ b/src/passes/DataFlowOpts.cpp
@@ -81,11 +81,13 @@ struct DataFlowOpts : public WalkerPass<PostWalker<DataFlowOpts>> {
}
void workOn(DataFlow::Node* node) {
- if (node->isConst())
+ if (node->isConst()) {
return;
+ }
// If there are no uses, there is no point to work.
- if (nodeUsers.getNumUses(node) == 0)
+ if (nodeUsers.getNumUses(node) == 0) {
return;
+ }
// Optimize: Look for nodes that we can easily convert into
// something simpler.
// TODO: we can expressionify and run full normal opts on that,
@@ -144,8 +146,9 @@ struct DataFlowOpts : public WalkerPass<PostWalker<DataFlowOpts>> {
// Get the optimized thing
auto* result = func->body;
// It may not be a constant, e.g. 0 / 0 does not optimize to 0
- if (!result->is<Const>())
+ if (!result->is<Const>()) {
return;
+ }
// All good, copy it.
node->expr = Builder(*getModule()).makeConst(result->cast<Const>()->value);
assert(node->isConst());
diff --git a/src/passes/DeadArgumentElimination.cpp b/src/passes/DeadArgumentElimination.cpp
index 0c6561ef6..3735c79d0 100644
--- a/src/passes/DeadArgumentElimination.cpp
+++ b/src/passes/DeadArgumentElimination.cpp
@@ -307,8 +307,9 @@ struct DAE : public Pass {
auto& calls = pair.second;
auto* func = module->getFunction(name);
auto numParams = func->getNumParams();
- if (numParams == 0)
+ if (numParams == 0) {
continue;
+ }
// Iterate downwards, as we may remove more than one.
Index i = numParams - 1;
while (1) {
@@ -331,8 +332,9 @@ struct DAE : public Pass {
changed.insert(func);
}
}
- if (i == 0)
+ if (i == 0) {
break;
+ }
i--;
}
}
diff --git a/src/passes/DeadCodeElimination.cpp b/src/passes/DeadCodeElimination.cpp
index d23713060..c77edf357 100644
--- a/src/passes/DeadCodeElimination.cpp
+++ b/src/passes/DeadCodeElimination.cpp
@@ -49,8 +49,9 @@ struct DeadCodeElimination
Expression* replaceCurrent(Expression* expression) {
auto* old = getCurrent();
- if (old == expression)
+ if (old == expression) {
return expression;
+ }
super::replaceCurrent(expression);
// also update the type updater
typeUpdater.noteReplacement(old, expression);
@@ -333,8 +334,9 @@ struct DeadCodeElimination
// we don't need to drop unreachable nodes
Expression* drop(Expression* toDrop) {
- if (toDrop->type == unreachable)
+ if (toDrop->type == unreachable) {
return toDrop;
+ }
return Builder(*getModule()).makeDrop(toDrop);
}
@@ -362,8 +364,9 @@ struct DeadCodeElimination
void visitCall(Call* curr) { handleCall(curr); }
void visitCallIndirect(CallIndirect* curr) {
- if (handleCall(curr) != curr)
+ if (handleCall(curr) != curr) {
return;
+ }
if (isUnreachable(curr->target)) {
auto* block = getModule()->allocator.alloc<Block>();
for (auto* operand : curr->operands) {
diff --git a/src/passes/Directize.cpp b/src/passes/Directize.cpp
index 8f75c8f57..54315dc77 100644
--- a/src/passes/Directize.cpp
+++ b/src/passes/Directize.cpp
@@ -93,17 +93,21 @@ private:
struct Directize : public Pass {
void run(PassRunner* runner, Module* module) override {
- if (!module->table.exists)
+ if (!module->table.exists) {
return;
- if (module->table.imported())
+ }
+ if (module->table.imported()) {
return;
+ }
for (auto& ex : module->exports) {
- if (ex->kind == ExternalKind::Table)
+ if (ex->kind == ExternalKind::Table) {
return;
+ }
}
FlatTable flatTable(module->table);
- if (!flatTable.valid)
+ if (!flatTable.valid) {
return;
+ }
// The table exists and is constant, so this is possible.
{
PassRunner runner(module);
diff --git a/src/passes/DuplicateFunctionElimination.cpp b/src/passes/DuplicateFunctionElimination.cpp
index 3caa43e1d..3f048d79a 100644
--- a/src/passes/DuplicateFunctionElimination.cpp
+++ b/src/passes/DuplicateFunctionElimination.cpp
@@ -85,19 +85,22 @@ struct DuplicateFunctionElimination : public Pass {
for (auto& pair : hashGroups) {
auto& group = pair.second;
Index size = group.size();
- if (size == 1)
+ if (size == 1) {
continue;
+ }
// The groups should be fairly small, and even if a group is large we
// should have almost all of them identical, so we should not hit actual
// O(N^2) here unless the hash is quite poor.
for (Index i = 0; i < size - 1; i++) {
auto* first = group[i];
- if (duplicates.count(first->name))
+ if (duplicates.count(first->name)) {
continue;
+ }
for (Index j = i + 1; j < size; j++) {
auto* second = group[j];
- if (duplicates.count(second->name))
+ if (duplicates.count(second->name)) {
continue;
+ }
if (FunctionUtils::equal(first, second)) {
// great, we can replace the second with the first!
replacements[second->name] = first->name;
diff --git a/src/passes/Flatten.cpp b/src/passes/Flatten.cpp
index a68fc9abe..55f3df6ab 100644
--- a/src/passes/Flatten.cpp
+++ b/src/passes/Flatten.cpp
@@ -128,9 +128,10 @@ struct Flatten
rep = builder.makeGetLocal(temp, type);
}
iff->ifTrue = getPreludesWithExpression(originalIfTrue, iff->ifTrue);
- if (iff->ifFalse)
+ if (iff->ifFalse) {
iff->ifFalse =
getPreludesWithExpression(originalIfFalse, iff->ifFalse);
+ }
iff->finalize();
if (prelude) {
ReFinalizeNode().visit(prelude);
@@ -284,8 +285,9 @@ private:
Expression* getPreludesWithExpression(Expression* preluder,
Expression* after) {
auto iter = preludes.find(preluder);
- if (iter == preludes.end())
+ if (iter == preludes.end()) {
return after;
+ }
// we have preludes
auto& thePreludes = iter->second;
auto* ret = Builder(*getModule()).makeBlock(thePreludes);
diff --git a/src/passes/I64ToI32Lowering.cpp b/src/passes/I64ToI32Lowering.cpp
index 26f40c284..e61e4055e 100644
--- a/src/passes/I64ToI32Lowering.cpp
+++ b/src/passes/I64ToI32Lowering.cpp
@@ -53,8 +53,9 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
TempVar& operator=(TempVar&& rhs) {
assert(!rhs.moved);
// free overwritten idx
- if (!moved)
+ if (!moved) {
freeIdx();
+ }
idx = rhs.idx;
rhs.moved = true;
moved = false;
@@ -62,8 +63,9 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
~TempVar() {
- if (!moved)
+ if (!moved) {
freeIdx();
+ }
}
bool operator==(const TempVar& rhs) {
@@ -101,13 +103,15 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
Pass* create() override { return new I64ToI32Lowering; }
void doWalkModule(Module* module) {
- if (!builder)
+ if (!builder) {
builder = make_unique<Builder>(*module);
+ }
// add new globals for high bits
for (size_t i = 0, globals = module->globals.size(); i < globals; ++i) {
auto* curr = module->globals[i].get();
- if (curr->type != i64)
+ if (curr->type != i64) {
continue;
+ }
originallyI64Globals.insert(curr->name);
curr->type = i32;
auto* high = builder->makeGlobal(makeHighName(curr->name),
@@ -162,8 +166,9 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
void doWalkFunction(Function* func) {
Flat::verifyFlatness(func);
// create builder here if this is first entry to module for this object
- if (!builder)
+ if (!builder) {
builder = make_unique<Builder>(*getModule());
+ }
indexMap.clear();
highBitVars.clear();
freeTemps.clear();
@@ -327,10 +332,12 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
void visitGetGlobal(GetGlobal* curr) {
- if (!getFunction())
+ if (!getFunction()) {
return; // if in a global init, skip - we already handled that.
- if (!originallyI64Globals.count(curr->name))
+ }
+ if (!originallyI64Globals.count(curr->name)) {
return;
+ }
curr->type = i32;
TempVar highBits = getTemp();
SetLocal* setHighBits = builder->makeSetLocal(
@@ -341,10 +348,12 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
void visitSetGlobal(SetGlobal* curr) {
- if (!originallyI64Globals.count(curr->name))
+ if (!originallyI64Globals.count(curr->name)) {
return;
- if (handleUnreachable(curr))
+ }
+ if (handleUnreachable(curr)) {
return;
+ }
TempVar highBits = fetchOutParam(curr->value);
auto* setHigh = builder->makeSetGlobal(
makeHighName(curr->name), builder->makeGetLocal(highBits, i32));
@@ -352,8 +361,9 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
void visitLoad(Load* curr) {
- if (curr->type != i64)
+ if (curr->type != i64) {
return;
+ }
assert(!curr->isAtomic && "atomic load not implemented");
TempVar lowBits = getTemp();
TempVar highBits = getTemp();
@@ -392,8 +402,9 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
void visitStore(Store* curr) {
- if (!hasOutParam(curr->value))
+ if (!hasOutParam(curr->value)) {
return;
+ }
assert(curr->offset + 4 > curr->offset);
assert(!curr->isAtomic && "atomic store not implemented");
TempVar highBits = fetchOutParam(curr->value);
@@ -426,10 +437,12 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
void visitConst(Const* curr) {
- if (!getFunction())
+ if (!getFunction()) {
return; // if in a global init, skip - we already handled that.
- if (curr->type != i64)
+ }
+ if (curr->type != i64) {
return;
+ }
TempVar highBits = getTemp();
Const* lowVal =
builder->makeConst(Literal(int32_t(curr->value.geti64() & 0xffffffff)));
@@ -763,10 +776,12 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
void visitUnary(Unary* curr) {
- if (!unaryNeedsLowering(curr->op))
+ if (!unaryNeedsLowering(curr->op)) {
return;
- if (handleUnreachable(curr))
+ }
+ if (handleUnreachable(curr)) {
return;
+ }
assert(hasOutParam(curr->value) || curr->type == i64 || curr->type == f64);
switch (curr->op) {
case ClzInt64:
@@ -1265,10 +1280,12 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
void visitBinary(Binary* curr) {
- if (handleUnreachable(curr))
+ if (handleUnreachable(curr)) {
return;
- if (!binaryNeedsLowering(curr->op))
+ }
+ if (!binaryNeedsLowering(curr->op)) {
return;
+ }
// left and right reachable, lower normally
TempVar leftLow = getTemp();
TempVar leftHigh = fetchOutParam(curr->left);
@@ -1374,8 +1391,9 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
void visitSelect(Select* curr) {
- if (handleUnreachable(curr))
+ if (handleUnreachable(curr)) {
return;
+ }
if (!hasOutParam(curr->ifTrue)) {
assert(!hasOutParam(curr->ifFalse));
return;
@@ -1402,15 +1420,17 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
void visitDrop(Drop* curr) {
- if (!hasOutParam(curr->value))
+ if (!hasOutParam(curr->value)) {
return;
+ }
// free temp var
fetchOutParam(curr->value);
}
void visitReturn(Return* curr) {
- if (!hasOutParam(curr->value))
+ if (!hasOutParam(curr->value)) {
return;
+ }
TempVar lowBits = getTemp();
TempVar highBits = fetchOutParam(curr->value);
SetLocal* setLow = builder->makeSetLocal(lowBits, curr->value);
@@ -1468,8 +1488,9 @@ private:
// unconditionally before themselves, so it is not valid for an if,
// in particular.
bool handleUnreachable(Expression* curr) {
- if (curr->type != unreachable)
+ if (curr->type != unreachable) {
return false;
+ }
std::vector<Expression*> children;
bool hasUnreachable = false;
for (auto* child : ChildIterator(curr)) {
@@ -1480,8 +1501,9 @@ private:
}
children.push_back(child);
}
- if (!hasUnreachable)
+ if (!hasUnreachable) {
return false;
+ }
// This has an unreachable child, so we can replace it with
// the children.
auto* block = builder->makeBlock(children);
diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp
index 681109af8..11f452e17 100644
--- a/src/passes/Inlining.cpp
+++ b/src/passes/Inlining.cpp
@@ -79,17 +79,20 @@ struct FunctionInfo {
bool worthInlining(PassOptions& options) {
// if it's big, it's just not worth doing (TODO: investigate more)
- if (size > FLEXIBLE_SIZE_LIMIT)
+ if (size > FLEXIBLE_SIZE_LIMIT) {
return false;
+ }
// if it's so small we have a guarantee that after we optimize the
// size will not increase, inline it
- if (size <= INLINING_OPTIMIZING_WILL_DECREASE_SIZE_LIMIT)
+ if (size <= INLINING_OPTIMIZING_WILL_DECREASE_SIZE_LIMIT) {
return true;
+ }
// if it has one use, then inlining it would likely reduce code size
// since we are just moving code around, + optimizing, so worth it
// if small enough that we are pretty sure its ok
- if (calls == 1 && !usedGlobally && size <= CAREFUL_SIZE_LIMIT)
+ if (calls == 1 && !usedGlobally && size <= CAREFUL_SIZE_LIMIT) {
return true;
+ }
// more than one use, so we can't eliminate it after inlining,
// so only worth it if we really care about speed and don't care
// about size, and if it's lightweight so a good candidate for
@@ -300,8 +303,9 @@ struct Inlining : public Pass {
state.worthInlining.insert(func->name);
}
});
- if (state.worthInlining.size() == 0)
+ if (state.worthInlining.size() == 0) {
return false;
+ }
// fill in actionsForFunction, as we operate on it in parallel (each
// function to its own entry)
for (auto& func : module->functions) {
@@ -323,16 +327,18 @@ struct Inlining : public Pass {
// avoid risk of races
// note that we do not risk stalling progress, as each iteration() will
// inline at least one call before hitting this
- if (inlinedUses.count(func->name))
+ if (inlinedUses.count(func->name)) {
continue;
+ }
for (auto& action : state.actionsForFunction[func->name]) {
auto* inlinedFunction = action.contents;
// if we've inlined into a function, don't inline it in this iteration,
// avoid risk of races
// note that we do not risk stalling progress, as each iteration() will
// inline at least one call before hitting this
- if (inlinedInto.count(inlinedFunction))
+ if (inlinedInto.count(inlinedFunction)) {
continue;
+ }
Name inlinedName = inlinedFunction->name;
#ifdef INLINING_DEBUG
std::cout << "inline " << inlinedName << " into " << func->name << '\n';
diff --git a/src/passes/LegalizeJSInterface.cpp b/src/passes/LegalizeJSInterface.cpp
index 324590427..ad6d0c35b 100644
--- a/src/passes/LegalizeJSInterface.cpp
+++ b/src/passes/LegalizeJSInterface.cpp
@@ -105,13 +105,15 @@ struct LegalizeJSInterface : public Pass {
void visitCall(Call* curr) {
auto iter = illegalImportsToLegal->find(curr->target);
- if (iter == illegalImportsToLegal->end())
+ if (iter == illegalImportsToLegal->end()) {
return;
+ }
- if (iter->second == getFunction()->name)
+ if (iter->second == getFunction()->name) {
// inside the stub function itself, is the one safe place to do the
// call
return;
+ }
replaceCurrent(Builder(*getModule())
.makeCall(iter->second, curr->operands, curr->type));
}
@@ -130,24 +132,27 @@ private:
template<typename T> bool isIllegal(T* t) {
for (auto param : t->params) {
- if (param == i64)
+ if (param == i64) {
return true;
+ }
}
return t->result == i64;
}
// Check if an export should be legalized.
bool shouldBeLegalized(Export* ex, Function* func) {
- if (full)
+ if (full) {
return true;
+ }
// We are doing minimal legalization - just what JS needs.
return ex->name.startsWith("dynCall_");
}
// Check if an import should be legalized.
bool shouldBeLegalized(Function* im) {
- if (full)
+ if (full) {
return true;
+ }
// We are doing minimal legalization - just what JS needs.
return im->module == ENV && im->base.startsWith("invoke_");
}
diff --git a/src/passes/LoopInvariantCodeMotion.cpp b/src/passes/LoopInvariantCodeMotion.cpp
index e9f376bd3..b8e00ffce 100644
--- a/src/passes/LoopInvariantCodeMotion.cpp
+++ b/src/passes/LoopInvariantCodeMotion.cpp
@@ -208,8 +208,9 @@ struct LoopInvariantCodeMotion
if (auto* set = curr->dynCast<SetLocal>()) {
while (1) {
auto* next = set->value->dynCast<SetLocal>();
- if (!next)
+ if (!next) {
break;
+ }
set = next;
}
if (set->value->is<GetLocal>() || set->value->is<Const>()) {
@@ -226,8 +227,9 @@ struct LoopInvariantCodeMotion
for (auto* set : sets) {
// nullptr means a parameter or zero-init value;
// no danger to us.
- if (!set)
+ if (!set) {
continue;
+ }
// Check if the set is in the loop. If not, it's either before,
// which is fine, or after, which is also fine - moving curr
// to just outside the loop will preserve those relationships.
diff --git a/src/passes/MemoryPacking.cpp b/src/passes/MemoryPacking.cpp
index 11dbc1743..99eb2e285 100644
--- a/src/passes/MemoryPacking.cpp
+++ b/src/passes/MemoryPacking.cpp
@@ -57,8 +57,9 @@ struct MemoryPacking : public Pass {
};
for (auto& segment : module->memory.segments) {
- if (!isSplittable(segment))
+ if (!isSplittable(segment)) {
continue;
+ }
// skip final zeros
while (segment.data.size() > 0 && segment.data.back() == 0) {
diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp
index 8df35abd2..973f17eec 100644
--- a/src/passes/MergeBlocks.cpp
+++ b/src/passes/MergeBlocks.cpp
@@ -259,16 +259,19 @@ optimizeBlock(Block* curr, Module* module, PassOptions& passOptions) {
}
}
// If no block, we can't do anything.
- if (!childBlock)
+ if (!childBlock) {
continue;
+ }
auto& childList = childBlock->list;
auto childSize = childList.size();
- if (childSize == 0)
+ if (childSize == 0) {
continue;
+ }
// If the child has items after an unreachable, ignore it - dce should
// have been run, and we prefer to not handle the complexity here.
- if (hasDeadCode(childBlock))
+ if (hasDeadCode(childBlock)) {
continue;
+ }
// In some cases we can remove only the head or the tail of the block,
// and must keep some things in the child block.
Index keepStart = childSize;
@@ -314,8 +317,9 @@ optimizeBlock(Block* curr, Module* module, PassOptions& passOptions) {
}
// Maybe there's nothing to do, if we must keep it all in the
// child anyhow.
- if (keepStart == 0 && keepEnd == childSize)
+ if (keepStart == 0 && keepEnd == childSize) {
continue;
+ }
// There is something to do!
bool keepingPart = keepStart < keepEnd;
// Create a new merged list, and fill in the code before the
@@ -411,20 +415,23 @@ struct MergeBlocks : public WalkerPass<PostWalker<MergeBlocks>> {
Block* outer = nullptr,
Expression** dependency1 = nullptr,
Expression** dependency2 = nullptr) {
- if (!child)
+ if (!child) {
return outer;
+ }
if ((dependency1 && *dependency1) || (dependency2 && *dependency2)) {
// there are dependencies, things we must be reordered through. make sure
// no problems there
EffectAnalyzer childEffects(getPassOptions(), child);
if (dependency1 && *dependency1 &&
EffectAnalyzer(getPassOptions(), *dependency1)
- .invalidates(childEffects))
+ .invalidates(childEffects)) {
return outer;
+ }
if (dependency2 && *dependency2 &&
EffectAnalyzer(getPassOptions(), *dependency2)
- .invalidates(childEffects))
+ .invalidates(childEffects)) {
return outer;
+ }
}
if (auto* block = child->dynCast<Block>()) {
if (!block->name.is() && block->list.size() >= 2) {
@@ -489,14 +496,17 @@ struct MergeBlocks : public WalkerPass<PostWalker<MergeBlocks>> {
// TODO: for now, just stop when we see any side effect. instead, we could
// check effects carefully for reordering
Block* outer = nullptr;
- if (EffectAnalyzer(getPassOptions(), first).hasSideEffects())
+ if (EffectAnalyzer(getPassOptions(), first).hasSideEffects()) {
return;
+ }
outer = optimize(curr, first, outer);
- if (EffectAnalyzer(getPassOptions(), second).hasSideEffects())
+ if (EffectAnalyzer(getPassOptions(), second).hasSideEffects()) {
return;
+ }
outer = optimize(curr, second, outer);
- if (EffectAnalyzer(getPassOptions(), third).hasSideEffects())
+ if (EffectAnalyzer(getPassOptions(), third).hasSideEffects()) {
return;
+ }
optimize(curr, third, outer);
}
void visitAtomicCmpxchg(AtomicCmpxchg* curr) {
@@ -519,8 +529,10 @@ struct MergeBlocks : public WalkerPass<PostWalker<MergeBlocks>> {
template<typename T> void handleCall(T* curr) {
Block* outer = nullptr;
for (Index i = 0; i < curr->operands.size(); i++) {
- if (EffectAnalyzer(getPassOptions(), curr->operands[i]).hasSideEffects())
+ if (EffectAnalyzer(getPassOptions(), curr->operands[i])
+ .hasSideEffects()) {
return;
+ }
outer = optimize(curr, curr->operands[i], outer);
}
return;
@@ -531,12 +543,15 @@ struct MergeBlocks : public WalkerPass<PostWalker<MergeBlocks>> {
void visitCallIndirect(CallIndirect* curr) {
Block* outer = nullptr;
for (Index i = 0; i < curr->operands.size(); i++) {
- if (EffectAnalyzer(getPassOptions(), curr->operands[i]).hasSideEffects())
+ if (EffectAnalyzer(getPassOptions(), curr->operands[i])
+ .hasSideEffects()) {
return;
+ }
outer = optimize(curr, curr->operands[i], outer);
}
- if (EffectAnalyzer(getPassOptions(), curr->target).hasSideEffects())
+ if (EffectAnalyzer(getPassOptions(), curr->target).hasSideEffects()) {
return;
+ }
optimize(curr, curr->target, outer);
}
};
diff --git a/src/passes/MergeLocals.cpp b/src/passes/MergeLocals.cpp
index fe9f4bb86..e8d42e8dd 100644
--- a/src/passes/MergeLocals.cpp
+++ b/src/passes/MergeLocals.cpp
@@ -96,8 +96,9 @@ struct MergeLocals
}
void optimizeCopies() {
- if (copies.empty())
+ if (copies.empty()) {
return;
+ }
// compute all dependencies
LocalGraph preGraph(getFunction());
preGraph.computeInfluences();
diff --git a/src/passes/Metrics.cpp b/src/passes/Metrics.cpp
index 0baca3e8b..ca558cd4f 100644
--- a/src/passes/Metrics.cpp
+++ b/src/passes/Metrics.cpp
@@ -179,8 +179,9 @@ struct Metrics
o << title << "\n";
for (auto* key : keys) {
auto value = counts[key];
- if (value == 0 && key[0] != '[')
+ if (value == 0 && key[0] != '[') {
continue;
+ }
o << " " << left << setw(15) << key << ": " << setw(8) << value;
if (lastCounts.count(key)) {
int before = lastCounts[key];
diff --git a/src/passes/NoExitRuntime.cpp b/src/passes/NoExitRuntime.cpp
index 680b91b23..82a296cfc 100644
--- a/src/passes/NoExitRuntime.cpp
+++ b/src/passes/NoExitRuntime.cpp
@@ -41,8 +41,9 @@ struct NoExitRuntime : public WalkerPass<PostWalker<NoExitRuntime>> {
void visitCall(Call* curr) {
auto* import = getModule()->getFunctionOrNull(curr->target);
- if (!import || !import->imported() || import->module != ENV)
+ if (!import || !import->imported() || import->module != ENV) {
return;
+ }
for (auto name : ATEXIT_NAMES) {
if (name == import->base) {
replaceCurrent(Builder(*getModule()).replaceWithIdenticalType(curr));
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 8a9309554..85258dbb8 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -102,8 +102,9 @@ Index getMaxBits(Expression* curr, LocalInfoProvider* localInfoProvider) {
case ShrSInt32: {
if (auto* shift = binary->right->dynCast<Const>()) {
auto maxBits = getMaxBits(binary->left, localInfoProvider);
- if (maxBits == 32)
+ if (maxBits == 32) {
return 32;
+ }
auto shifts =
std::min(Index(Bits::getEffectiveShifts(shift)),
maxBits); // can ignore more shifts than zero us out
@@ -227,11 +228,13 @@ struct LocalScanner : PostWalker<LocalScanner> {
void visitSetLocal(SetLocal* curr) {
auto* func = getFunction();
- if (func->isParam(curr->index))
+ if (func->isParam(curr->index)) {
return;
+ }
auto type = getFunction()->getLocalType(curr->index);
- if (type != i32 && type != i64)
+ if (type != i32 && type != i64) {
return;
+ }
// an integer var, worth processing
auto* value = Properties::getFallthrough(curr->value);
auto& info = localInfo[curr->index];
@@ -501,12 +504,14 @@ struct OptimizeInstructions
}
}
auto* ret = optimizeAddedConstants(binary);
- if (ret)
+ if (ret) {
return ret;
+ }
} else if (binary->op == SubInt32) {
auto* ret = optimizeAddedConstants(binary);
- if (ret)
+ if (ret) {
return ret;
+ }
}
// a bunch of operations on a constant right side can be simplified
if (auto* right = binary->right->dynCast<Const>()) {
@@ -532,8 +537,9 @@ struct OptimizeInstructions
}
// some math operations have trivial results
Expression* ret = optimizeWithConstantOnRight(binary);
- if (ret)
+ if (ret) {
return ret;
+ }
// the square of some operations can be merged
if (auto* left = binary->left->dynCast<Binary>()) {
if (left->op == binary->op) {
@@ -575,8 +581,9 @@ struct OptimizeInstructions
// a bunch of operations on a constant left side can be simplified
if (binary->left->is<Const>()) {
Expression* ret = optimizeWithConstantOnLeft(binary);
- if (ret)
+ if (ret) {
return ret;
+ }
}
// bitwise operations
if (binary->op == AndInt32) {
@@ -895,8 +902,9 @@ private:
if (binary->left->is<Const>() && !binary->right->is<Const>()) {
return swap();
}
- if (binary->right->is<Const>())
+ if (binary->right->is<Const>()) {
return;
+ }
// Prefer a get on the right.
if (binary->left->is<GetLocal>() && !binary->right->is<GetLocal>()) {
return maybeSwap();
@@ -1085,8 +1093,9 @@ private:
};
Expression* walked = binary;
ZeroRemover(getPassOptions()).walk(walked);
- if (constant == 0)
+ if (constant == 0) {
return walked; // nothing more to do
+ }
if (auto* c = walked->dynCast<Const>()) {
assert(c->value.geti32() == 0);
c->value = Literal(constant);
@@ -1103,40 +1112,48 @@ private:
Expression* conditionalizeExpensiveOnBitwise(Binary* binary) {
// this operation can increase code size, so don't always do it
auto& options = getPassRunner()->options;
- if (options.optimizeLevel < 2 || options.shrinkLevel > 0)
+ if (options.optimizeLevel < 2 || options.shrinkLevel > 0) {
return nullptr;
+ }
const auto MIN_COST = 7;
assert(binary->op == AndInt32 || binary->op == OrInt32);
- if (binary->right->is<Const>())
+ if (binary->right->is<Const>()) {
return nullptr; // trivial
+ }
// bitwise logical operator on two non-numerical values, check if they are
// boolean
auto* left = binary->left;
auto* right = binary->right;
- if (!Properties::emitsBoolean(left) || !Properties::emitsBoolean(right))
+ if (!Properties::emitsBoolean(left) || !Properties::emitsBoolean(right)) {
return nullptr;
+ }
auto leftEffects = EffectAnalyzer(getPassOptions(), left);
auto rightEffects = EffectAnalyzer(getPassOptions(), right);
auto leftHasSideEffects = leftEffects.hasSideEffects();
auto rightHasSideEffects = rightEffects.hasSideEffects();
- if (leftHasSideEffects && rightHasSideEffects)
+ if (leftHasSideEffects && rightHasSideEffects) {
return nullptr; // both must execute
+ }
// canonicalize with side effects, if any, happening on the left
if (rightHasSideEffects) {
- if (CostAnalyzer(left).cost < MIN_COST)
+ if (CostAnalyzer(left).cost < MIN_COST) {
return nullptr; // avoidable code is too cheap
- if (leftEffects.invalidates(rightEffects))
+ }
+ if (leftEffects.invalidates(rightEffects)) {
return nullptr; // cannot reorder
+ }
std::swap(left, right);
} else if (leftHasSideEffects) {
- if (CostAnalyzer(right).cost < MIN_COST)
+ if (CostAnalyzer(right).cost < MIN_COST) {
return nullptr; // avoidable code is too cheap
+ }
} else {
// no side effects, reorder based on cost estimation
auto leftCost = CostAnalyzer(left).cost;
auto rightCost = CostAnalyzer(right).cost;
- if (std::max(leftCost, rightCost) < MIN_COST)
+ if (std::max(leftCost, rightCost) < MIN_COST) {
return nullptr; // avoidable code is too cheap
+ }
// canonicalize with expensive code on the right
if (leftCost > rightCost) {
std::swap(left, right);
@@ -1240,8 +1257,9 @@ private:
auto* outerConst = outer->right->cast<Const>();
auto* innerConst = inner->right->cast<Const>();
auto* value = inner->left;
- if (outerConst->value == innerConst->value)
+ if (outerConst->value == innerConst->value) {
return value;
+ }
// add a shift, by reusing the existing node
innerConst->value = innerConst->value.sub(outerConst->value);
return inner;
diff --git a/src/passes/PostEmscripten.cpp b/src/passes/PostEmscripten.cpp
index 6c9b84d7c..cc4b03a7f 100644
--- a/src/passes/PostEmscripten.cpp
+++ b/src/passes/PostEmscripten.cpp
@@ -35,8 +35,9 @@ struct PostEmscripten : public WalkerPass<PostWalker<PostEmscripten>> {
void visitCall(Call* curr) {
// special asm.js imports can be optimized
auto* func = getModule()->getFunction(curr->target);
- if (!func->imported())
+ if (!func->imported()) {
return;
+ }
if (func->module == GLOBAL_MATH) {
if (func->base == POW) {
if (auto* exponent = curr->operands[1]->dynCast<Const>()) {
diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp
index 074dd832c..02fd089ec 100644
--- a/src/passes/Precompute.cpp
+++ b/src/passes/Precompute.cpp
@@ -163,20 +163,24 @@ struct Precompute
void visitExpression(Expression* curr) {
// TODO: if local.get, only replace with a constant if we don't care about
// size...?
- if (curr->is<Const>() || curr->is<Nop>())
+ if (curr->is<Const>() || curr->is<Nop>()) {
return;
+ }
// Until engines implement v128.const and we have SIMD-aware optimizations
// that can break large v128.const instructions into smaller consts and
// splats, do not try to precompute v128 expressions.
- if (isVectorType(curr->type))
+ if (isVectorType(curr->type)) {
return;
+ }
// try to evaluate this into a const
Flow flow = precomputeExpression(curr);
- if (isVectorType(flow.value.type))
+ if (isVectorType(flow.value.type)) {
return;
+ }
if (flow.breaking()) {
- if (flow.breakTo == NOTPRECOMPUTABLE_FLOW)
+ if (flow.breakTo == NOTPRECOMPUTABLE_FLOW) {
return;
+ }
if (flow.breakTo == RETURN_FLOW) {
// this expression causes a return. if it's already a return, reuse the
// node
@@ -301,8 +305,9 @@ private:
// mark it as such and add everything it influences to the work list,
// as they may be constant too.
if (auto* set = curr->dynCast<SetLocal>()) {
- if (setValues[set].isConcrete())
+ if (setValues[set].isConcrete()) {
continue; // already known constant
+ }
auto value = setValues[set] = precomputeValue(set->value);
if (value.isConcrete()) {
for (auto* get : localGraph.setInfluences[set]) {
@@ -311,8 +316,9 @@ private:
}
} else {
auto* get = curr->cast<GetLocal>();
- if (getValues[get].isConcrete())
+ if (getValues[get].isConcrete()) {
continue; // already known constant
+ }
// for this get to have constant value, all sets must agree
Literal value;
bool first = true;
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 405097455..73d91b9ce 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -132,8 +132,9 @@ struct PrintExpressionContents : public Visitor<PrintExpressionContents> {
}
void visitLoad(Load* curr) {
prepareColor(o) << printType(curr->type);
- if (curr->isAtomic)
+ if (curr->isAtomic) {
o << ".atomic";
+ }
o << ".load";
if (curr->type != unreachable && curr->bytes < getTypeSize(curr->type)) {
if (curr->bytes == 1) {
@@ -157,8 +158,9 @@ struct PrintExpressionContents : public Visitor<PrintExpressionContents> {
}
void visitStore(Store* curr) {
prepareColor(o) << printType(curr->valueType);
- if (curr->isAtomic)
+ if (curr->isAtomic) {
o << ".atomic";
+ }
o << ".store";
if (curr->bytes < 4 || (curr->valueType == i64 && curr->bytes < 8)) {
if (curr->bytes == 1) {
@@ -1174,8 +1176,9 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
PrintSExpression(std::ostream& o) : o(o) {
setMinify(false);
- if (!full)
+ if (!full) {
full = isFullForced();
+ }
}
void printDebugLocation(const Function::DebugLocation& location) {
@@ -1214,8 +1217,9 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
void setFull(bool full_) { full = full_; }
void incIndent() {
- if (minify)
+ if (minify) {
return;
+ }
o << '\n';
indent++;
}
@@ -1352,8 +1356,9 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
}
incIndent();
}
- if (curr->value && !curr->value->is<Nop>())
+ if (curr->value && !curr->value->is<Nop>()) {
printFullLine(curr->value);
+ }
if (curr->condition) {
printFullLine(curr->condition);
}
@@ -1363,8 +1368,9 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
o << '(';
PrintExpressionContents(currFunction, o).visit(curr);
incIndent();
- if (curr->value && !curr->value->is<Nop>())
+ if (curr->value && !curr->value->is<Nop>()) {
printFullLine(curr->value);
+ }
printFullLine(curr->condition);
decIndent();
}
@@ -1618,8 +1624,9 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
// Module-level visitors
void visitFunctionType(FunctionType* curr, Name* internalName = nullptr) {
o << "(func";
- if (internalName)
+ if (internalName) {
o << ' ' << *internalName;
+ }
if (curr->params.size() > 0) {
o << maybeSpace;
o << '(';
@@ -1803,13 +1810,15 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
printMedium(o, "table") << ' ';
printName(curr->name, o) << ' ';
o << curr->initial;
- if (curr->hasMax())
+ if (curr->hasMax()) {
o << ' ' << curr->max;
+ }
o << " funcref)";
}
void visitTable(Table* curr) {
- if (!curr->exists)
+ if (!curr->exists) {
return;
+ }
if (curr->imported()) {
doIndent(o, indent);
o << '(';
@@ -1823,8 +1832,9 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
}
for (auto& segment : curr->segments) {
// Don't print empty segments
- if (segment.data.empty())
+ if (segment.data.empty()) {
continue;
+ }
doIndent(o, indent);
o << '(';
printMajor(o, "elem ");
@@ -1845,15 +1855,18 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
printMedium(o, "shared ");
}
o << curr->initial;
- if (curr->hasMax())
+ if (curr->hasMax()) {
o << ' ' << curr->max;
- if (curr->shared)
+ }
+ if (curr->shared) {
o << ")";
+ }
o << ")";
}
void visitMemory(Memory* curr) {
- if (!curr->exists)
+ if (!curr->exists) {
return;
+ }
if (curr->imported()) {
doIndent(o, indent);
o << '(';
@@ -2104,8 +2117,9 @@ WasmPrinter::printStackIR(StackIR* ir, std::ostream& o, Function* func) {
};
for (Index i = 0; i < (*ir).size(); i++) {
auto* inst = (*ir)[i];
- if (!inst)
+ if (!inst) {
continue;
+ }
switch (inst->op) {
case StackInst::Basic: {
doIndent();
diff --git a/src/passes/PrintCallGraph.cpp b/src/passes/PrintCallGraph.cpp
index 7df5a8875..6d9224a21 100644
--- a/src/passes/PrintCallGraph.cpp
+++ b/src/passes/PrintCallGraph.cpp
@@ -85,8 +85,9 @@ struct PrintCallGraph : public Pass {
}
void visitCall(Call* curr) {
auto* target = module->getFunction(curr->target);
- if (visitedTargets.count(target->name) > 0)
+ if (visitedTargets.count(target->name) > 0) {
return;
+ }
visitedTargets.insert(target->name);
std::cout << " \"" << currFunction->name << "\" -> \"" << target->name
<< "\"; // call\n";
diff --git a/src/passes/ReReloop.cpp b/src/passes/ReReloop.cpp
index 3a7c2ad87..0fbe22c71 100644
--- a/src/passes/ReReloop.cpp
+++ b/src/passes/ReReloop.cpp
@@ -91,8 +91,9 @@ struct ReReloop final : public Pass {
CFG::Block* to,
const std::set<Index>& values) {
std::vector<Index> list;
- for (auto i : values)
+ for (auto i : values) {
list.push_back(i);
+ }
from->AddSwitchBranchTo(to, std::move(list));
}
diff --git a/src/passes/RedundantSetElimination.cpp b/src/passes/RedundantSetElimination.cpp
index e03020da0..bd0e5b890 100644
--- a/src/passes/RedundantSetElimination.cpp
+++ b/src/passes/RedundantSetElimination.cpp
@@ -145,12 +145,14 @@ struct RedundantSetElimination
bool isBlockMergeValue(BasicBlock* block, Index index, Index value) {
auto iter = blockMergeValues.find(block);
- if (iter == blockMergeValues.end())
+ if (iter == blockMergeValues.end()) {
return false;
+ }
auto& mergeValues = iter->second;
auto iter2 = mergeValues.find(index);
- if (iter2 == mergeValues.end())
+ if (iter2 == mergeValues.end()) {
return false;
+ }
return value == iter2->second;
}
diff --git a/src/passes/RelooperJumpThreading.cpp b/src/passes/RelooperJumpThreading.cpp
index 9fcf7a4a8..855e89b7f 100644
--- a/src/passes/RelooperJumpThreading.cpp
+++ b/src/passes/RelooperJumpThreading.cpp
@@ -37,17 +37,21 @@ static Name getOuterName(int i) {
}
static If* isLabelCheckingIf(Expression* curr, Index labelIndex) {
- if (!curr)
+ if (!curr) {
return nullptr;
+ }
auto* iff = curr->dynCast<If>();
- if (!iff)
+ if (!iff) {
return nullptr;
+ }
auto* condition = iff->condition->dynCast<Binary>();
- if (!(condition && condition->op == EqInt32))
+ if (!(condition && condition->op == EqInt32)) {
return nullptr;
+ }
auto* left = condition->left->dynCast<GetLocal>();
- if (!(left && left->index == labelIndex))
+ if (!(left && left->index == labelIndex)) {
return nullptr;
+ }
return iff;
}
@@ -56,13 +60,16 @@ static Index getCheckedLabelValue(If* iff) {
}
static SetLocal* isLabelSettingSetLocal(Expression* curr, Index labelIndex) {
- if (!curr)
+ if (!curr) {
return nullptr;
+ }
auto* set = curr->dynCast<SetLocal>();
- if (!set)
+ if (!set) {
return nullptr;
- if (set->index != labelIndex)
+ }
+ if (set->index != labelIndex) {
return nullptr;
+ }
return set;
}
@@ -108,8 +115,9 @@ struct RelooperJumpThreading
void visitBlock(Block* curr) {
// look for the if label == X pattern
auto& list = curr->list;
- if (list.size() == 0)
+ if (list.size() == 0) {
return;
+ }
for (Index i = 0; i < list.size() - 1; i++) {
// once we see something that might be irreducible, we must skip that if
// and the rest of the dependents
@@ -186,8 +194,9 @@ private:
while (iff) {
auto num = getCheckedLabelValue(iff);
assert(labelChecks[num] > 0);
- if (labelChecks[num] > 1)
+ if (labelChecks[num] > 1) {
return true; // checked more than once, somewhere in function
+ }
assert(labelChecksInOrigin[num] == 0);
if (labelSetsInOrigin[num] != labelSets[num]) {
assert(labelSetsInOrigin[num] < labelSets[num]);
diff --git a/src/passes/RemoveNonJSOps.cpp b/src/passes/RemoveNonJSOps.cpp
index 26ede65c5..dd23aa9bf 100644
--- a/src/passes/RemoveNonJSOps.cpp
+++ b/src/passes/RemoveNonJSOps.cpp
@@ -56,8 +56,9 @@ struct RemoveNonJSOpsPass : public WalkerPass<PostWalker<RemoveNonJSOpsPass>> {
// Discover all of the intrinsics that we need to inject, lowering all
// operations to intrinsic calls while we're at it.
- if (!builder)
+ if (!builder) {
builder = make_unique<Builder>(*module);
+ }
PostWalker<RemoveNonJSOpsPass>::doWalkModule(module);
if (neededIntrinsics.size() == 0) {
@@ -142,8 +143,9 @@ struct RemoveNonJSOpsPass : public WalkerPass<PostWalker<RemoveNonJSOpsPass>> {
}
void doWalkFunction(Function* func) {
- if (!builder)
+ if (!builder) {
builder = make_unique<Builder>(*getModule());
+ }
PostWalker<RemoveNonJSOpsPass>::doWalkFunction(func);
}
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp
index 4b5c9613e..20811efef 100644
--- a/src/passes/RemoveUnusedBrs.cpp
+++ b/src/passes/RemoveUnusedBrs.cpp
@@ -36,13 +36,16 @@ static bool canTurnIfIntoBrIf(Expression* ifCondition,
Expression* brValue,
PassOptions& options) {
// if the if isn't even reached, this is all dead code anyhow
- if (ifCondition->type == unreachable)
+ if (ifCondition->type == unreachable) {
return false;
- if (!brValue)
+ }
+ if (!brValue) {
return true;
+ }
EffectAnalyzer value(options, brValue);
- if (value.hasSideEffects())
+ if (value.hasSideEffects()) {
return false;
+ }
return !EffectAnalyzer(options, ifCondition).invalidates(value);
}
@@ -219,8 +222,9 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
}
// when there isn't a value, we can do some trivial optimizations without
// worrying about the value being executed before the condition
- if (curr->value)
+ if (curr->value) {
return;
+ }
if (curr->targets.size() == 0) {
// a switch with just a default always goes there
Builder builder(*getModule());
@@ -344,19 +348,23 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
// helpful, as it shortens the logical loop. it is also good to generate
// an if-else instead of an if, as it might allow an eqz to be removed
// by flipping arms)
- if (!loop->name.is())
+ if (!loop->name.is()) {
return false;
+ }
auto* block = loop->body->dynCast<Block>();
- if (!block)
+ if (!block) {
return false;
+ }
// does the last element break to the top of the loop?
auto& list = block->list;
- if (list.size() <= 1)
+ if (list.size() <= 1) {
return false;
+ }
auto* last = list.back()->dynCast<Break>();
if (!last || !ExpressionAnalyzer::isSimple(last) ||
- last->name != loop->name)
+ last->name != loop->name) {
return false;
+ }
// last is a simple break to the top of the loop. if we can conditionalize
// it, it won't block things from flowing out and not needing breaks to do
// so.
@@ -391,8 +399,9 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
auto blockifyMerge = [&](Expression* any,
Expression* append) -> Block* {
Block* block = nullptr;
- if (any)
+ if (any) {
block = any->dynCast<Block>();
+ }
// if the first isn't a block, or it's a block with a name (so we
// might branch to the end, and so can't append to it, we might skip
// that code!) then make a new block
@@ -468,8 +477,9 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
if (EffectAnalyzer(getPassOptions(), curr).branches) {
return false;
}
- if (i == 0)
+ if (i == 0) {
return false;
+ }
i--;
}
}
@@ -560,8 +570,9 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
// optimized
for (Index i = 0; i < flows.size(); i++) {
auto* flow = (*flows[i])->dynCast<Return>();
- if (!flow)
+ if (!flow) {
continue;
+ }
if (!flow->value) {
// return => nop
ExpressionManipulator::nop(flow);
@@ -689,10 +700,11 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
auto& list = curr->list;
for (Index i = 0; i < list.size(); i++) {
auto* iff = list[i]->dynCast<If>();
- if (!iff || !iff->ifFalse)
+ if (!iff || !iff->ifFalse) {
// if it lacked an if-false, it would already be a br_if, as that's
// the easy case
continue;
+ }
auto* ifTrueBreak = iff->ifTrue->dynCast<Break>();
if (ifTrueBreak && !ifTrueBreak->condition &&
canTurnIfIntoBrIf(
@@ -724,12 +736,14 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
auto* br1 = list[i]->dynCast<Break>();
// avoid unreachable brs, as they are dead code anyhow, and after
// merging them the outer scope could need type changes
- if (!br1 || !br1->condition || br1->type == unreachable)
+ if (!br1 || !br1->condition || br1->type == unreachable) {
continue;
+ }
assert(!br1->value);
auto* br2 = list[i + 1]->dynCast<Break>();
- if (!br2 || br1->name != br2->name)
+ if (!br2 || br1->name != br2->name) {
continue;
+ }
assert(!br2->value); // same target as previous, which has no value
// a br_if and then a br[_if] with the same target right after it
if (br2->condition) {
@@ -862,8 +876,9 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
const auto MAX_COST = 7;
auto total =
CostAnalyzer(iff->ifTrue).cost + CostAnalyzer(iff->ifFalse).cost;
- if (total >= MAX_COST)
+ if (total >= MAX_COST) {
return nullptr;
+ }
}
// Check if side effects allow this.
EffectAnalyzer condition(passOptions, iff->condition);
@@ -889,10 +904,12 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
}
void optimizeSetIf(Expression** currp) {
- if (optimizeSetIfWithBrArm(currp))
+ if (optimizeSetIfWithBrArm(currp)) {
return;
- if (optimizeSetIfWithCopyArm(currp))
+ }
+ if (optimizeSetIfWithCopyArm(currp)) {
return;
+ }
}
// If one arm is a br, we prefer a br_if and the set later:
@@ -1003,8 +1020,9 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
get = nullptr;
}
}
- if (!get)
+ if (!get) {
return false;
+ }
// We can do it!
bool tee = set->isTee();
assert(set->index == get->index);
@@ -1045,8 +1063,9 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
// TODO: consider also looking at <= etc. and not just eq
void tablify(Block* block) {
auto& list = block->list;
- if (list.size() <= 1)
+ if (list.size() <= 1) {
return;
+ }
// Heuristics. These are slightly inspired by the constants from the
// asm.js backend.
@@ -1065,25 +1084,32 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
// or nullptr otherwise
auto getProperBrIf = [](Expression* curr) -> Break* {
auto* br = curr->dynCast<Break>();
- if (!br)
+ if (!br) {
return nullptr;
- if (!br->condition || br->value)
+ }
+ if (!br->condition || br->value) {
return nullptr;
- if (br->type != none)
+ }
+ if (br->type != none) {
// no value, so can be unreachable or none. ignore unreachable ones,
// dce will clean it up
return nullptr;
+ }
auto* binary = br->condition->dynCast<Binary>();
- if (!binary)
+ if (!binary) {
return nullptr;
- if (binary->op != EqInt32)
+ }
+ if (binary->op != EqInt32) {
return nullptr;
+ }
auto* c = binary->right->dynCast<Const>();
- if (!c)
+ if (!c) {
return nullptr;
+ }
uint32_t value = c->value.geti32();
- if (value >= uint32_t(std::numeric_limits<int32_t>::max()))
+ if (value >= uint32_t(std::numeric_limits<int32_t>::max())) {
return nullptr;
+ }
return br;
};
@@ -1092,8 +1118,9 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
auto getProperBrIfConditionValue =
[&getProperBrIf](Expression* curr) -> Expression* {
auto* br = getProperBrIf(curr);
- if (!br)
+ if (!br) {
return nullptr;
+ }
return br->condition->cast<Binary>()->left;
};
@@ -1160,8 +1187,9 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
Index i = 0;
while (1) {
defaultName = "tablify|" + std::to_string(i++);
- if (usedNames.count(defaultName) == 0)
+ if (usedNames.count(defaultName) == 0) {
break;
+ }
}
std::vector<Name> table;
for (Index i = start; i < end; i++) {
diff --git a/src/passes/RemoveUnusedModuleElements.cpp b/src/passes/RemoveUnusedModuleElements.cpp
index 3338bb756..ca0817b20 100644
--- a/src/passes/RemoveUnusedModuleElements.cpp
+++ b/src/passes/RemoveUnusedModuleElements.cpp
@@ -256,8 +256,9 @@ struct RemoveUnusedModuleElements : public Pass {
std::unordered_map<std::string, FunctionType*> canonicals;
std::unordered_set<FunctionType*> needed;
auto canonicalize = [&](Name name) {
- if (!name.is())
+ if (!name.is()) {
return name;
+ }
FunctionType* type = module->getFunctionType(name);
auto sig = getSig(type);
auto iter = canonicals.find(sig);
diff --git a/src/passes/RemoveUnusedNames.cpp b/src/passes/RemoveUnusedNames.cpp
index 86db53b0c..3db5a2173 100644
--- a/src/passes/RemoveUnusedNames.cpp
+++ b/src/passes/RemoveUnusedNames.cpp
@@ -61,15 +61,18 @@ struct RemoveUnusedNames : public WalkerPass<PostWalker<RemoveUnusedNames>> {
auto& branches = branchesSeen[curr->name];
for (auto* branch : branches) {
if (Break* br = branch->dynCast<Break>()) {
- if (br->name == curr->name)
+ if (br->name == curr->name) {
br->name = child->name;
+ }
} else if (Switch* sw = branch->dynCast<Switch>()) {
for (auto& target : sw->targets) {
- if (target == curr->name)
+ if (target == curr->name) {
target = child->name;
+ }
}
- if (sw->default_ == curr->name)
+ if (sw->default_ == curr->name) {
sw->default_ = child->name;
+ }
} else {
WASM_UNREACHABLE();
}
diff --git a/src/passes/ReorderLocals.cpp b/src/passes/ReorderLocals.cpp
index 45796c0aa..e5e01af5d 100644
--- a/src/passes/ReorderLocals.cpp
+++ b/src/passes/ReorderLocals.cpp
@@ -47,16 +47,19 @@ struct ReorderLocals : public WalkerPass<PostWalker<ReorderLocals>> {
// sort, keeping params in front (where they will not be moved)
sort(
newToOld.begin(), newToOld.end(), [this, curr](Index a, Index b) -> bool {
- if (curr->isParam(a) && !curr->isParam(b))
+ if (curr->isParam(a) && !curr->isParam(b)) {
return true;
- if (curr->isParam(b) && !curr->isParam(a))
+ }
+ if (curr->isParam(b) && !curr->isParam(a)) {
return false;
+ }
if (curr->isParam(b) && curr->isParam(a)) {
return a < b;
}
if (counts[a] == counts[b]) {
- if (counts[a] == 0)
+ if (counts[a] == 0) {
return a < b;
+ }
return firstUses[a] < firstUses[b];
}
return counts[a] > counts[b];
diff --git a/src/passes/SSAify.cpp b/src/passes/SSAify.cpp
index 2f0f9439c..990a627f6 100644
--- a/src/passes/SSAify.cpp
+++ b/src/passes/SSAify.cpp
@@ -141,8 +141,9 @@ struct SSAify : public Pass {
}
continue;
}
- if (!allowMerges)
+ if (!allowMerges) {
continue;
+ }
// more than 1 set, need a phi: a new local written to at each of the sets
auto new_ = addLocal(get->type);
auto old = get->index;
diff --git a/src/passes/SafeHeap.cpp b/src/passes/SafeHeap.cpp
index a293ee5e9..2cc309a92 100644
--- a/src/passes/SafeHeap.cpp
+++ b/src/passes/SafeHeap.cpp
@@ -69,8 +69,9 @@ struct AccessInstrumenter : public WalkerPass<PostWalker<AccessInstrumenter>> {
AccessInstrumenter* create() override { return new AccessInstrumenter; }
void visitLoad(Load* curr) {
- if (curr->type == unreachable)
+ if (curr->type == unreachable) {
return;
+ }
Builder builder(*getModule());
replaceCurrent(
builder.makeCall(getLoadName(curr),
@@ -82,8 +83,9 @@ struct AccessInstrumenter : public WalkerPass<PostWalker<AccessInstrumenter>> {
}
void visitStore(Store* curr) {
- if (curr->type == unreachable)
+ if (curr->type == unreachable) {
return;
+ }
Builder builder(*getModule());
replaceCurrent(
builder.makeCall(getStoreName(curr),
@@ -161,22 +163,26 @@ struct SafeHeap : public Pass {
// load funcs
Load load;
for (auto type : {i32, i64, f32, f64, v128}) {
- if (type == v128 && !features.hasSIMD())
+ if (type == v128 && !features.hasSIMD()) {
continue;
+ }
load.type = type;
for (Index bytes : {1, 2, 4, 8, 16}) {
load.bytes = bytes;
if (bytes > getTypeSize(type) || (type == f32 && bytes != 4) ||
- (type == f64 && bytes != 8) || (type == v128 && bytes != 16))
+ (type == f64 && bytes != 8) || (type == v128 && bytes != 16)) {
continue;
+ }
for (auto signed_ : {true, false}) {
load.signed_ = signed_;
- if (isFloatType(type) && signed_)
+ if (isFloatType(type) && signed_) {
continue;
+ }
for (Index align : {1, 2, 4, 8, 16}) {
load.align = align;
- if (align > bytes)
+ if (align > bytes) {
continue;
+ }
for (auto isAtomic : {true, false}) {
load.isAtomic = isAtomic;
if (isAtomic && !isPossibleAtomicOperation(
@@ -192,8 +198,9 @@ struct SafeHeap : public Pass {
// store funcs
Store store;
for (auto valueType : {i32, i64, f32, f64, v128}) {
- if (valueType == v128 && !features.hasSIMD())
+ if (valueType == v128 && !features.hasSIMD()) {
continue;
+ }
store.valueType = valueType;
store.type = none;
for (Index bytes : {1, 2, 4, 8, 16}) {
@@ -201,12 +208,14 @@ struct SafeHeap : public Pass {
if (bytes > getTypeSize(valueType) ||
(valueType == f32 && bytes != 4) ||
(valueType == f64 && bytes != 8) ||
- (valueType == v128 && bytes != 16))
+ (valueType == v128 && bytes != 16)) {
continue;
+ }
for (Index align : {1, 2, 4, 8, 16}) {
store.align = align;
- if (align > bytes)
+ if (align > bytes) {
continue;
+ }
for (auto isAtomic : {true, false}) {
store.isAtomic = isAtomic;
if (isAtomic && !isPossibleAtomicOperation(
@@ -223,8 +232,9 @@ struct SafeHeap : public Pass {
// creates a function for a particular style of load
void addLoadFunc(Load style, Module* module) {
auto name = getLoadName(&style);
- if (module->getFunctionOrNull(name))
+ if (module->getFunctionOrNull(name)) {
return;
+ }
auto* func = new Function;
func->name = name;
func->params.push_back(i32); // pointer
@@ -262,8 +272,9 @@ struct SafeHeap : public Pass {
// creates a function for a particular type of store
void addStoreFunc(Store style, Module* module) {
auto name = getStoreName(&style);
- if (module->getFunctionOrNull(name))
+ if (module->getFunctionOrNull(name)) {
return;
+ }
auto* func = new Function;
func->name = name;
func->params.push_back(i32); // pointer
diff --git a/src/passes/SimplifyLocals.cpp b/src/passes/SimplifyLocals.cpp
index 6b714688f..71fd74f43 100644
--- a/src/passes/SimplifyLocals.cpp
+++ b/src/passes/SimplifyLocals.cpp
@@ -403,12 +403,14 @@ struct SimplifyLocals
bool canSink(SetLocal* set) {
// we can never move a tee
- if (set->isTee())
+ if (set->isTee()) {
return false;
+ }
// if in the first cycle, or not allowing tees, then we cannot sink if >1
// use as that would make a tee
- if ((firstCycle || !allowTee) && getCounter.num[set->index] > 1)
+ if ((firstCycle || !allowTee) && getCounter.num[set->index] > 1) {
return false;
+ }
return true;
}
@@ -419,10 +421,12 @@ struct SimplifyLocals
void optimizeLoopReturn(Loop* loop) {
// If there is a sinkable thing in an eligible loop, we can optimize
// it in a trivial way to the outside of the loop.
- if (loop->type != none)
+ if (loop->type != none) {
return;
- if (sinkables.empty())
+ }
+ if (sinkables.empty()) {
return;
+ }
Index goodIndex = sinkables.begin()->first;
// Ensure we have a place to write the return values for, if not, we
// need another cycle.
@@ -455,9 +459,10 @@ struct SimplifyLocals
}
auto breaks = std::move(blockBreaks[block->name]);
blockBreaks.erase(block->name);
- if (breaks.size() == 0)
+ if (breaks.size() == 0) {
// block has no branches TODO we might optimize trivial stuff here too
return;
+ }
// block does not already have a return value (if one break has one, they
// all do)
assert(!(*breaks[0].brp)->template cast<Break>()->value);
@@ -479,8 +484,9 @@ struct SimplifyLocals
break;
}
}
- if (!found)
+ if (!found) {
return;
+ }
// If one of our brs is a br_if, then we will give it a value. since
// the value executes before the condition, it is dangerous if we are
// moving code out of the condition,
@@ -578,8 +584,9 @@ struct SimplifyLocals
assert(iff->ifFalse);
// if this if already has a result, or is unreachable code, we have
// nothing to do
- if (iff->type != none)
+ if (iff->type != none) {
return;
+ }
// We now have the sinkables from both sides of the if, and can look
// for something to sink. That is either a shared index on both sides,
// *or* if one side is unreachable, we can sink anything from the other,
@@ -622,8 +629,9 @@ struct SimplifyLocals
}
}
}
- if (!found)
+ if (!found) {
return;
+ }
// great, we can optimize!
// ensure we have a place to write the return values for, if not, we
// need another cycle
@@ -695,11 +703,13 @@ struct SimplifyLocals
// arm into a one-sided if.
void optimizeIfReturn(If* iff, Expression** currp) {
// If this if is unreachable code, we have nothing to do.
- if (iff->type != none || iff->ifTrue->type != none)
+ if (iff->type != none || iff->ifTrue->type != none) {
return;
+ }
// Anything sinkable is good for us.
- if (sinkables.empty())
+ if (sinkables.empty()) {
return;
+ }
Index goodIndex = sinkables.begin()->first;
// Ensure we have a place to write the return values for, if not, we
// need another cycle.
diff --git a/src/passes/Souperify.cpp b/src/passes/Souperify.cpp
index 1cc3037fe..6d7176e40 100644
--- a/src/passes/Souperify.cpp
+++ b/src/passes/Souperify.cpp
@@ -86,8 +86,9 @@ struct UseFinder {
LocalGraph& localGraph,
std::vector<Expression*>& ret) {
// If already handled, nothing to do here.
- if (seenSets.count(set))
+ if (seenSets.count(set)) {
return;
+ }
seenSets.insert(set);
// Find all the uses of that set.
auto& gets = localGraph.setInfluences[set];
@@ -190,8 +191,9 @@ struct Trace {
}
// Pull in all the dependencies, starting from the value itself.
add(toInfer, 0);
- if (bad)
+ if (bad) {
return;
+ }
// If we are trivial before adding pcs, we are still trivial, and
// can ignore this.
auto sizeBeforePathConditions = nodes.size();
@@ -385,8 +387,9 @@ struct Trace {
}
}
for (auto& node : nodes) {
- if (node == toInfer)
+ if (node == toInfer) {
continue;
+ }
if (auto* origin = node->origin) {
auto uses = UseFinder().getUses(origin, graph, localGraph);
for (auto* use : uses) {
@@ -715,8 +718,9 @@ struct Souperify : public WalkerPass<PostWalker<Souperify>> {
// Build the data-flow IR.
DataFlow::Graph graph;
graph.build(func, getModule());
- if (debug() >= 2)
+ if (debug() >= 2) {
dump(graph, std::cout);
+ }
// Build the local graph data structure.
LocalGraph localGraph(func);
localGraph.computeInfluences();
diff --git a/src/passes/SpillPointers.cpp b/src/passes/SpillPointers.cpp
index 75fa72652..6c194eb60 100644
--- a/src/passes/SpillPointers.cpp
+++ b/src/passes/SpillPointers.cpp
@@ -50,8 +50,9 @@ struct SpillPointers
// note calls in basic blocks
template<typename T> void visitSpillable(T* curr) {
// if in unreachable code, ignore
- if (!currBasicBlock)
+ if (!currBasicBlock) {
return;
+ }
auto* pointer = getCurrentPointer();
currBasicBlock->contents.actions.emplace_back(pointer);
// starts out as correct, may change later
@@ -85,8 +86,9 @@ struct SpillPointers
bool spilled = false;
Index spillLocal = -1;
for (auto& curr : basicBlocks) {
- if (liveBlocks.count(curr.get()) == 0)
+ if (liveBlocks.count(curr.get()) == 0) {
continue; // ignore dead blocks
+ }
auto& liveness = curr->contents;
auto& actions = liveness.actions;
Index lastCall = -1;
@@ -96,8 +98,9 @@ struct SpillPointers
lastCall = i;
}
}
- if (lastCall == Index(-1))
+ if (lastCall == Index(-1)) {
continue; // nothing to see here
+ }
// scan through the block, spilling around the calls
// TODO: we can filter on pointerMap everywhere
LocalSet live = liveness.end;
@@ -149,8 +152,9 @@ struct SpillPointers
Function* func,
Module* module) {
auto* call = *origin;
- if (call->type == unreachable)
+ if (call->type == unreachable) {
return; // the call is never reached anyhow, ignore
+ }
Builder builder(*module);
auto* block = builder.makeBlock();
// move the operands into locals, as we must spill after they are executed
diff --git a/src/passes/StackIR.cpp b/src/passes/StackIR.cpp
index 2506eca27..1f182dbc3 100644
--- a/src/passes/StackIR.cpp
+++ b/src/passes/StackIR.cpp
@@ -94,8 +94,9 @@ private:
bool inUnreachableCode = false;
for (Index i = 0; i < insts.size(); i++) {
auto* inst = insts[i];
- if (!inst)
+ if (!inst) {
continue;
+ }
if (inUnreachableCode) {
// Does the unreachable code end here?
if (isControlFlowBarrier(inst)) {
@@ -143,8 +144,9 @@ private:
#endif
for (Index i = 0; i < insts.size(); i++) {
auto* inst = insts[i];
- if (!inst)
+ if (!inst) {
continue;
+ }
// First, consume values from the stack as required.
auto consumed = getNumConsumedValues(inst);
#ifdef STACK_OPT_DEBUG
@@ -194,8 +196,9 @@ private:
while (1) {
// If there's an actual value in the way, we've failed.
auto index = values[j];
- if (index == null)
+ if (index == null) {
break;
+ }
auto* set = insts[index]->origin->cast<SetLocal>();
if (set->index == get->index) {
// This might be a proper set-get pair, where the set is
@@ -224,8 +227,9 @@ private:
}
}
// We failed here. Can we look some more?
- if (j == 0)
+ if (j == 0) {
break;
+ }
j--;
}
}
@@ -247,8 +251,9 @@ private:
// a branch to that if body
void removeUnneededBlocks() {
for (auto*& inst : insts) {
- if (!inst)
+ if (!inst) {
continue;
+ }
if (auto* block = inst->origin->dynCast<Block>()) {
if (!BranchUtils::BranchSeeker::hasNamed(block, block->name)) {
// TODO optimize, maybe run remove-unused-names
diff --git a/src/passes/Vacuum.cpp b/src/passes/Vacuum.cpp
index 8874ffed2..43a5f8a09 100644
--- a/src/passes/Vacuum.cpp
+++ b/src/passes/Vacuum.cpp
@@ -56,8 +56,9 @@ struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum>> {
Expression* optimize(Expression* curr, bool resultUsed, bool typeMatters) {
auto type = curr->type;
// An unreachable node must not be changed.
- if (type == unreachable)
+ if (type == unreachable) {
return curr;
+ }
// We iterate on possible replacements. If a replacement changes the type,
// stop and go back.
auto* prev = curr;
@@ -104,8 +105,9 @@ struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum>> {
case Expression::Id::ConstId:
case Expression::Id::GetLocalId:
case Expression::Id::GetGlobalId: {
- if (!resultUsed)
+ if (!resultUsed) {
return nullptr;
+ }
return curr;
}
@@ -326,8 +328,9 @@ struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum>> {
}
void visitLoop(Loop* curr) {
- if (curr->body->is<Nop>())
+ if (curr->body->is<Nop>()) {
ExpressionManipulator::nop(curr);
+ }
}
void visitDrop(Drop* curr) {
diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp
index ae940a56d..7cfb21dfe 100644
--- a/src/passes/pass.cpp
+++ b/src/passes/pass.cpp
@@ -43,8 +43,9 @@ void PassRegistry::registerPass(const char* name,
}
Pass* PassRegistry::createPass(std::string name) {
- if (passInfos.find(name) == passInfos.end())
+ if (passInfos.find(name) == passInfos.end()) {
return nullptr;
+ }
auto ret = passInfos[name].create();
ret->name = name;
return ret;
diff --git a/src/shell-interface.h b/src/shell-interface.h
index 1bbe97dd9..c07203a92 100644
--- a/src/shell-interface.h
+++ b/src/shell-interface.h
@@ -147,13 +147,16 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface {
LiteralList& arguments,
Type result,
ModuleInstance& instance) override {
- if (index >= table.size())
+ if (index >= table.size()) {
trap("callTable overflow");
+ }
auto* func = instance.wasm.getFunctionOrNull(table[index]);
- if (!func)
+ if (!func) {
trap("uninitialized table element");
- if (func->params.size() != arguments.size())
+ }
+ if (func->params.size() != arguments.size()) {
trap("callIndirect: bad # of arguments");
+ }
for (size_t i = 0; i < func->params.size(); i++) {
if (func->params[i] != arguments[i].type) {
trap("callIndirect: bad argument type");
diff --git a/src/support/archive.cpp b/src/support/archive.cpp
index 66f9c192a..1704fd88e 100644
--- a/src/support/archive.cpp
+++ b/src/support/archive.cpp
@@ -46,8 +46,9 @@ std::string ArchiveMemberHeader::getName() const {
}
auto* end =
static_cast<const uint8_t*>(memchr(fileName, endChar, sizeof(fileName)));
- if (!end)
+ if (!end) {
end = fileName + sizeof(fileName);
+ }
return std::string((char*)(fileName), end - fileName);
}
@@ -81,16 +82,18 @@ Archive::Archive(Buffer& b, bool& error)
return;
}
child_iterator end = child_end();
- if (it == end)
+ if (it == end) {
return; // Empty archive.
+ }
const Child* c = &*it;
auto increment = [&]() {
++it;
error = it.hasError();
- if (error)
+ if (error) {
return true;
+ }
c = &*it;
return false;
};
@@ -98,15 +101,17 @@ Archive::Archive(Buffer& b, bool& error)
std::string name = c->getRawName();
if (name == "/") {
symbolTable = c->getBuffer();
- if (increment() || it == end)
+ if (increment() || it == end) {
return;
+ }
name = c->getRawName();
}
if (name == "//") {
stringTable = c->getBuffer();
- if (increment() || it == end)
+ if (increment() || it == end) {
return;
+ }
setFirstRegular(*c);
return;
}
@@ -120,8 +125,9 @@ Archive::Archive(Buffer& b, bool& error)
Archive::Child::Child(const Archive* parent, const uint8_t* data, bool* error)
: parent(parent), data(data) {
- if (!data)
+ if (!data) {
return;
+ }
len = sizeof(ArchiveMemberHeader) + getHeader()->getSize();
startOfFile = sizeof(ArchiveMemberHeader);
}
@@ -180,8 +186,9 @@ std::string Archive::Child::getName() const {
}
Archive::child_iterator Archive::child_begin(bool SkipInternal) const {
- if (data.size() == 0)
+ if (data.size() == 0) {
return child_end();
+ }
if (SkipInternal) {
child_iterator it;
diff --git a/src/support/colors.cpp b/src/support/colors.cpp
index d0dc5ceb3..6d06b69fd 100644
--- a/src/support/colors.cpp
+++ b/src/support/colors.cpp
@@ -34,8 +34,9 @@ void Colors::outputColorCode(std::ostream& stream, const char* colorCode) {
(isatty(STDOUT_FILENO) &&
(!getenv("COLORS") || getenv("COLORS")[0] != '0')); // implicit
}();
- if (has_color && !colors_disabled)
+ if (has_color && !colors_disabled) {
stream << colorCode;
+ }
}
#elif defined(_WIN32)
#include <io.h>
diff --git a/src/support/command-line.cpp b/src/support/command-line.cpp
index f3b9ffe25..f1b4fca4d 100644
--- a/src/support/command-line.cpp
+++ b/src/support/command-line.cpp
@@ -37,8 +37,9 @@ void printWrap(std::ostream& os, int leftPad, const std::string& content) {
}
os << nextWord;
space -= nextWord.size() + 1;
- if (space > 0)
+ if (space > 0) {
os << ' ';
+ }
nextWord.clear();
if (content[i] == '\n') {
os << '\n';
@@ -56,8 +57,9 @@ Options::Options(const std::string& command, const std::string& description)
Arguments::Zero,
[this, command, description](Options* o, const std::string&) {
std::cout << command;
- if (positional != Arguments::Zero)
+ if (positional != Arguments::Zero) {
std::cout << ' ' << positionalName;
+ }
std::cout << "\n\n";
printWrap(std::cout, 0, description);
std::cout << "\n\nOptions:\n";
@@ -109,8 +111,9 @@ void Options::parse(int argc, const char* argv[]) {
size_t positionalsSeen = 0;
auto dashes = [](const std::string& s) {
for (size_t i = 0;; ++i) {
- if (s[i] != '-')
+ if (s[i] != '-') {
return i;
+ }
}
};
for (size_t i = 1, e = argc; i != e; ++i) {
@@ -147,9 +150,11 @@ void Options::parse(int argc, const char* argv[]) {
currentOption = currentOption.substr(0, equal);
}
Option* option = nullptr;
- for (auto& o : options)
- if (o.longName == currentOption || o.shortName == currentOption)
+ for (auto& o : options) {
+ if (o.longName == currentOption || o.shortName == currentOption) {
option = &o;
+ }
+ }
if (!option) {
std::cerr << "Unknown option '" << currentOption << "'\n";
exit(EXIT_FAILURE);
@@ -181,8 +186,9 @@ void Options::parse(int argc, const char* argv[]) {
break;
case Arguments::Optional:
if (!argument.size()) {
- if (i + 1 != e)
+ if (i + 1 != e) {
argument = argv[++i];
+ }
}
break;
}
diff --git a/src/support/file.cpp b/src/support/file.cpp
index 3af7af44b..b4c410b5e 100644
--- a/src/support/file.cpp
+++ b/src/support/file.cpp
@@ -22,8 +22,9 @@
#include <limits>
std::vector<char> wasm::read_stdin(Flags::DebugOption debug) {
- if (debug == Flags::Debug)
+ if (debug == Flags::Debug) {
std::cerr << "Loading stdin..." << std::endl;
+ }
std::vector<char> input;
char c;
while (std::cin.get(c) && !std::cin.eof()) {
@@ -36,12 +37,14 @@ template<typename T>
T wasm::read_file(const std::string& filename,
Flags::BinaryOption binary,
Flags::DebugOption debug) {
- if (debug == Flags::Debug)
+ if (debug == Flags::Debug) {
std::cerr << "Loading '" << filename << "'..." << std::endl;
+ }
std::ifstream infile;
std::ios_base::openmode flags = std::ifstream::in;
- if (binary == Flags::Binary)
+ if (binary == Flags::Binary) {
flags |= std::ifstream::binary;
+ }
infile.open(filename, flags);
if (!infile.is_open()) {
std::cerr << "Failed opening '" << filename << "'" << std::endl;
@@ -58,8 +61,9 @@ T wasm::read_file(const std::string& filename,
exit(EXIT_FAILURE);
}
T input(size_t(insize) + (binary == Flags::Binary ? 0 : 1), '\0');
- if (size_t(insize) == 0)
+ if (size_t(insize) == 0) {
return input;
+ }
infile.seekg(0);
infile.read(&input[0], insize);
if (binary == Flags::Text) {
@@ -88,11 +92,13 @@ wasm::Output::Output(const std::string& filename,
}
std::streambuf* buffer;
if (filename.size()) {
- if (debug == Flags::Debug)
+ if (debug == Flags::Debug) {
std::cerr << "Opening '" << filename << "'" << std::endl;
+ }
auto flags = std::ofstream::out | std::ofstream::trunc;
- if (binary == Flags::Binary)
+ if (binary == Flags::Binary) {
flags |= std::ofstream::binary;
+ }
outfile.open(filename, flags);
if (!outfile.is_open()) {
std::cerr << "Failed opening '" << filename << "'" << std::endl;
diff --git a/src/support/json.h b/src/support/json.h
index 8f2edc04d..d31fcf59b 100644
--- a/src/support/json.h
+++ b/src/support/json.h
@@ -224,8 +224,9 @@ struct Value {
}
bool operator==(const Value& other) {
- if (type != other.type)
+ if (type != other.type) {
return false;
+ }
switch (other.type) {
case String:
return str == other.str;
@@ -273,8 +274,9 @@ struct Value {
arr->push_back(temp);
curr = temp->parse(curr);
skip();
- if (*curr == ']')
+ if (*curr == ']') {
break;
+ }
assert(*curr == ',');
curr++;
skip();
@@ -316,8 +318,9 @@ struct Value {
curr = value->parse(curr);
(*obj)[key] = value;
skip();
- if (*curr == '}')
+ if (*curr == '}') {
break;
+ }
assert(*curr == ',');
curr++;
skip();
@@ -348,8 +351,9 @@ struct Value {
void setSize(size_t size) {
assert(isArray());
auto old = arr->size();
- if (old != size)
+ if (old != size) {
arr->resize(size);
+ }
if (old < size) {
for (auto i = old; i < size; i++) {
(*arr)[i] = Ref(new Value());
@@ -376,8 +380,9 @@ struct Value {
Ref back() {
assert(isArray());
- if (arr->size() == 0)
+ if (arr->size() == 0) {
return nullptr;
+ }
return arr->back();
}
diff --git a/src/support/path.cpp b/src/support/path.cpp
index 7ae68d719..e9817aca9 100644
--- a/src/support/path.cpp
+++ b/src/support/path.cpp
@@ -36,8 +36,9 @@ std::string getPathSeparator() {
std::string getBinaryenRoot() {
auto* envVar = getenv("BINARYEN_ROOT");
- if (envVar)
+ if (envVar) {
return envVar;
+ }
return ".";
}
diff --git a/src/support/small_vector.h b/src/support/small_vector.h
index dd6afb526..7f00bd4a6 100644
--- a/src/support/small_vector.h
+++ b/src/support/small_vector.h
@@ -109,11 +109,13 @@ public:
}
bool operator==(const SmallVector<T, N>& other) const {
- if (usedFixed != other.usedFixed)
+ if (usedFixed != other.usedFixed) {
return false;
+ }
for (size_t i = 0; i < usedFixed; i++) {
- if (fixed[i] != other.fixed[i])
+ if (fixed[i] != other.fixed[i]) {
return false;
+ }
}
return flexible == other.flexible;
}
diff --git a/src/support/sorted_vector.h b/src/support/sorted_vector.h
index e26d5e3af..872c2f8fb 100644
--- a/src/support/sorted_vector.h
+++ b/src/support/sorted_vector.h
@@ -61,9 +61,9 @@ struct SortedVector : public std::vector<Index> {
void insert(Index x) {
auto it = std::lower_bound(begin(), end(), x);
- if (it == end())
+ if (it == end()) {
push_back(x);
- else if (*it > x) {
+ } else if (*it > x) {
Index i = it - begin();
resize(size() + 1);
std::move_backward(begin() + i, begin() + size() - 1, end());
@@ -107,8 +107,9 @@ struct SortedVector : public std::vector<Index> {
void dump(const char* str = nullptr) const {
std::cout << "SortedVector " << (str ? str : "") << ": ";
- for (auto x : *this)
+ for (auto x : *this) {
std::cout << x << " ";
+ }
std::cout << '\n';
}
};
diff --git a/src/support/threads.cpp b/src/support/threads.cpp
index 785994b4e..ab9de4175 100644
--- a/src/support/threads.cpp
+++ b/src/support/threads.cpp
@@ -114,8 +114,9 @@ std::mutex ThreadPool::workMutex;
std::mutex ThreadPool::threadMutex;
void ThreadPool::initialize(size_t num) {
- if (num == 1)
+ if (num == 1) {
return; // no multiple cores, don't create threads
+ }
DEBUG_POOL("initialize()\n");
std::unique_lock<std::mutex> lock(threadMutex);
// initial state before first resetThreadsAreReady()
diff --git a/src/tools/asm2wasm.cpp b/src/tools/asm2wasm.cpp
index 843106ffd..b1196850b 100644
--- a/src/tools/asm2wasm.cpp
+++ b/src/tools/asm2wasm.cpp
@@ -212,13 +212,15 @@ int main(int argc, const char* argv[]) {
: Flags::Release));
char* start = pre.process(input.data());
- if (options.debug)
+ if (options.debug) {
std::cerr << "parsing..." << std::endl;
+ }
cashew::Parser<Ref, DotZeroValueBuilder> builder;
Ref asmjs = builder.parseToplevel(start);
- if (options.debug)
+ if (options.debug) {
std::cerr << "wasming..." << std::endl;
+ }
Module wasm;
// set up memory
@@ -294,8 +296,9 @@ int main(int argc, const char* argv[]) {
}
}
- if (options.debug)
+ if (options.debug) {
std::cerr << "emitting..." << std::endl;
+ }
ModuleWriter writer;
writer.setDebug(options.debug);
writer.setDebugInfo(options.passOptions.debugInfo);
@@ -307,6 +310,7 @@ int main(int argc, const char* argv[]) {
}
writer.write(wasm, options.extra["output"]);
- if (options.debug)
+ if (options.debug) {
std::cerr << "done." << std::endl;
+ }
}
diff --git a/src/tools/execution-results.h b/src/tools/execution-results.h
index 2a42b941b..13771a69d 100644
--- a/src/tools/execution-results.h
+++ b/src/tools/execution-results.h
@@ -62,8 +62,9 @@ struct ExecutionResults {
// execute all exported methods (that are therefore preserved through
// opts)
for (auto& exp : wasm.exports) {
- if (exp->kind != ExternalKind::Function)
+ if (exp->kind != ExternalKind::Function) {
continue;
+ }
std::cout << "[fuzz-exec] calling " << exp->name << "\n";
auto* func = wasm.getFunction(exp->value);
if (func->result != none) {
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index f5b548ec6..16b04fe02 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -463,8 +463,9 @@ private:
}
Expression* makeDeNanOp(Expression* expr) {
- if (allowNaNs)
+ if (allowNaNs) {
return expr;
+ }
if (expr->type == f32) {
return builder.makeCall("deNan32", {expr}, f32);
} else if (expr->type == f64) {
@@ -566,8 +567,9 @@ private:
void recombine(Function* func) {
// Don't always do this.
- if (oneIn(2))
+ if (oneIn(2)) {
return;
+ }
// First, scan and group all expressions by type.
struct Scanner
: public PostWalker<Scanner, UnifiedExpressionVisitor<Scanner>> {
@@ -583,8 +585,9 @@ private:
// Potentially trim the list of possible picks, so replacements are more
// likely to collide.
for (auto& pair : scanner.exprsByType) {
- if (oneIn(2))
+ if (oneIn(2)) {
continue;
+ }
auto& list = pair.second;
std::vector<Expression*> trimmed;
size_t num = upToSquared(list.size());
@@ -630,8 +633,9 @@ private:
void mutate(Function* func) {
// Don't always do this.
- if (oneIn(2))
+ if (oneIn(2)) {
return;
+ }
struct Modder
: public PostWalker<Modder, UnifiedExpressionVisitor<Modder>> {
Module& wasm;
@@ -688,8 +692,9 @@ private:
void visitSwitch(Switch* curr) {
for (auto name : curr->targets) {
- if (replaceIfInvalid(name))
+ if (replaceIfInvalid(name)) {
return;
+ }
}
replaceIfInvalid(curr->default_);
}
@@ -708,23 +713,27 @@ private:
void replace() { replaceCurrent(parent.makeTrivial(getCurrent()->type)); }
bool hasBreakTarget(Name name) {
- if (controlFlowStack.empty())
+ if (controlFlowStack.empty()) {
return false;
+ }
Index i = controlFlowStack.size() - 1;
while (1) {
auto* curr = controlFlowStack[i];
if (Block* block = curr->template dynCast<Block>()) {
- if (name == block->name)
+ if (name == block->name) {
return true;
+ }
} else if (Loop* loop = curr->template dynCast<Loop>()) {
- if (name == loop->name)
+ if (name == loop->name) {
return true;
+ }
} else {
// an if, ignorable
assert(curr->template is<If>());
}
- if (i == 0)
+ if (i == 0) {
return false;
+ }
i--;
}
}
@@ -754,8 +763,9 @@ private:
invocations.push_back(makeMemoryHashLogging());
}
}
- if (invocations.empty())
+ if (invocations.empty()) {
return;
+ }
auto* invoker = new Function;
invoker->name = func->name.str + std::string("_invoker");
invoker->result = none;
@@ -821,20 +831,27 @@ private:
Expression* _makeConcrete(Type type) {
auto choice = upTo(100);
- if (choice < 10)
+ if (choice < 10) {
return makeConst(type);
- if (choice < 30)
+ }
+ if (choice < 30) {
return makeSetLocal(type);
- if (choice < 50)
+ }
+ if (choice < 50) {
return makeGetLocal(type);
- if (choice < 60)
+ }
+ if (choice < 60) {
return makeBlock(type);
- if (choice < 70)
+ }
+ if (choice < 70) {
return makeIf(type);
- if (choice < 80)
+ }
+ if (choice < 80) {
return makeLoop(type);
- if (choice < 90)
+ }
+ if (choice < 90) {
return makeBreak(type);
+ }
using Self = TranslateToFuzzReader;
auto options = FeatureOptions<Expression* (Self::*)(Type)>()
.add(FeatureSet::MVP,
@@ -869,16 +886,21 @@ private:
}
}
choice = upTo(100);
- if (choice < 50)
+ if (choice < 50) {
return makeSetLocal(none);
- if (choice < 60)
+ }
+ if (choice < 60) {
return makeBlock(none);
- if (choice < 70)
+ }
+ if (choice < 70) {
return makeIf(none);
- if (choice < 80)
+ }
+ if (choice < 80) {
return makeLoop(none);
- if (choice < 90)
+ }
+ if (choice < 90) {
return makeBreak(none);
+ }
using Self = TranslateToFuzzReader;
auto options = FeatureOptions<Expression* (Self::*)(Type)>()
.add(FeatureSet::MVP,
@@ -1056,8 +1078,9 @@ private:
}
Expression* makeBreak(Type type) {
- if (breakableStack.empty())
+ if (breakableStack.empty()) {
return makeTrivial(type);
+ }
Expression* condition = nullptr;
if (type != unreachable) {
hangStack.push_back(nullptr);
@@ -1110,18 +1133,21 @@ private:
}
switch (conditions) {
case 0: {
- if (!oneIn(4))
+ if (!oneIn(4)) {
continue;
+ }
break;
}
case 1: {
- if (!oneIn(2))
+ if (!oneIn(2)) {
continue;
+ }
break;
}
default: {
- if (oneIn(conditions + 1))
+ if (oneIn(conditions + 1)) {
continue;
+ }
}
}
return builder.makeBreak(name);
@@ -1142,8 +1168,9 @@ private:
if (!wasm.functions.empty() && !oneIn(wasm.functions.size())) {
target = vectorPick(wasm.functions).get();
}
- if (target->result != type)
+ if (target->result != type) {
continue;
+ }
// we found one!
std::vector<Expression*> args;
for (auto argType : target->params) {
@@ -1157,8 +1184,9 @@ private:
Expression* makeCallIndirect(Type type) {
auto& data = wasm.table.segments[0].data;
- if (data.empty())
+ if (data.empty()) {
return make(type);
+ }
// look for a call target with the right type
Index start = upTo(data.size());
Index i = start;
@@ -1170,10 +1198,12 @@ private:
break;
}
i++;
- if (i == data.size())
+ if (i == data.size()) {
i = 0;
- if (i == start)
+ }
+ if (i == start) {
return make(type);
+ }
}
// with high probability, make sure the type is valid otherwise, most are
// going to trap
@@ -1193,8 +1223,9 @@ private:
Expression* makeGetLocal(Type type) {
auto& locals = typeLocals[type];
- if (locals.empty())
+ if (locals.empty()) {
return makeConst(type);
+ }
return builder.makeGetLocal(vectorPick(locals), type);
}
@@ -1207,8 +1238,9 @@ private:
valueType = getConcreteType();
}
auto& locals = typeLocals[valueType];
- if (locals.empty())
+ if (locals.empty()) {
return makeTrivial(type);
+ }
auto* value = make(valueType);
if (tee) {
return builder.makeTeeLocal(vectorPick(locals), value);
@@ -1219,8 +1251,9 @@ private:
Expression* makeGetGlobal(Type type) {
auto& globals = globalsByType[type];
- if (globals.empty())
+ if (globals.empty()) {
return makeConst(type);
+ }
return builder.makeGetGlobal(vectorPick(globals), type);
}
@@ -1228,8 +1261,9 @@ private:
assert(type == none);
type = getConcreteType();
auto& globals = globalsByType[type];
- if (globals.empty())
+ if (globals.empty()) {
return makeTrivial(none);
+ }
auto* value = make(type);
return builder.makeSetGlobal(vectorPick(globals), value);
}
@@ -1300,13 +1334,16 @@ private:
}
Expression* makeLoad(Type type) {
- if (!allowMemory)
+ if (!allowMemory) {
return makeTrivial(type);
+ }
auto* ret = makeNonAtomicLoad(type);
- if (type != i32 && type != i64)
+ if (type != i32 && type != i64) {
return ret;
- if (!wasm.features.hasAtomics() || oneIn(2))
+ }
+ if (!wasm.features.hasAtomics() || oneIn(2)) {
return ret;
+ }
// make it atomic
auto* load = ret->cast<Load>();
wasm.memory.shared = true;
@@ -1321,8 +1358,9 @@ private:
// make a normal store, then make it unreachable
auto* ret = makeNonAtomicStore(getConcreteType());
auto* store = ret->dynCast<Store>();
- if (!store)
+ if (!store) {
return ret;
+ }
switch (upTo(3)) {
case 0:
store->ptr = make(unreachable);
@@ -1395,16 +1433,20 @@ private:
}
Expression* makeStore(Type type) {
- if (!allowMemory)
+ if (!allowMemory) {
return makeTrivial(type);
+ }
auto* ret = makeNonAtomicStore(type);
auto* store = ret->dynCast<Store>();
- if (!store)
+ if (!store) {
return ret;
- if (store->value->type != i32 && store->value->type != i64)
+ }
+ if (store->value->type != i32 && store->value->type != i64) {
return store;
- if (!wasm.features.hasAtomics() || oneIn(2))
+ }
+ if (!wasm.features.hasAtomics() || oneIn(2)) {
return store;
+ }
// make it atomic
wasm.memory.shared = true;
store->isAtomic = true;
@@ -2051,8 +2093,9 @@ private:
Expression* makeSwitch(Type type) {
assert(type == unreachable);
- if (breakableStack.empty())
+ if (breakableStack.empty()) {
return make(type);
+ }
// we need to find proper targets to break to; try a bunch
int tries = TRIES;
std::vector<Name> names;
@@ -2103,8 +2146,9 @@ private:
Expression* makeAtomic(Type type) {
assert(wasm.features.hasAtomics());
- if (!allowMemory)
+ if (!allowMemory) {
return makeTrivial(type);
+ }
wasm.memory.shared = true;
if (type == i32 && oneIn(2)) {
if (ATOMIC_WAITS && oneIn(2)) {
@@ -2330,8 +2374,9 @@ private:
}
Expression* makeBulkMemory(Type type) {
- if (!allowMemory)
+ if (!allowMemory) {
return makeTrivial(type);
+ }
assert(wasm.features.hasBulkMemory());
assert(type == none);
switch (upTo(4)) {
@@ -2348,8 +2393,9 @@ private:
}
Expression* makeMemoryInit() {
- if (!allowMemory)
+ if (!allowMemory) {
return makeTrivial(none);
+ }
uint32_t segment = upTo(wasm.memory.segments.size());
size_t totalSize = wasm.memory.segments[segment].data.size();
size_t offsetVal = upTo(totalSize);
@@ -2361,14 +2407,16 @@ private:
}
Expression* makeDataDrop() {
- if (!allowMemory)
+ if (!allowMemory) {
return makeTrivial(none);
+ }
return builder.makeDataDrop(upTo(wasm.memory.segments.size()));
}
Expression* makeMemoryCopy() {
- if (!allowMemory)
+ if (!allowMemory) {
return makeTrivial(none);
+ }
Expression* dest = makePointer();
Expression* source = makePointer();
Expression* size = make(i32);
@@ -2376,8 +2424,9 @@ private:
}
Expression* makeMemoryFill() {
- if (!allowMemory)
+ if (!allowMemory) {
return makeTrivial(none);
+ }
Expression* dest = makePointer();
Expression* value = makePointer();
Expression* size = make(i32);
@@ -2428,8 +2477,9 @@ private:
// this isn't a perfectly uniform distribution, but it's fast
// and reasonable
Index upTo(Index x) {
- if (x == 0)
+ if (x == 0) {
return 0;
+ }
Index raw;
if (x <= 255) {
raw = get();
@@ -2486,8 +2536,9 @@ private:
template<typename T, typename... Args>
T pickGivenNum(size_t num, T first, Args... args) {
- if (num == 0)
+ if (num == 0) {
return first;
+ }
return pickGivenNum<T>(num - 1, args...);
}
diff --git a/src/tools/js-wrapper.h b/src/tools/js-wrapper.h
index e39a015d6..32b46affa 100644
--- a/src/tools/js-wrapper.h
+++ b/src/tools/js-wrapper.h
@@ -83,8 +83,9 @@ static std::string generateJSWrapper(Module& wasm) {
"});\n";
for (auto& exp : wasm.exports) {
auto* func = wasm.getFunctionOrNull(exp->value);
- if (!func)
+ if (!func) {
continue; // something exported other than a function
+ }
ret += "if (instance.exports.hangLimitInitializer) "
"instance.exports.hangLimitInitializer();\n";
ret += "try {\n";
diff --git a/src/tools/optimization-options.h b/src/tools/optimization-options.h
index 6fa9aac36..30f59f04d 100644
--- a/src/tools/optimization-options.h
+++ b/src/tools/optimization-options.h
@@ -177,8 +177,9 @@ struct OptimizationOptions : public ToolOptions {
void runPasses(Module& wasm) {
PassRunner passRunner(&wasm, passOptions);
- if (debug)
+ if (debug) {
passRunner.setDebug(true);
+ }
for (auto& pass : passes) {
if (pass == DEFAULT_OPT_PASSES) {
passRunner.addDefaultOptimizationPasses();
diff --git a/src/tools/spec-wrapper.h b/src/tools/spec-wrapper.h
index 516ce17a9..d481f0fa8 100644
--- a/src/tools/spec-wrapper.h
+++ b/src/tools/spec-wrapper.h
@@ -25,8 +25,9 @@ static std::string generateSpecWrapper(Module& wasm) {
std::string ret;
for (auto& exp : wasm.exports) {
auto* func = wasm.getFunctionOrNull(exp->value);
- if (!func)
+ if (!func) {
continue; // something exported other than a function
+ }
ret += std::string("(invoke \"hangLimitInitializer\") (invoke \"") +
exp->name.str + "\" ";
for (Type param : func->params) {
diff --git a/src/tools/wasm-as.cpp b/src/tools/wasm-as.cpp
index 253a93b3b..d45f10f81 100644
--- a/src/tools/wasm-as.cpp
+++ b/src/tools/wasm-as.cpp
@@ -105,12 +105,14 @@ int main(int argc, const char* argv[]) {
Module wasm;
try {
- if (options.debug)
+ if (options.debug) {
std::cerr << "s-parsing..." << std::endl;
+ }
SExpressionParser parser(const_cast<char*>(input.c_str()));
Element& root = *parser.root;
- if (options.debug)
+ if (options.debug) {
std::cerr << "w-parsing..." << std::endl;
+ }
SExpressionWasmBuilder builder(wasm, *root[0]);
} catch (ParseException& p) {
p.dump(std::cerr);
@@ -120,8 +122,9 @@ int main(int argc, const char* argv[]) {
options.applyFeatures(wasm);
if (options.extra["validate"] != "none") {
- if (options.debug)
+ if (options.debug) {
std::cerr << "Validating..." << std::endl;
+ }
if (!wasm::WasmValidator().validate(
wasm,
WasmValidator::Globally |
@@ -131,8 +134,9 @@ int main(int argc, const char* argv[]) {
}
}
- if (options.debug)
+ if (options.debug) {
std::cerr << "writing..." << std::endl;
+ }
ModuleWriter writer;
writer.setBinary(true);
writer.setDebugInfo(debugInfo);
@@ -145,6 +149,7 @@ int main(int argc, const char* argv[]) {
}
writer.write(wasm, options.extra["output"]);
- if (options.debug)
+ if (options.debug) {
std::cerr << "Done." << std::endl;
+ }
}
diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp
index 2050b3ebc..6a967ece7 100644
--- a/src/tools/wasm-ctor-eval.cpp
+++ b/src/tools/wasm-ctor-eval.cpp
@@ -441,8 +441,9 @@ int main(int argc, const char* argv[]) {
Module wasm;
{
- if (options.debug)
+ if (options.debug) {
std::cerr << "reading...\n";
+ }
ModuleReader reader;
reader.setDebug(options.debug);
@@ -483,8 +484,9 @@ int main(int argc, const char* argv[]) {
}
if (options.extra.count("output") > 0) {
- if (options.debug)
+ if (options.debug) {
std::cerr << "writing..." << std::endl;
+ }
ModuleWriter writer;
writer.setDebug(options.debug);
writer.setBinary(emitBinary);
diff --git a/src/tools/wasm-dis.cpp b/src/tools/wasm-dis.cpp
index 5b9cb9804..1dbe97656 100644
--- a/src/tools/wasm-dis.cpp
+++ b/src/tools/wasm-dis.cpp
@@ -56,8 +56,9 @@ int main(int argc, const char* argv[]) {
});
options.parse(argc, argv);
- if (options.debug)
+ if (options.debug) {
std::cerr << "parsing binary..." << std::endl;
+ }
Module wasm;
try {
ModuleReader().readBinary(options.extra["infile"], wasm, sourceMapFilename);
@@ -71,14 +72,16 @@ int main(int argc, const char* argv[]) {
Fatal() << "error in parsing wasm source mapping";
}
- if (options.debug)
+ if (options.debug) {
std::cerr << "Printing..." << std::endl;
+ }
Output output(options.extra["output"],
Flags::Text,
options.debug ? Flags::Debug : Flags::Release);
WasmPrinter::printModule(&wasm, output.getStream());
output << '\n';
- if (options.debug)
+ if (options.debug) {
std::cerr << "Done." << std::endl;
+ }
}
diff --git a/src/tools/wasm-emscripten-finalize.cpp b/src/tools/wasm-emscripten-finalize.cpp
index a23ba1c5a..e524e4732 100644
--- a/src/tools/wasm-emscripten-finalize.cpp
+++ b/src/tools/wasm-emscripten-finalize.cpp
@@ -193,12 +193,14 @@ int main(int argc, const char* argv[]) {
std::vector<Name> initializerFunctions;
if (wasm.table.imported()) {
- if (wasm.table.base != "table")
+ if (wasm.table.base != "table") {
wasm.table.base = Name("table");
+ }
}
if (wasm.memory.imported()) {
- if (wasm.table.base != "memory")
+ if (wasm.table.base != "memory") {
wasm.memory.base = Name("memory");
+ }
}
wasm.updateMaps();
diff --git a/src/tools/wasm-metadce.cpp b/src/tools/wasm-metadce.cpp
index a6f5bb012..c87da8c9a 100644
--- a/src/tools/wasm-metadce.cpp
+++ b/src/tools/wasm-metadce.cpp
@@ -230,8 +230,9 @@ struct MetaDCEGraph {
MetaDCEGraph* parent;
void handleGlobal(Name name) {
- if (!getFunction())
+ if (!getFunction()) {
return; // non-function stuff (initializers) are handled separately
+ }
Name dceName;
if (!getModule()->getGlobal(name)->imported()) {
// its a global
@@ -465,8 +466,9 @@ int main(int argc, const char* argv[]) {
Module wasm;
{
- if (options.debug)
+ if (options.debug) {
std::cerr << "reading...\n";
+ }
ModuleReader reader;
reader.setDebug(options.debug);
diff --git a/src/tools/wasm-opt.cpp b/src/tools/wasm-opt.cpp
index e9f369d22..f7e8b5918 100644
--- a/src/tools/wasm-opt.cpp
+++ b/src/tools/wasm-opt.cpp
@@ -203,8 +203,9 @@ int main(int argc, const char* argv[]) {
Module wasm;
- if (options.debug)
+ if (options.debug) {
std::cerr << "reading...\n";
+ }
if (!translateToFuzz) {
ModuleReader reader;
@@ -280,9 +281,10 @@ int main(int argc, const char* argv[]) {
std::string firstOutput;
if (extraFuzzCommand.size() > 0 && options.extra.count("output") > 0) {
- if (options.debug)
+ if (options.debug) {
std::cerr << "writing binary before opts, for extra fuzz command..."
<< std::endl;
+ }
ModuleWriter writer;
writer.setDebug(options.debug);
writer.setBinary(emitBinary);
@@ -316,8 +318,9 @@ int main(int argc, const char* argv[]) {
}
if (options.runningPasses()) {
- if (options.debug)
+ if (options.debug) {
std::cerr << "running passes...\n";
+ }
auto runPasses = [&]() {
options.runPasses(*curr);
if (options.passOptions.validate) {
@@ -340,13 +343,15 @@ int main(int argc, const char* argv[]) {
};
auto lastSize = getSize();
while (1) {
- if (options.debug)
+ if (options.debug) {
std::cerr << "running iteration for convergence (" << lastSize
<< ")...\n";
+ }
runPasses();
auto currSize = getSize();
- if (currSize >= lastSize)
+ if (currSize >= lastSize) {
break;
+ }
lastSize = currSize;
}
}
@@ -359,8 +364,9 @@ int main(int argc, const char* argv[]) {
if (options.extra.count("output") == 0) {
std::cerr << "(no output file specified, not emitting output)\n";
} else {
- if (options.debug)
+ if (options.debug) {
std::cerr << "writing..." << std::endl;
+ }
ModuleWriter writer;
writer.setDebug(options.debug);
writer.setBinary(emitBinary);
diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp
index 87f64c1ae..54a915ec0 100644
--- a/src/tools/wasm-reduce.cpp
+++ b/src/tools/wasm-reduce.cpp
@@ -285,10 +285,12 @@ struct Reducer
// TODO(tlively): -all should be replaced with an option to use the
// existing feature set, once implemented.
currCommand += working + " -all -o " + test + " " + pass;
- if (debugInfo)
+ if (debugInfo) {
currCommand += " -g ";
- if (verbose)
+ }
+ if (verbose) {
std::cerr << "| trying pass command: " << currCommand << "\n";
+ }
if (!ProgramResult(currCommand).failed()) {
auto newSize = file_size(test);
if (newSize < oldSize) {
@@ -306,8 +308,9 @@ struct Reducer
}
}
}
- if (verbose)
+ if (verbose) {
std::cerr << "| done with passes for now\n";
+ }
}
// does one pass of slow and destructive reduction. returns whether it
@@ -400,10 +403,12 @@ struct Reducer
}
auto* curr = getCurrent();
// std::cerr << "try " << curr << " => " << with << '\n';
- if (curr->type != with->type)
+ if (curr->type != with->type) {
return false;
- if (!shouldTryToReduce())
+ }
+ if (!shouldTryToReduce()) {
return false;
+ }
replaceCurrent(with);
if (!writeAndTestReduction()) {
replaceCurrent(curr);
@@ -425,10 +430,12 @@ struct Reducer
if (!isOkReplacement(with)) {
return false;
}
- if (child->type != with->type)
+ if (child->type != with->type) {
return false;
- if (!shouldTryToReduce())
+ }
+ if (!shouldTryToReduce()) {
return false;
+ }
auto* before = child;
child = with;
if (!writeAndTestReduction()) {
@@ -443,8 +450,9 @@ struct Reducer
}
std::string getLocation() {
- if (getFunction())
+ if (getFunction()) {
return getFunction()->name.str;
+ }
return "(non-function context)";
}
@@ -455,15 +463,18 @@ struct Reducer
void visitExpression(Expression* curr) {
// type-based reductions
if (curr->type == none) {
- if (tryToReduceCurrentToNop())
+ if (tryToReduceCurrentToNop()) {
return;
+ }
} else if (isConcreteType(curr->type)) {
- if (tryToReduceCurrentToConst())
+ if (tryToReduceCurrentToConst()) {
return;
+ }
} else {
assert(curr->type == unreachable);
- if (tryToReduceCurrentToUnreachable())
+ if (tryToReduceCurrentToUnreachable()) {
return;
+ }
}
// specific reductions
if (auto* iff = curr->dynCast<If>()) {
@@ -500,14 +511,16 @@ struct Reducer
}
}
} else if (auto* block = curr->dynCast<Block>()) {
- if (!shouldTryToReduce())
+ if (!shouldTryToReduce()) {
return;
+ }
// replace a singleton
auto& list = block->list;
if (list.size() == 1 &&
!BranchUtils::BranchSeeker::hasNamed(block, block->name)) {
- if (tryToReplaceCurrent(block->list[0]))
+ if (tryToReplaceCurrent(block->list[0])) {
return;
+ }
}
// try to get rid of nops
Index i = 0;
@@ -544,21 +557,25 @@ struct Reducer
// Finally, try to replace with a child.
for (auto* child : ChildIterator(curr)) {
if (isConcreteType(child->type) && curr->type == none) {
- if (tryToReplaceCurrent(builder->makeDrop(child)))
+ if (tryToReplaceCurrent(builder->makeDrop(child))) {
return;
+ }
} else {
- if (tryToReplaceCurrent(child))
+ if (tryToReplaceCurrent(child)) {
return;
+ }
}
}
// If that didn't work, try to replace with a child + a unary conversion
if (isConcreteType(curr->type) &&
!curr->is<Unary>()) { // but not if it's already unary
for (auto* child : ChildIterator(curr)) {
- if (child->type == curr->type)
+ if (child->type == curr->type) {
continue; // already tried
- if (!isConcreteType(child->type))
+ }
+ if (!isConcreteType(child->type)) {
continue; // no conversion
+ }
Expression* fixed = nullptr;
switch (curr->type) {
case i32: {
@@ -652,8 +669,9 @@ struct Reducer
WASM_UNREACHABLE();
}
assert(fixed->type == curr->type);
- if (tryToReplaceCurrent(fixed))
+ if (tryToReplaceCurrent(fixed)) {
return;
+ }
}
}
}
@@ -684,8 +702,9 @@ struct Reducer
first = item;
break;
}
- if (!first.isNull())
+ if (!first.isNull()) {
break;
+ }
}
visitSegmented(curr, first, 100);
}
@@ -706,12 +725,14 @@ struct Reducer
// when we succeed, try to shrink by more and more, similar to bisection
size_t skip = 1;
for (size_t i = 0; i < data.size() && !data.empty(); i++) {
- if (!justShrank && !shouldTryToReduce(bonus))
+ if (!justShrank && !shouldTryToReduce(bonus)) {
continue;
+ }
auto save = data;
for (size_t j = 0; j < skip; j++) {
- if (!data.empty())
+ if (!data.empty()) {
data.pop_back();
+ }
}
auto justShrank = writeAndTestReduction();
if (justShrank) {
@@ -727,13 +748,16 @@ struct Reducer
}
// the "opposite" of shrinking: copy a 'zero' element
for (auto& segment : curr->segments) {
- if (segment.data.empty())
+ if (segment.data.empty()) {
continue;
+ }
for (auto& item : segment.data) {
- if (!shouldTryToReduce(bonus))
+ if (!shouldTryToReduce(bonus)) {
continue;
- if (item == zero)
+ }
+ if (item == zero) {
continue;
+ }
auto save = item;
item = zero;
if (writeAndTestReduction()) {
@@ -766,8 +790,9 @@ struct Reducer
for (size_t i = 0; i < functionNames.size(); i++) {
if (!justRemoved &&
functionsWeTriedToRemove.count(functionNames[i]) == 1 &&
- !shouldTryToReduce(std::max((factor / 100) + 1, 1000)))
+ !shouldTryToReduce(std::max((factor / 100) + 1, 1000))) {
continue;
+ }
std::vector<Name> names;
for (size_t j = 0; names.size() < skip && i + j < functionNames.size();
j++) {
@@ -777,8 +802,9 @@ struct Reducer
functionsWeTriedToRemove.insert(name);
}
}
- if (names.size() == 0)
+ if (names.size() == 0) {
continue;
+ }
std::cout << "| try to remove " << names.size()
<< " functions (skip: " << skip << ")\n";
justRemoved = tryToRemoveFunctions(names);
@@ -798,8 +824,9 @@ struct Reducer
}
skip = 1;
for (size_t i = 0; i < exports.size(); i++) {
- if (!shouldTryToReduce(std::max((factor / 100) + 1, 1000)))
+ if (!shouldTryToReduce(std::max((factor / 100) + 1, 1000))) {
continue;
+ }
std::vector<Export> currExports;
for (size_t j = 0; currExports.size() < skip && i + j < exports.size();
j++) {
@@ -891,11 +918,13 @@ struct Reducer
break;
}
}
- if (!other.isNull())
+ if (!other.isNull()) {
break;
+ }
}
- if (other.isNull())
+ if (other.isNull()) {
return; // we failed to find a replacement
+ }
for (auto& segment : curr->segments) {
for (auto& name : segment.data) {
if (names.count(name)) {
@@ -929,10 +958,12 @@ struct Reducer
// try to replace condition with always true and always false
void handleCondition(Expression*& condition) {
- if (!condition)
+ if (!condition) {
return;
- if (condition->is<Const>())
+ }
+ if (condition->is<Const>()) {
return;
+ }
auto* c = builder->makeConst(Literal(int32_t(0)));
if (!tryToReplaceChild(condition, c)) {
c->value = Literal(int32_t(1));
@@ -942,8 +973,9 @@ struct Reducer
bool tryToReduceCurrentToNop() {
auto* curr = getCurrent();
- if (curr->is<Nop>())
+ if (curr->is<Nop>()) {
return false;
+ }
// try to replace with a trivial value
Nop nop;
if (tryToReplaceCurrent(&nop)) {
@@ -956,12 +988,14 @@ struct Reducer
// try to replace a concrete value with a trivial constant
bool tryToReduceCurrentToConst() {
auto* curr = getCurrent();
- if (curr->is<Const>())
+ if (curr->is<Const>()) {
return false;
+ }
// try to replace with a trivial value
Const* c = builder->makeConst(Literal(int32_t(0)));
- if (tryToReplaceCurrent(c))
+ if (tryToReplaceCurrent(c)) {
return true;
+ }
c->value = Literal::makeFromInt32(1, curr->type);
c->type = curr->type;
return tryToReplaceCurrent(c);
@@ -969,8 +1003,9 @@ struct Reducer
bool tryToReduceCurrentToUnreachable() {
auto* curr = getCurrent();
- if (curr->is<Unreachable>())
+ if (curr->is<Unreachable>()) {
return false;
+ }
// try to replace with a trivial value
Unreachable un;
if (tryToReplaceCurrent(&un)) {
@@ -1065,10 +1100,12 @@ int main(int argc, const char* argv[]) {
[&](Options* o, const std::string& argument) { input = argument; });
options.parse(argc, argv);
- if (test.size() == 0)
+ if (test.size() == 0) {
Fatal() << "test file not provided\n";
- if (working.size() == 0)
+ }
+ if (working.size() == 0) {
Fatal() << "working file not provided\n";
+ }
if (!binary) {
Colors::disable();
@@ -1124,8 +1161,9 @@ int main(int argc, const char* argv[]) {
// feature set, once implemented.
auto cmd = Path::getBinaryenBinaryTool("wasm-opt") + " " + input +
" -all -o " + test;
- if (!binary)
+ if (!binary) {
cmd += " -S";
+ }
ProgramResult readWrite(cmd);
if (readWrite.failed()) {
stopIfNotForced("failed to read and write the binary", readWrite);
@@ -1166,8 +1204,9 @@ int main(int argc, const char* argv[]) {
std::cerr << "| after pass reduction: " << newSize << "\n";
// always stop after a pass reduction attempt, for final cleanup
- if (stopping)
+ if (stopping) {
break;
+ }
// check if the full cycle (destructive/passes) has helped or not
if (lastPostPassesSize && newSize >= lastPostPassesSize) {
@@ -1208,8 +1247,9 @@ int main(int argc, const char* argv[]) {
while (1) {
std::cerr << "| reduce destructively... (factor: " << factor << ")\n";
lastDestructiveReductions = reducer.reduceDestructively(factor);
- if (lastDestructiveReductions > 0)
+ if (lastDestructiveReductions > 0) {
break;
+ }
// we failed to reduce destructively
if (factor == 1) {
stopping = true;
diff --git a/src/tools/wasm-shell.cpp b/src/tools/wasm-shell.cpp
index 6141b1a37..652b3a352 100644
--- a/src/tools/wasm-shell.cpp
+++ b/src/tools/wasm-shell.cpp
@@ -125,8 +125,9 @@ static void run_asserts(Name moduleName,
while (*i < root->size()) {
Element& curr = *(*root)[*i];
IString id = curr[0]->str();
- if (id == MODULE)
+ if (id == MODULE) {
break;
+ }
*checked = true;
Colors::red(std::cerr);
std::cerr << *i << '/' << (root->size() - 1);
@@ -228,8 +229,9 @@ static void run_asserts(Name moduleName,
}
}
}
- if (id == ASSERT_TRAP)
+ if (id == ASSERT_TRAP) {
assert(trapped);
+ }
}
*i += 1;
}
@@ -281,8 +283,9 @@ int main(int argc, const char* argv[]) {
bool checked = false;
try {
- if (options.debug)
+ if (options.debug) {
std::cerr << "parsing text to s-expressions...\n";
+ }
SExpressionParser parser(input.data());
Element& root = *parser.root;
@@ -299,8 +302,9 @@ int main(int argc, const char* argv[]) {
}
IString id = curr[0]->str();
if (id == MODULE) {
- if (options.debug)
+ if (options.debug) {
std::cerr << "parsing s-expressions to wasm...\n";
+ }
Colors::green(std::cerr);
std::cerr << "BUILDING MODULE [line: " << curr.line << "]\n";
Colors::normal(std::cerr);
diff --git a/src/tools/wasm2js.cpp b/src/tools/wasm2js.cpp
index 6e4656878..823ab7f96 100644
--- a/src/tools/wasm2js.cpp
+++ b/src/tools/wasm2js.cpp
@@ -694,8 +694,9 @@ int main(int argc, const char* argv[]) {
o->extra["infile"] = argument;
});
options.parse(argc, argv);
- if (options.debug)
+ if (options.debug) {
flags.debug = true;
+ }
Element* root = nullptr;
Module wasm;
@@ -728,13 +729,15 @@ int main(int argc, const char* argv[]) {
Flags::Text,
options.debug ? Flags::Debug
: Flags::Release));
- if (options.debug)
+ if (options.debug) {
std::cerr << "s-parsing..." << std::endl;
+ }
sexprParser = make_unique<SExpressionParser>(input.data());
root = sexprParser->root;
- if (options.debug)
+ if (options.debug) {
std::cerr << "w-parsing..." << std::endl;
+ }
sexprBuilder = make_unique<SExpressionWasmBuilder>(wasm, *(*root)[0]);
}
} catch (ParseException& p) {
@@ -752,8 +755,9 @@ int main(int argc, const char* argv[]) {
}
}
- if (options.debug)
+ if (options.debug) {
std::cerr << "j-printing..." << std::endl;
+ }
Output output(options.extra["output"],
Flags::Text,
options.debug ? Flags::Debug : Flags::Release);
@@ -764,6 +768,7 @@ int main(int argc, const char* argv[]) {
emitWasm(wasm, output, flags, options.passOptions, "asmFunc");
}
- if (options.debug)
+ if (options.debug) {
std::cerr << "done." << std::endl;
+ }
}
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index aa13685e1..6f159740c 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -118,8 +118,9 @@ template<typename T, typename MiniT> struct LEB {
}
}
value |= significant_payload << shift;
- if (last)
+ if (last) {
break;
+ }
shift += 7;
if (size_t(shift) >= sizeof(T) * 8) {
throw ParseException("LEB overflow");
@@ -160,22 +161,25 @@ public:
BufferWithRandomAccess(bool debug = false) : debug(debug) {}
BufferWithRandomAccess& operator<<(int8_t x) {
- if (debug)
+ if (debug) {
std::cerr << "writeInt8: " << (int)(uint8_t)x << " (at " << size() << ")"
<< std::endl;
+ }
push_back(x);
return *this;
}
BufferWithRandomAccess& operator<<(int16_t x) {
- if (debug)
+ if (debug) {
std::cerr << "writeInt16: " << x << " (at " << size() << ")" << std::endl;
+ }
push_back(x & 0xff);
push_back(x >> 8);
return *this;
}
BufferWithRandomAccess& operator<<(int32_t x) {
- if (debug)
+ if (debug) {
std::cerr << "writeInt32: " << x << " (at " << size() << ")" << std::endl;
+ }
push_back(x & 0xff);
x >>= 8;
push_back(x & 0xff);
@@ -186,8 +190,9 @@ public:
return *this;
}
BufferWithRandomAccess& operator<<(int64_t x) {
- if (debug)
+ if (debug) {
std::cerr << "writeInt64: " << x << " (at " << size() << ")" << std::endl;
+ }
push_back(x & 0xff);
x >>= 8;
push_back(x & 0xff);
@@ -272,27 +277,31 @@ public:
BufferWithRandomAccess& operator<<(uint64_t x) { return *this << (int64_t)x; }
BufferWithRandomAccess& operator<<(float x) {
- if (debug)
+ if (debug) {
std::cerr << "writeFloat32: " << x << " (at " << size() << ")"
<< std::endl;
+ }
return *this << Literal(x).reinterpreti32();
}
BufferWithRandomAccess& operator<<(double x) {
- if (debug)
+ if (debug) {
std::cerr << "writeFloat64: " << x << " (at " << size() << ")"
<< std::endl;
+ }
return *this << Literal(x).reinterpreti64();
}
void writeAt(size_t i, uint16_t x) {
- if (debug)
+ if (debug) {
std::cerr << "backpatchInt16: " << x << " (at " << i << ")" << std::endl;
+ }
(*this)[i] = x & 0xff;
(*this)[i + 1] = x >> 8;
}
void writeAt(size_t i, uint32_t x) {
- if (debug)
+ if (debug) {
std::cerr << "backpatchInt32: " << x << " (at " << i << ")" << std::endl;
+ }
(*this)[i] = x & 0xff;
x >>= 8;
(*this)[i + 1] = x & 0xff;
@@ -305,24 +314,27 @@ public:
// writes out an LEB to an arbitrary location. this writes the LEB as a full
// 5 bytes, the fixed amount that can easily be set aside ahead of time
void writeAtFullFixedSize(size_t i, U32LEB x) {
- if (debug)
+ if (debug) {
std::cerr << "backpatchU32LEB: " << x.value << " (at " << i << ")"
<< std::endl;
+ }
// fill all 5 bytes, we have to do this when backpatching
x.writeAt(this, i, MaxLEB32Bytes);
}
// writes out an LEB of normal size
// returns how many bytes were written
size_t writeAt(size_t i, U32LEB x) {
- if (debug)
+ if (debug) {
std::cerr << "writeAtU32LEB: " << x.value << " (at " << i << ")"
<< std::endl;
+ }
return x.writeAt(this, i);
}
template<typename T> void writeTo(T& o) {
- for (auto c : *this)
+ for (auto c : *this) {
o << c;
+ }
}
std::vector<char> getAsChars() {
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index 8e7cc9908..9024ea6b1 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -547,10 +547,12 @@ public:
// block
Block* blockify(Expression* any, Expression* append = nullptr) {
Block* block = nullptr;
- if (any)
+ if (any) {
block = any->dynCast<Block>();
- if (!block)
+ }
+ if (!block) {
block = makeBlock(any);
+ }
if (append) {
block->list.push_back(append);
block->finalize();
@@ -569,10 +571,12 @@ public:
Block*
blockifyWithName(Expression* any, Name name, Expression* append = nullptr) {
Block* block = nullptr;
- if (any)
+ if (any) {
block = any->dynCast<Block>();
- if (!block || block->name.is())
+ }
+ if (!block || block->name.is()) {
block = makeBlock(any);
+ }
block->name = name;
if (append) {
block->list.push_back(append);
@@ -619,8 +623,9 @@ public:
// Drop an expression if it has a concrete type
Expression* dropIfConcretelyTyped(Expression* curr) {
- if (!isConcreteType(curr->type))
+ if (!isConcreteType(curr->type)) {
return curr;
+ }
return makeDrop(curr);
}
diff --git a/src/wasm-features.h b/src/wasm-features.h
index d31715f18..6337f6af9 100644
--- a/src/wasm-features.h
+++ b/src/wasm-features.h
@@ -84,18 +84,24 @@ struct FeatureSet {
}
template<typename F> void iterFeatures(F f) {
- if (hasAtomics())
+ if (hasAtomics()) {
f(Atomics);
- if (hasBulkMemory())
+ }
+ if (hasBulkMemory()) {
f(BulkMemory);
- if (hasMutableGlobals())
+ }
+ if (hasMutableGlobals()) {
f(MutableGlobals);
- if (hasTruncSat())
+ }
+ if (hasTruncSat()) {
f(TruncSat);
- if (hasSignExt())
+ }
+ if (hasSignExt()) {
f(SignExt);
- if (hasSIMD())
+ }
+ if (hasSIMD()) {
f(SIMD);
+ }
}
bool operator<=(const FeatureSet& other) const {
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index dd6e2b073..02e065c5f 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -182,17 +182,20 @@ public:
Flow visitIf(If* curr) {
NOTE_ENTER("If");
Flow flow = visit(curr->condition);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
NOTE_EVAL1(flow.value);
if (flow.value.geti32()) {
Flow flow = visit(curr->ifTrue);
- if (!flow.breaking() && !curr->ifFalse)
+ if (!flow.breaking() && !curr->ifFalse) {
flow.value = Literal(); // if_else returns a value, but if does not
+ }
return flow;
}
- if (curr->ifFalse)
+ if (curr->ifFalse) {
return visit(curr->ifFalse);
+ }
return Flow();
}
Flow visitLoop(Loop* curr) {
@@ -200,8 +203,9 @@ public:
while (1) {
Flow flow = visit(curr->body);
if (flow.breaking()) {
- if (flow.breakTo == curr->name)
+ if (flow.breakTo == curr->name) {
continue; // lol
+ }
}
// loop does not loop automatically, only continue achieves that
return flow;
@@ -213,16 +217,19 @@ public:
Flow flow;
if (curr->value) {
flow = visit(curr->value);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
}
if (curr->condition) {
Flow conditionFlow = visit(curr->condition);
- if (conditionFlow.breaking())
+ if (conditionFlow.breaking()) {
return conditionFlow;
+ }
condition = conditionFlow.value.getInteger() != 0;
- if (!condition)
+ if (!condition) {
return flow;
+ }
}
flow.breakTo = curr->name;
return flow;
@@ -233,14 +240,16 @@ public:
Literal value;
if (curr->value) {
flow = visit(curr->value);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
value = flow.value;
NOTE_EVAL1(value);
}
flow = visit(curr->condition);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
int64_t index = flow.value.getInteger();
Name target = curr->default_;
if (index >= 0 && (size_t)index < curr->targets.size()) {
@@ -263,8 +272,9 @@ public:
Flow visitUnary(Unary* curr) {
NOTE_ENTER("Unary");
Flow flow = visit(curr->value);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
Literal value = flow.value;
NOTE_EVAL1(value);
switch (curr->op) {
@@ -436,12 +446,14 @@ public:
Flow visitBinary(Binary* curr) {
NOTE_ENTER("Binary");
Flow flow = visit(curr->left);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
Literal left = flow.value;
flow = visit(curr->right);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
Literal right = flow.value;
NOTE_EVAL2(left, right);
assert(isConcreteType(curr->left->type) ? left.type == curr->left->type
@@ -465,53 +477,65 @@ public:
case MulFloat64:
return left.mul(right);
case DivSInt32: {
- if (right.getInteger() == 0)
+ if (right.getInteger() == 0) {
trap("i32.div_s by 0");
+ }
if (left.getInteger() == std::numeric_limits<int32_t>::min() &&
- right.getInteger() == -1)
+ right.getInteger() == -1) {
trap("i32.div_s overflow"); // signed division overflow
+ }
return left.divS(right);
}
case DivUInt32: {
- if (right.getInteger() == 0)
+ if (right.getInteger() == 0) {
trap("i32.div_u by 0");
+ }
return left.divU(right);
}
case RemSInt32: {
- if (right.getInteger() == 0)
+ if (right.getInteger() == 0) {
trap("i32.rem_s by 0");
+ }
if (left.getInteger() == std::numeric_limits<int32_t>::min() &&
- right.getInteger() == -1)
+ right.getInteger() == -1) {
return Literal(int32_t(0));
+ }
return left.remS(right);
}
case RemUInt32: {
- if (right.getInteger() == 0)
+ if (right.getInteger() == 0) {
trap("i32.rem_u by 0");
+ }
return left.remU(right);
}
case DivSInt64: {
- if (right.getInteger() == 0)
+ if (right.getInteger() == 0) {
trap("i64.div_s by 0");
- if (left.getInteger() == LLONG_MIN && right.getInteger() == -1LL)
+ }
+ if (left.getInteger() == LLONG_MIN && right.getInteger() == -1LL) {
trap("i64.div_s overflow"); // signed division overflow
+ }
return left.divS(right);
}
case DivUInt64: {
- if (right.getInteger() == 0)
+ if (right.getInteger() == 0) {
trap("i64.div_u by 0");
+ }
return left.divU(right);
}
case RemSInt64: {
- if (right.getInteger() == 0)
+ if (right.getInteger() == 0) {
trap("i64.rem_s by 0");
- if (left.getInteger() == LLONG_MIN && right.getInteger() == -1LL)
+ }
+ if (left.getInteger() == LLONG_MIN && right.getInteger() == -1LL) {
return Literal(int64_t(0));
+ }
return left.remS(right);
}
case RemUInt64: {
- if (right.getInteger() == 0)
+ if (right.getInteger() == 0) {
trap("i64.rem_u by 0");
+ }
return left.remU(right);
}
case DivFloat32:
@@ -763,8 +787,9 @@ public:
Flow visitSIMDExtract(SIMDExtract* curr) {
NOTE_ENTER("SIMDExtract");
Flow flow = this->visit(curr->vec);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
Literal vec = flow.value;
switch (curr->op) {
case ExtractLaneSVecI8x16:
@@ -789,12 +814,14 @@ public:
Flow visitSIMDReplace(SIMDReplace* curr) {
NOTE_ENTER("SIMDReplace");
Flow flow = this->visit(curr->vec);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
Literal vec = flow.value;
flow = this->visit(curr->value);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
Literal value = flow.value;
switch (curr->op) {
case ReplaceLaneVecI8x16:
@@ -815,40 +842,47 @@ public:
Flow visitSIMDShuffle(SIMDShuffle* curr) {
NOTE_ENTER("SIMDShuffle");
Flow flow = this->visit(curr->left);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
Literal left = flow.value;
flow = this->visit(curr->right);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
Literal right = flow.value;
return left.shuffleV8x16(right, curr->mask);
}
Flow visitSIMDBitselect(SIMDBitselect* curr) {
NOTE_ENTER("SIMDBitselect");
Flow flow = this->visit(curr->left);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
Literal left = flow.value;
flow = this->visit(curr->right);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
Literal right = flow.value;
flow = this->visit(curr->cond);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
Literal cond = flow.value;
return cond.bitselectV128(left, right);
}
Flow visitSIMDShift(SIMDShift* curr) {
NOTE_ENTER("SIMDShift");
Flow flow = this->visit(curr->vec);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
Literal vec = flow.value;
flow = this->visit(curr->shift);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
Literal shift = flow.value;
switch (curr->op) {
case ShlVecI8x16:
@@ -881,22 +915,26 @@ public:
Flow visitSelect(Select* curr) {
NOTE_ENTER("Select");
Flow ifTrue = visit(curr->ifTrue);
- if (ifTrue.breaking())
+ if (ifTrue.breaking()) {
return ifTrue;
+ }
Flow ifFalse = visit(curr->ifFalse);
- if (ifFalse.breaking())
+ if (ifFalse.breaking()) {
return ifFalse;
+ }
Flow condition = visit(curr->condition);
- if (condition.breaking())
+ if (condition.breaking()) {
return condition;
+ }
NOTE_EVAL1(condition.value);
return condition.value.geti32() ? ifTrue : ifFalse; // ;-)
}
Flow visitDrop(Drop* curr) {
NOTE_ENTER("Drop");
Flow value = visit(curr->value);
- if (value.breaking())
+ if (value.breaking()) {
return value;
+ }
return Flow();
}
Flow visitReturn(Return* curr) {
@@ -904,8 +942,9 @@ public:
Flow flow;
if (curr->value) {
flow = visit(curr->value);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
NOTE_EVAL1(flow.value);
}
flow.breakTo = RETURN_FLOW;
@@ -923,24 +962,29 @@ public:
Literal truncSFloat(Unary* curr, Literal value) {
double val = value.getFloat();
- if (std::isnan(val))
+ if (std::isnan(val)) {
trap("truncSFloat of nan");
+ }
if (curr->type == i32) {
if (value.type == f32) {
- if (!isInRangeI32TruncS(value.reinterpreti32()))
+ if (!isInRangeI32TruncS(value.reinterpreti32())) {
trap("i32.truncSFloat overflow");
+ }
} else {
- if (!isInRangeI32TruncS(value.reinterpreti64()))
+ if (!isInRangeI32TruncS(value.reinterpreti64())) {
trap("i32.truncSFloat overflow");
+ }
}
return Literal(int32_t(val));
} else {
if (value.type == f32) {
- if (!isInRangeI64TruncS(value.reinterpreti32()))
+ if (!isInRangeI64TruncS(value.reinterpreti32())) {
trap("i64.truncSFloat overflow");
+ }
} else {
- if (!isInRangeI64TruncS(value.reinterpreti64()))
+ if (!isInRangeI64TruncS(value.reinterpreti64())) {
trap("i64.truncSFloat overflow");
+ }
}
return Literal(int64_t(val));
}
@@ -948,24 +992,29 @@ public:
Literal truncUFloat(Unary* curr, Literal value) {
double val = value.getFloat();
- if (std::isnan(val))
+ if (std::isnan(val)) {
trap("truncUFloat of nan");
+ }
if (curr->type == i32) {
if (value.type == f32) {
- if (!isInRangeI32TruncU(value.reinterpreti32()))
+ if (!isInRangeI32TruncU(value.reinterpreti32())) {
trap("i32.truncUFloat overflow");
+ }
} else {
- if (!isInRangeI32TruncU(value.reinterpreti64()))
+ if (!isInRangeI32TruncU(value.reinterpreti64())) {
trap("i32.truncUFloat overflow");
+ }
}
return Literal(uint32_t(val));
} else {
if (value.type == f32) {
- if (!isInRangeI64TruncU(value.reinterpreti32()))
+ if (!isInRangeI64TruncU(value.reinterpreti32())) {
trap("i64.truncUFloat overflow");
+ }
} else {
- if (!isInRangeI64TruncU(value.reinterpreti64()))
+ if (!isInRangeI64TruncU(value.reinterpreti64())) {
trap("i64.truncUFloat overflow");
+ }
}
return Literal(uint64_t(val));
}
@@ -1193,8 +1242,9 @@ public:
// call an exported function
Literal callExport(Name name, const LiteralList& arguments) {
Export* export_ = wasm.getExportOrNull(name);
- if (!export_)
+ if (!export_) {
externalInterface->trap("callExport not found");
+ }
return callFunction(export_->value, arguments);
}
@@ -1203,12 +1253,14 @@ public:
// get an exported global
Literal getExport(Name name) {
Export* export_ = wasm.getExportOrNull(name);
- if (!export_)
+ if (!export_) {
externalInterface->trap("getExport external not found");
+ }
Name internalName = export_->value;
auto iter = globals.find(internalName);
- if (iter == globals.end())
+ if (iter == globals.end()) {
externalInterface->trap("getExport internal not found");
+ }
return iter->second;
}
@@ -1333,8 +1385,9 @@ private:
arguments.reserve(operands.size());
for (auto expression : operands) {
Flow flow = this->visit(expression);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
NOTE_EVAL1(flow.value);
arguments.push_back(flow.value);
}
@@ -1346,8 +1399,9 @@ private:
NOTE_NAME(curr->target);
LiteralList arguments;
Flow flow = generateArguments(curr->operands, arguments);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
auto* func = instance.wasm.getFunction(curr->target);
Flow ret;
if (func->imported()) {
@@ -1364,11 +1418,13 @@ private:
NOTE_ENTER("CallIndirect");
LiteralList arguments;
Flow flow = generateArguments(curr->operands, arguments);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
Flow target = this->visit(curr->target);
- if (target.breaking())
+ if (target.breaking()) {
return target;
+ }
Index index = target.value.geti32();
return instance.externalInterface->callTable(
index, arguments, curr->type, *instance.self());
@@ -1385,8 +1441,9 @@ private:
NOTE_ENTER("SetLocal");
auto index = curr->index;
Flow flow = this->visit(curr->value);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
NOTE_EVAL1(index);
NOTE_EVAL1(flow.value);
assert(curr->isTee() ? flow.value.type == curr->type : true);
@@ -1406,8 +1463,9 @@ private:
NOTE_ENTER("SetGlobal");
auto name = curr->name;
Flow flow = this->visit(curr->value);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
NOTE_EVAL1(name);
NOTE_EVAL1(flow.value);
instance.globals[name] = flow.value;
@@ -1417,8 +1475,9 @@ private:
Flow visitLoad(Load* curr) {
NOTE_ENTER("Load");
Flow flow = this->visit(curr->ptr);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
NOTE_EVAL1(flow);
auto addr = instance.getFinalAddress(curr, flow.value);
auto ret = instance.externalInterface->load(curr, addr);
@@ -1429,11 +1488,13 @@ private:
Flow visitStore(Store* curr) {
NOTE_ENTER("Store");
Flow ptr = this->visit(curr->ptr);
- if (ptr.breaking())
+ if (ptr.breaking()) {
return ptr;
+ }
Flow value = this->visit(curr->value);
- if (value.breaking())
+ if (value.breaking()) {
return value;
+ }
auto addr = instance.getFinalAddress(curr, ptr.value);
NOTE_EVAL1(addr);
NOTE_EVAL1(value);
@@ -1444,11 +1505,13 @@ private:
Flow visitAtomicRMW(AtomicRMW* curr) {
NOTE_ENTER("AtomicRMW");
Flow ptr = this->visit(curr->ptr);
- if (ptr.breaking())
+ if (ptr.breaking()) {
return ptr;
+ }
auto value = this->visit(curr->value);
- if (value.breaking())
+ if (value.breaking()) {
return value;
+ }
NOTE_EVAL1(ptr);
auto addr = instance.getFinalAddress(curr, ptr.value);
NOTE_EVAL1(addr);
@@ -1482,15 +1545,18 @@ private:
Flow visitAtomicCmpxchg(AtomicCmpxchg* curr) {
NOTE_ENTER("AtomicCmpxchg");
Flow ptr = this->visit(curr->ptr);
- if (ptr.breaking())
+ if (ptr.breaking()) {
return ptr;
+ }
NOTE_EVAL1(ptr);
auto expected = this->visit(curr->expected);
- if (expected.breaking())
+ if (expected.breaking()) {
return expected;
+ }
auto replacement = this->visit(curr->replacement);
- if (replacement.breaking())
+ if (replacement.breaking()) {
return replacement;
+ }
auto addr = instance.getFinalAddress(curr, ptr.value);
NOTE_EVAL1(addr);
NOTE_EVAL1(expected);
@@ -1505,17 +1571,20 @@ private:
Flow visitAtomicWait(AtomicWait* curr) {
NOTE_ENTER("AtomicWait");
Flow ptr = this->visit(curr->ptr);
- if (ptr.breaking())
+ if (ptr.breaking()) {
return ptr;
+ }
NOTE_EVAL1(ptr);
auto expected = this->visit(curr->expected);
NOTE_EVAL1(expected);
- if (expected.breaking())
+ if (expected.breaking()) {
return expected;
+ }
auto timeout = this->visit(curr->timeout);
NOTE_EVAL1(timeout);
- if (timeout.breaking())
+ if (timeout.breaking()) {
return timeout;
+ }
auto bytes = getTypeSize(curr->expectedType);
auto addr = instance.getFinalAddress(ptr.value, bytes);
auto loaded = instance.doAtomicLoad(addr, bytes, curr->expectedType);
@@ -1530,13 +1599,15 @@ private:
Flow visitAtomicNotify(AtomicNotify* curr) {
NOTE_ENTER("AtomicNotify");
Flow ptr = this->visit(curr->ptr);
- if (ptr.breaking())
+ if (ptr.breaking()) {
return ptr;
+ }
NOTE_EVAL1(ptr);
auto count = this->visit(curr->notifyCount);
NOTE_EVAL1(count);
- if (count.breaking())
+ if (count.breaking()) {
return count;
+ }
// TODO: add threads support!
return Literal(int32_t(0)); // none woken up
}
@@ -1548,17 +1619,21 @@ private:
case GrowMemory: {
auto fail = Literal(int32_t(-1));
Flow flow = this->visit(curr->operands[0]);
- if (flow.breaking())
+ if (flow.breaking()) {
return flow;
+ }
int32_t ret = instance.memorySize;
uint32_t delta = flow.value.geti32();
- if (delta > uint32_t(-1) / Memory::kPageSize)
+ if (delta > uint32_t(-1) / Memory::kPageSize) {
return fail;
- if (instance.memorySize >= uint32_t(-1) - delta)
+ }
+ if (instance.memorySize >= uint32_t(-1) - delta) {
return fail;
+ }
uint32_t newSize = instance.memorySize + delta;
- if (newSize > instance.wasm.memory.max)
+ if (newSize > instance.wasm.memory.max) {
return fail;
+ }
instance.externalInterface->growMemory(instance.memorySize *
Memory::kPageSize,
newSize * Memory::kPageSize);
@@ -1571,14 +1646,17 @@ private:
Flow visitMemoryInit(MemoryInit* curr) {
NOTE_ENTER("MemoryInit");
Flow dest = this->visit(curr->dest);
- if (dest.breaking())
+ if (dest.breaking()) {
return dest;
+ }
Flow offset = this->visit(curr->offset);
- if (offset.breaking())
+ if (offset.breaking()) {
return offset;
+ }
Flow size = this->visit(curr->size);
- if (size.breaking())
+ if (size.breaking()) {
return size;
+ }
NOTE_EVAL1(dest);
NOTE_EVAL1(offset);
NOTE_EVAL1(size);
@@ -1620,14 +1698,17 @@ private:
Flow visitMemoryCopy(MemoryCopy* curr) {
NOTE_ENTER("MemoryCopy");
Flow dest = this->visit(curr->dest);
- if (dest.breaking())
+ if (dest.breaking()) {
return dest;
+ }
Flow source = this->visit(curr->source);
- if (source.breaking())
+ if (source.breaking()) {
return source;
+ }
Flow size = this->visit(curr->size);
- if (size.breaking())
+ if (size.breaking()) {
return size;
+ }
NOTE_EVAL1(dest);
NOTE_EVAL1(source);
NOTE_EVAL1(size);
@@ -1662,14 +1743,17 @@ private:
Flow visitMemoryFill(MemoryFill* curr) {
NOTE_ENTER("MemoryFill");
Flow dest = this->visit(curr->dest);
- if (dest.breaking())
+ if (dest.breaking()) {
return dest;
+ }
Flow value = this->visit(curr->value);
- if (value.breaking())
+ if (value.breaking()) {
return value;
+ }
Flow size = this->visit(curr->size);
- if (size.breaking())
+ if (size.breaking()) {
return size;
+ }
NOTE_EVAL1(dest);
NOTE_EVAL1(value);
NOTE_EVAL1(size);
@@ -1704,8 +1788,9 @@ public:
// Internal function call. Must be public so that callTable implementations
// can use it (refactor?)
Literal callFunctionInternal(Name name, const LiteralList& arguments) {
- if (callDepth > maxCallDepth)
+ if (callDepth > maxCallDepth) {
externalInterface->trap("stack limit");
+ }
auto previousCallDepth = callDepth;
callDepth++;
auto previousFunctionStackSize = functionStack.size();
diff --git a/src/wasm-module-building.h b/src/wasm-module-building.h
index 6f9a58eeb..63129f874 100644
--- a/src/wasm-module-building.h
+++ b/src/wasm-module-building.h
@@ -169,8 +169,9 @@ public:
// Add a function to the module, and to be optimized
void addFunction(Function* func) {
wasm->addFunction(func);
- if (!useWorkers())
+ if (!useWorkers()) {
return; // we optimize at the end in that case
+ }
queueFunction(func);
// notify workers if needed
auto notify = availableFuncs.load();
@@ -240,8 +241,9 @@ private:
}
}
DEBUG_THREAD("joining");
- for (auto& thread : threads)
+ for (auto& thread : threads) {
thread->join();
+ }
DEBUG_THREAD("joined");
}
diff --git a/src/wasm-stack.h b/src/wasm-stack.h
index 124b70926..0355f60ee 100644
--- a/src/wasm-stack.h
+++ b/src/wasm-stack.h
@@ -246,8 +246,9 @@ public:
this->setFunction(funcInit);
this->mapLocalsAndEmitHeader();
for (auto* inst : *funcInit->stackIR) {
- if (!inst)
+ if (!inst) {
continue; // a nullptr is just something we can skip
+ }
switch (inst->op) {
case StackInst::Basic:
case StackInst::BlockBegin:
@@ -335,16 +336,21 @@ void StackWriter<Mode, Parent>::mapLocalsAndEmitHeader() {
o << U32LEB((numLocalsByType[i32] ? 1 : 0) + (numLocalsByType[i64] ? 1 : 0) +
(numLocalsByType[f32] ? 1 : 0) + (numLocalsByType[f64] ? 1 : 0) +
(numLocalsByType[v128] ? 1 : 0));
- if (numLocalsByType[i32])
+ if (numLocalsByType[i32]) {
o << U32LEB(numLocalsByType[i32]) << binaryType(i32);
- if (numLocalsByType[i64])
+ }
+ if (numLocalsByType[i64]) {
o << U32LEB(numLocalsByType[i64]) << binaryType(i64);
- if (numLocalsByType[f32])
+ }
+ if (numLocalsByType[f32]) {
o << U32LEB(numLocalsByType[f32]) << binaryType(f32);
- if (numLocalsByType[f64])
+ }
+ if (numLocalsByType[f64]) {
o << U32LEB(numLocalsByType[f64]) << binaryType(f64);
- if (numLocalsByType[v128])
+ }
+ if (numLocalsByType[v128]) {
o << U32LEB(numLocalsByType[v128]) << binaryType(v128);
+ }
}
template<StackWriterMode Mode, typename Parent>
@@ -570,8 +576,9 @@ void StackWriter<Mode, Parent>::visitBreak(Break* curr) {
if (curr->value) {
visitChild(curr->value);
}
- if (curr->condition)
+ if (curr->condition) {
visitChild(curr->condition);
+ }
if (!justAddToStack(curr)) {
o << int8_t(curr->condition ? BinaryConsts::BrIf : BinaryConsts::Br)
<< U32LEB(getBreakIndex(curr->name));
@@ -601,8 +608,9 @@ void StackWriter<Mode, Parent>::visitSwitch(Switch* curr) {
emitExtraUnreachable();
return;
}
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::TableSwitch) << U32LEB(curr->targets.size());
for (auto target : curr->targets) {
o << U32LEB(getBreakIndex(target));
@@ -643,8 +651,9 @@ void StackWriter<Mode, Parent>::visitCallIndirect(CallIndirect* curr) {
template<StackWriterMode Mode, typename Parent>
void StackWriter<Mode, Parent>::visitGetLocal(GetLocal* curr) {
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::GetLocal) << U32LEB(mappedLocals[curr->index]);
}
@@ -662,8 +671,9 @@ void StackWriter<Mode, Parent>::visitSetLocal(SetLocal* curr) {
template<StackWriterMode Mode, typename Parent>
void StackWriter<Mode, Parent>::visitGetGlobal(GetGlobal* curr) {
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::GetGlobal)
<< U32LEB(parent.getGlobalIndex(curr->name));
}
@@ -671,8 +681,9 @@ void StackWriter<Mode, Parent>::visitGetGlobal(GetGlobal* curr) {
template<StackWriterMode Mode, typename Parent>
void StackWriter<Mode, Parent>::visitSetGlobal(SetGlobal* curr) {
visitChild(curr->value);
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::SetGlobal)
<< U32LEB(parent.getGlobalIndex(curr->name));
}
@@ -685,8 +696,9 @@ void StackWriter<Mode, Parent>::visitLoad(Load* curr) {
emitExtraUnreachable();
return;
}
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
if (!curr->isAtomic) {
switch (curr->type) {
case i32: {
@@ -801,8 +813,9 @@ void StackWriter<Mode, Parent>::visitStore(Store* curr) {
emitExtraUnreachable();
return;
}
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
if (!curr->isAtomic) {
switch (curr->valueType) {
case i32: {
@@ -903,18 +916,21 @@ template<StackWriterMode Mode, typename Parent>
void StackWriter<Mode, Parent>::visitAtomicRMW(AtomicRMW* curr) {
visitChild(curr->ptr);
// stop if the rest isn't reachable anyhow
- if (curr->ptr->type == unreachable)
+ if (curr->ptr->type == unreachable) {
return;
+ }
visitChild(curr->value);
- if (curr->value->type == unreachable)
+ if (curr->value->type == unreachable) {
return;
+ }
if (curr->type == unreachable) {
// don't even emit it; we don't know the right type
emitExtraUnreachable();
return;
}
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::AtomicPrefix);
@@ -978,21 +994,25 @@ template<StackWriterMode Mode, typename Parent>
void StackWriter<Mode, Parent>::visitAtomicCmpxchg(AtomicCmpxchg* curr) {
visitChild(curr->ptr);
// stop if the rest isn't reachable anyhow
- if (curr->ptr->type == unreachable)
+ if (curr->ptr->type == unreachable) {
return;
+ }
visitChild(curr->expected);
- if (curr->expected->type == unreachable)
+ if (curr->expected->type == unreachable) {
return;
+ }
visitChild(curr->replacement);
- if (curr->replacement->type == unreachable)
+ if (curr->replacement->type == unreachable) {
return;
+ }
if (curr->type == unreachable) {
// don't even emit it; we don't know the right type
emitExtraUnreachable();
return;
}
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::AtomicPrefix);
switch (curr->type) {
@@ -1039,16 +1059,20 @@ template<StackWriterMode Mode, typename Parent>
void StackWriter<Mode, Parent>::visitAtomicWait(AtomicWait* curr) {
visitChild(curr->ptr);
// stop if the rest isn't reachable anyhow
- if (curr->ptr->type == unreachable)
+ if (curr->ptr->type == unreachable) {
return;
+ }
visitChild(curr->expected);
- if (curr->expected->type == unreachable)
+ if (curr->expected->type == unreachable) {
return;
+ }
visitChild(curr->timeout);
- if (curr->timeout->type == unreachable)
+ if (curr->timeout->type == unreachable) {
return;
- if (justAddToStack(curr))
+ }
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::AtomicPrefix);
switch (curr->expectedType) {
@@ -1071,13 +1095,16 @@ template<StackWriterMode Mode, typename Parent>
void StackWriter<Mode, Parent>::visitAtomicNotify(AtomicNotify* curr) {
visitChild(curr->ptr);
// stop if the rest isn't reachable anyhow
- if (curr->ptr->type == unreachable)
+ if (curr->ptr->type == unreachable) {
return;
+ }
visitChild(curr->notifyCount);
- if (curr->notifyCount->type == unreachable)
+ if (curr->notifyCount->type == unreachable) {
return;
- if (justAddToStack(curr))
+ }
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::AtomicPrefix) << int8_t(BinaryConsts::AtomicNotify);
emitMemoryAccess(4, 4, 0);
@@ -1086,8 +1113,9 @@ void StackWriter<Mode, Parent>::visitAtomicNotify(AtomicNotify* curr) {
template<StackWriterMode Mode, typename Parent>
void StackWriter<Mode, Parent>::visitSIMDExtract(SIMDExtract* curr) {
visitChild(curr->vec);
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::SIMDPrefix);
switch (curr->op) {
case ExtractLaneSVecI8x16:
@@ -1122,8 +1150,9 @@ template<StackWriterMode Mode, typename Parent>
void StackWriter<Mode, Parent>::visitSIMDReplace(SIMDReplace* curr) {
visitChild(curr->vec);
visitChild(curr->value);
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::SIMDPrefix);
switch (curr->op) {
case ReplaceLaneVecI8x16:
@@ -1153,8 +1182,9 @@ template<StackWriterMode Mode, typename Parent>
void StackWriter<Mode, Parent>::visitSIMDShuffle(SIMDShuffle* curr) {
visitChild(curr->left);
visitChild(curr->right);
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::V8x16Shuffle);
for (uint8_t m : curr->mask) {
o << m;
@@ -1166,8 +1196,9 @@ void StackWriter<Mode, Parent>::visitSIMDBitselect(SIMDBitselect* curr) {
visitChild(curr->left);
visitChild(curr->right);
visitChild(curr->cond);
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::V128Bitselect);
}
@@ -1175,8 +1206,9 @@ template<StackWriterMode Mode, typename Parent>
void StackWriter<Mode, Parent>::visitSIMDShift(SIMDShift* curr) {
visitChild(curr->vec);
visitChild(curr->shift);
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::SIMDPrefix);
switch (curr->op) {
case ShlVecI8x16:
@@ -1223,8 +1255,9 @@ void StackWriter<Mode, Parent>::visitMemoryInit(MemoryInit* curr) {
visitChild(curr->dest);
visitChild(curr->offset);
visitChild(curr->size);
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::MiscPrefix);
o << U32LEB(BinaryConsts::MemoryInit);
o << U32LEB(curr->segment) << int8_t(0);
@@ -1232,8 +1265,9 @@ void StackWriter<Mode, Parent>::visitMemoryInit(MemoryInit* curr) {
template<StackWriterMode Mode, typename Parent>
void StackWriter<Mode, Parent>::visitDataDrop(DataDrop* curr) {
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::MiscPrefix);
o << U32LEB(BinaryConsts::DataDrop);
o << U32LEB(curr->segment);
@@ -1244,8 +1278,9 @@ void StackWriter<Mode, Parent>::visitMemoryCopy(MemoryCopy* curr) {
visitChild(curr->dest);
visitChild(curr->source);
visitChild(curr->size);
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::MiscPrefix);
o << U32LEB(BinaryConsts::MemoryCopy);
o << int8_t(0) << int8_t(0);
@@ -1256,8 +1291,9 @@ void StackWriter<Mode, Parent>::visitMemoryFill(MemoryFill* curr) {
visitChild(curr->dest);
visitChild(curr->value);
visitChild(curr->size);
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::MiscPrefix);
o << U32LEB(BinaryConsts::MemoryFill);
o << int8_t(0);
@@ -1265,8 +1301,9 @@ void StackWriter<Mode, Parent>::visitMemoryFill(MemoryFill* curr) {
template<StackWriterMode Mode, typename Parent>
void StackWriter<Mode, Parent>::visitConst(Const* curr) {
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
switch (curr->type) {
case i32: {
o << int8_t(BinaryConsts::I32Const) << S32LEB(curr->value.geti32());
@@ -1305,8 +1342,9 @@ void StackWriter<Mode, Parent>::visitUnary(Unary* curr) {
emitExtraUnreachable();
return;
}
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
switch (curr->op) {
case ClzInt32:
o << int8_t(BinaryConsts::I32Clz);
@@ -1624,8 +1662,9 @@ void StackWriter<Mode, Parent>::visitBinary(Binary* curr) {
emitExtraUnreachable();
return;
}
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
switch (curr->op) {
case AddInt32:
o << int8_t(BinaryConsts::I32Add);
@@ -2111,8 +2150,9 @@ void StackWriter<Mode, Parent>::visitSelect(Select* curr) {
emitExtraUnreachable();
return;
}
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::Select);
}
@@ -2121,8 +2161,9 @@ void StackWriter<Mode, Parent>::visitReturn(Return* curr) {
if (curr->value) {
visitChild(curr->value);
}
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::Return);
}
@@ -2138,8 +2179,9 @@ void StackWriter<Mode, Parent>::visitHost(Host* curr) {
break;
}
}
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
switch (curr->op) {
case CurrentMemory: {
o << int8_t(BinaryConsts::CurrentMemory);
@@ -2155,23 +2197,26 @@ void StackWriter<Mode, Parent>::visitHost(Host* curr) {
template<StackWriterMode Mode, typename Parent>
void StackWriter<Mode, Parent>::visitNop(Nop* curr) {
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::Nop);
}
template<StackWriterMode Mode, typename Parent>
void StackWriter<Mode, Parent>::visitUnreachable(Unreachable* curr) {
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::Unreachable);
}
template<StackWriterMode Mode, typename Parent>
void StackWriter<Mode, Parent>::visitDrop(Drop* curr) {
visitChild(curr->value);
- if (justAddToStack(curr))
+ if (justAddToStack(curr)) {
return;
+ }
o << int8_t(BinaryConsts::Drop);
}
diff --git a/src/wasm-traversal.h b/src/wasm-traversal.h
index 2b495e025..5a2debcdf 100644
--- a/src/wasm-traversal.h
+++ b/src/wasm-traversal.h
@@ -957,17 +957,20 @@ struct ControlFlowWalker : public PostWalker<SubType, VisitorType> {
while (1) {
auto* curr = controlFlowStack[i];
if (Block* block = curr->template dynCast<Block>()) {
- if (name == block->name)
+ if (name == block->name) {
return curr;
+ }
} else if (Loop* loop = curr->template dynCast<Loop>()) {
- if (name == loop->name)
+ if (name == loop->name) {
return curr;
+ }
} else {
// an if, ignorable
assert(curr->template is<If>());
}
- if (i == 0)
+ if (i == 0) {
return nullptr;
+ }
i--;
}
}
@@ -1024,23 +1027,27 @@ struct ExpressionStackWalker : public PostWalker<SubType, VisitorType> {
while (1) {
auto* curr = expressionStack[i];
if (Block* block = curr->template dynCast<Block>()) {
- if (name == block->name)
+ if (name == block->name) {
return curr;
+ }
} else if (Loop* loop = curr->template dynCast<Loop>()) {
- if (name == loop->name)
+ if (name == loop->name) {
return curr;
+ }
} else {
WASM_UNREACHABLE();
}
- if (i == 0)
+ if (i == 0) {
return nullptr;
+ }
i--;
}
}
Expression* getParent() {
- if (expressionStack.size() == 1)
+ if (expressionStack.size() == 1) {
return nullptr;
+ }
assert(expressionStack.size() >= 2);
return expressionStack[expressionStack.size() - 2];
}
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index be92ae03d..3d7303e23 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -144,10 +144,12 @@ void Literal::getBits(uint8_t (&buf)[16]) const {
}
bool Literal::operator==(const Literal& other) const {
- if (type != other.type)
+ if (type != other.type) {
return false;
- if (type == none)
+ }
+ if (type == none) {
return true;
+ }
uint8_t bits[16], other_bits[16];
getBits(bits);
other.getBits(other_bits);
@@ -238,8 +240,9 @@ void Literal::printDouble(std::ostream& o, double d) {
void Literal::printVec128(std::ostream& o, const std::array<uint8_t, 16>& v) {
o << std::hex;
for (auto i = 0; i < 16; i += 4) {
- if (i)
+ if (i) {
o << " ";
+ }
o << "0x" << std::setfill('0') << std::setw(8)
<< uint32_t(v[i] | (v[i + 1] << 8) | (v[i + 2] << 16) | (v[i + 3] << 24));
}
@@ -276,26 +279,32 @@ std::ostream& operator<<(std::ostream& o, Literal literal) {
}
Literal Literal::countLeadingZeroes() const {
- if (type == Type::i32)
+ if (type == Type::i32) {
return Literal((int32_t)CountLeadingZeroes(i32));
- if (type == Type::i64)
+ }
+ if (type == Type::i64) {
return Literal((int64_t)CountLeadingZeroes(i64));
+ }
WASM_UNREACHABLE();
}
Literal Literal::countTrailingZeroes() const {
- if (type == Type::i32)
+ if (type == Type::i32) {
return Literal((int32_t)CountTrailingZeroes(i32));
- if (type == Type::i64)
+ }
+ if (type == Type::i64) {
return Literal((int64_t)CountTrailingZeroes(i64));
+ }
WASM_UNREACHABLE();
}
Literal Literal::popCount() const {
- if (type == Type::i32)
+ if (type == Type::i32) {
return Literal((int32_t)PopCount(i32));
- if (type == Type::i64)
+ }
+ if (type == Type::i64) {
return Literal((int64_t)PopCount(i64));
+ }
WASM_UNREACHABLE();
}
@@ -315,24 +324,29 @@ Literal Literal::extendToF64() const {
}
Literal Literal::extendS8() const {
- if (type == Type::i32)
+ if (type == Type::i32) {
return Literal(int32_t(int8_t(geti32() & 0xFF)));
- if (type == Type::i64)
+ }
+ if (type == Type::i64) {
return Literal(int64_t(int8_t(geti64() & 0xFF)));
+ }
WASM_UNREACHABLE();
}
Literal Literal::extendS16() const {
- if (type == Type::i32)
+ if (type == Type::i32) {
return Literal(int32_t(int16_t(geti32() & 0xFFFF)));
- if (type == Type::i64)
+ }
+ if (type == Type::i64) {
return Literal(int64_t(int16_t(geti64() & 0xFFFF)));
+ }
WASM_UNREACHABLE();
}
Literal Literal::extendS32() const {
- if (type == Type::i64)
+ if (type == Type::i64) {
return Literal(int64_t(int32_t(geti64() & 0xFFFFFFFF)));
+ }
WASM_UNREACHABLE();
}
@@ -342,34 +356,42 @@ Literal Literal::wrapToI32() const {
}
Literal Literal::convertSIToF32() const {
- if (type == Type::i32)
+ if (type == Type::i32) {
return Literal(float(i32));
- if (type == Type::i64)
+ }
+ if (type == Type::i64) {
return Literal(float(i64));
+ }
WASM_UNREACHABLE();
}
Literal Literal::convertUIToF32() const {
- if (type == Type::i32)
+ if (type == Type::i32) {
return Literal(float(uint32_t(i32)));
- if (type == Type::i64)
+ }
+ if (type == Type::i64) {
return Literal(float(uint64_t(i64)));
+ }
WASM_UNREACHABLE();
}
Literal Literal::convertSIToF64() const {
- if (type == Type::i32)
+ if (type == Type::i32) {
return Literal(double(i32));
- if (type == Type::i64)
+ }
+ if (type == Type::i64) {
return Literal(double(i64));
+ }
WASM_UNREACHABLE();
}
Literal Literal::convertUIToF64() const {
- if (type == Type::i32)
+ if (type == Type::i32) {
return Literal(double(uint32_t(i32)));
- if (type == Type::i64)
+ }
+ if (type == Type::i64) {
return Literal(double(uint64_t(i64)));
+ }
WASM_UNREACHABLE();
}
@@ -551,23 +573,29 @@ Literal Literal::sqrt() const {
Literal Literal::demote() const {
auto f64 = getf64();
- if (std::isnan(f64))
+ if (std::isnan(f64)) {
return Literal(float(f64));
- if (std::isinf(f64))
+ }
+ if (std::isinf(f64)) {
return Literal(float(f64));
+ }
// when close to the limit, but still truncatable to a valid value, do that
// see
// https://github.com/WebAssembly/sexpr-wasm-prototype/blob/2d375e8d502327e814d62a08f22da9d9b6b675dc/src/wasm-interpreter.c#L247
uint64_t bits = reinterpreti64();
- if (bits > 0x47efffffe0000000ULL && bits < 0x47effffff0000000ULL)
+ if (bits > 0x47efffffe0000000ULL && bits < 0x47effffff0000000ULL) {
return Literal(std::numeric_limits<float>::max());
- if (bits > 0xc7efffffe0000000ULL && bits < 0xc7effffff0000000ULL)
+ }
+ if (bits > 0xc7efffffe0000000ULL && bits < 0xc7effffff0000000ULL) {
return Literal(-std::numeric_limits<float>::max());
+ }
// when we must convert to infinity, do that
- if (f64 < -std::numeric_limits<float>::max())
+ if (f64 < -std::numeric_limits<float>::max()) {
return Literal(-std::numeric_limits<float>::infinity());
- if (f64 > std::numeric_limits<float>::max())
+ }
+ if (f64 > std::numeric_limits<float>::max()) {
return Literal(std::numeric_limits<float>::infinity());
+ }
return Literal(float(getf64()));
}
@@ -1067,14 +1095,17 @@ Literal Literal::min(const Literal& other) const {
switch (type) {
case Type::f32: {
auto l = getf32(), r = other.getf32();
- if (l == r && l == 0)
+ if (l == r && l == 0) {
return Literal(std::signbit(l) ? l : r);
+ }
auto result = std::min(l, r);
bool lnan = std::isnan(l), rnan = std::isnan(r);
- if (!std::isnan(result) && !lnan && !rnan)
+ if (!std::isnan(result) && !lnan && !rnan) {
return Literal(result);
- if (!lnan && !rnan)
+ }
+ if (!lnan && !rnan) {
return Literal((int32_t)0x7fc00000).castToF32();
+ }
return Literal(lnan ? l : r)
.castToI32()
.or_(Literal(0xc00000))
@@ -1082,14 +1113,17 @@ Literal Literal::min(const Literal& other) const {
}
case Type::f64: {
auto l = getf64(), r = other.getf64();
- if (l == r && l == 0)
+ if (l == r && l == 0) {
return Literal(std::signbit(l) ? l : r);
+ }
auto result = std::min(l, r);
bool lnan = std::isnan(l), rnan = std::isnan(r);
- if (!std::isnan(result) && !lnan && !rnan)
+ if (!std::isnan(result) && !lnan && !rnan) {
return Literal(result);
- if (!lnan && !rnan)
+ }
+ if (!lnan && !rnan) {
return Literal((int64_t)0x7ff8000000000000LL).castToF64();
+ }
return Literal(lnan ? l : r)
.castToI64()
.or_(Literal(int64_t(0x8000000000000LL)))
@@ -1104,14 +1138,17 @@ Literal Literal::max(const Literal& other) const {
switch (type) {
case Type::f32: {
auto l = getf32(), r = other.getf32();
- if (l == r && l == 0)
+ if (l == r && l == 0) {
return Literal(std::signbit(l) ? r : l);
+ }
auto result = std::max(l, r);
bool lnan = std::isnan(l), rnan = std::isnan(r);
- if (!std::isnan(result) && !lnan && !rnan)
+ if (!std::isnan(result) && !lnan && !rnan) {
return Literal(result);
- if (!lnan && !rnan)
+ }
+ if (!lnan && !rnan) {
return Literal((int32_t)0x7fc00000).castToF32();
+ }
return Literal(lnan ? l : r)
.castToI32()
.or_(Literal(0xc00000))
@@ -1119,14 +1156,17 @@ Literal Literal::max(const Literal& other) const {
}
case Type::f64: {
auto l = getf64(), r = other.getf64();
- if (l == r && l == 0)
+ if (l == r && l == 0) {
return Literal(std::signbit(l) ? r : l);
+ }
auto result = std::max(l, r);
bool lnan = std::isnan(l), rnan = std::isnan(r);
- if (!std::isnan(result) && !lnan && !rnan)
+ if (!std::isnan(result) && !lnan && !rnan) {
return Literal(result);
- if (!lnan && !rnan)
+ }
+ if (!lnan && !rnan) {
return Literal((int64_t)0x7ff8000000000000LL).castToF64();
+ }
return Literal(lnan ? l : r)
.castToI64()
.or_(Literal(int64_t(0x8000000000000LL)))
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 6369a79fa..81020cf75 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -63,12 +63,15 @@ void WasmBinaryWriter::write() {
writeDataCount();
writeFunctions();
writeDataSegments();
- if (debugInfo)
+ if (debugInfo) {
writeNames();
- if (sourceMap && !sourceMapUrl.empty())
+ }
+ if (sourceMap && !sourceMapUrl.empty()) {
writeSourceMapUrl();
- if (symbolMap.size() > 0)
+ }
+ if (symbolMap.size() > 0) {
writeSymbolMap();
+ }
if (sourceMap) {
writeSourceMapEpilog();
@@ -81,8 +84,9 @@ void WasmBinaryWriter::write() {
}
void WasmBinaryWriter::writeHeader() {
- if (debug)
+ if (debug) {
std::cerr << "== writeHeader" << std::endl;
+ }
o << int32_t(BinaryConsts::Magic); // magic number \0asm
o << int32_t(BinaryConsts::Version);
}
@@ -109,8 +113,9 @@ void WasmBinaryWriter::writeResizableLimits(Address initial,
template<typename T> int32_t WasmBinaryWriter::startSection(T code) {
o << U32LEB(code);
- if (sourceMap)
+ if (sourceMap) {
sourceMapLocationsSizeAtSectionStart = sourceMapLocations.size();
+ }
return writeU32LEBPlaceholder(); // section size to be filled in later
}
@@ -144,20 +149,24 @@ WasmBinaryWriter::startSubsection(BinaryConsts::UserSections::Subsection code) {
void WasmBinaryWriter::finishSubsection(int32_t start) { finishSection(start); }
void WasmBinaryWriter::writeStart() {
- if (!wasm->start.is())
+ if (!wasm->start.is()) {
return;
- if (debug)
+ }
+ if (debug) {
std::cerr << "== writeStart" << std::endl;
+ }
auto start = startSection(BinaryConsts::Section::Start);
o << U32LEB(getFunctionIndex(wasm->start.str));
finishSection(start);
}
void WasmBinaryWriter::writeMemory() {
- if (!wasm->memory.exists || wasm->memory.imported())
+ if (!wasm->memory.exists || wasm->memory.imported()) {
return;
- if (debug)
+ }
+ if (debug) {
std::cerr << "== writeMemory" << std::endl;
+ }
auto start = startSection(BinaryConsts::Section::Memory);
o << U32LEB(1); // Define 1 memory
writeResizableLimits(wasm->memory.initial,
@@ -168,15 +177,18 @@ void WasmBinaryWriter::writeMemory() {
}
void WasmBinaryWriter::writeTypes() {
- if (wasm->functionTypes.size() == 0)
+ if (wasm->functionTypes.size() == 0) {
return;
- if (debug)
+ }
+ if (debug) {
std::cerr << "== writeTypes" << std::endl;
+ }
auto start = startSection(BinaryConsts::Section::Type);
o << U32LEB(wasm->functionTypes.size());
for (auto& type : wasm->functionTypes) {
- if (debug)
+ if (debug) {
std::cerr << "write one" << std::endl;
+ }
o << S32LEB(BinaryConsts::EncodedType::Func);
o << U32LEB(type->params.size());
for (auto param : type->params) {
@@ -195,18 +207,21 @@ void WasmBinaryWriter::writeTypes() {
int32_t WasmBinaryWriter::getFunctionTypeIndex(Name type) {
// TODO: optimize
for (size_t i = 0; i < wasm->functionTypes.size(); i++) {
- if (wasm->functionTypes[i]->name == type)
+ if (wasm->functionTypes[i]->name == type) {
return i;
+ }
}
abort();
}
void WasmBinaryWriter::writeImports() {
auto num = importInfo->getNumImports();
- if (num == 0)
+ if (num == 0) {
return;
- if (debug)
+ }
+ if (debug) {
std::cerr << "== writeImports" << std::endl;
+ }
auto start = startSection(BinaryConsts::Section::Import);
o << U32LEB(num);
auto writeImportHeader = [&](Importable* import) {
@@ -214,23 +229,26 @@ void WasmBinaryWriter::writeImports() {
writeInlineString(import->base.str);
};
ModuleUtils::iterImportedFunctions(*wasm, [&](Function* func) {
- if (debug)
+ if (debug) {
std::cerr << "write one function" << std::endl;
+ }
writeImportHeader(func);
o << U32LEB(int32_t(ExternalKind::Function));
o << U32LEB(getFunctionTypeIndex(func->type));
});
ModuleUtils::iterImportedGlobals(*wasm, [&](Global* global) {
- if (debug)
+ if (debug) {
std::cerr << "write one global" << std::endl;
+ }
writeImportHeader(global);
o << U32LEB(int32_t(ExternalKind::Global));
o << binaryType(global->type);
o << U32LEB(global->mutable_);
});
if (wasm->memory.imported()) {
- if (debug)
+ if (debug) {
std::cerr << "write one memory" << std::endl;
+ }
writeImportHeader(&wasm->memory);
o << U32LEB(int32_t(ExternalKind::Memory));
writeResizableLimits(wasm->memory.initial,
@@ -239,8 +257,9 @@ void WasmBinaryWriter::writeImports() {
wasm->memory.shared);
}
if (wasm->table.imported()) {
- if (debug)
+ if (debug) {
std::cerr << "write one table" << std::endl;
+ }
writeImportHeader(&wasm->table);
o << U32LEB(int32_t(ExternalKind::Table));
o << S32LEB(BinaryConsts::EncodedType::AnyFunc);
@@ -253,15 +272,18 @@ void WasmBinaryWriter::writeImports() {
}
void WasmBinaryWriter::writeFunctionSignatures() {
- if (importInfo->getNumDefinedFunctions() == 0)
+ if (importInfo->getNumDefinedFunctions() == 0) {
return;
- if (debug)
+ }
+ if (debug) {
std::cerr << "== writeFunctionSignatures" << std::endl;
+ }
auto start = startSection(BinaryConsts::Section::Function);
o << U32LEB(importInfo->getNumDefinedFunctions());
ModuleUtils::iterDefinedFunctions(*wasm, [&](Function* func) {
- if (debug)
+ if (debug) {
std::cerr << "write one" << std::endl;
+ }
o << U32LEB(getFunctionTypeIndex(func->type));
});
finishSection(start);
@@ -272,35 +294,42 @@ void WasmBinaryWriter::writeExpression(Expression* curr) {
}
void WasmBinaryWriter::writeFunctions() {
- if (importInfo->getNumDefinedFunctions() == 0)
+ if (importInfo->getNumDefinedFunctions() == 0) {
return;
- if (debug)
+ }
+ if (debug) {
std::cerr << "== writeFunctions" << std::endl;
+ }
auto start = startSection(BinaryConsts::Section::Code);
o << U32LEB(importInfo->getNumDefinedFunctions());
ModuleUtils::iterDefinedFunctions(*wasm, [&](Function* func) {
size_t sourceMapLocationsSizeAtFunctionStart = sourceMapLocations.size();
- if (debug)
+ if (debug) {
std::cerr << "write one at" << o.size() << std::endl;
+ }
size_t sizePos = writeU32LEBPlaceholder();
size_t start = o.size();
- if (debug)
+ if (debug) {
std::cerr << "writing" << func->name << std::endl;
+ }
// Emit Stack IR if present, and if we can
if (func->stackIR && !sourceMap) {
- if (debug)
+ if (debug) {
std::cerr << "write Stack IR" << std::endl;
+ }
StackIRFunctionStackWriter<WasmBinaryWriter>(func, *this, o, debug);
} else {
- if (debug)
+ if (debug) {
std::cerr << "write Binaryen IR" << std::endl;
+ }
FunctionStackWriter<WasmBinaryWriter>(func, *this, o, sourceMap, debug);
}
size_t size = o.size() - start;
assert(size <= std::numeric_limits<uint32_t>::max());
- if (debug)
+ if (debug) {
std::cerr << "body size: " << size << ", writing at " << sizePos
<< ", next starts at " << o.size() << std::endl;
+ }
auto sizeFieldSize = o.writeAt(sizePos, U32LEB(size));
if (sizeFieldSize != MaxLEB32Bytes) {
// we can save some room, nice
@@ -323,16 +352,19 @@ void WasmBinaryWriter::writeFunctions() {
}
void WasmBinaryWriter::writeGlobals() {
- if (importInfo->getNumDefinedGlobals() == 0)
+ if (importInfo->getNumDefinedGlobals() == 0) {
return;
- if (debug)
+ }
+ if (debug) {
std::cerr << "== writeglobals" << std::endl;
+ }
auto start = startSection(BinaryConsts::Section::Global);
auto num = importInfo->getNumDefinedGlobals();
o << U32LEB(num);
ModuleUtils::iterDefinedGlobals(*wasm, [&](Global* global) {
- if (debug)
+ if (debug) {
std::cerr << "write one" << std::endl;
+ }
o << binaryType(global->type);
o << U32LEB(global->mutable_);
writeExpression(global->init);
@@ -342,15 +374,18 @@ void WasmBinaryWriter::writeGlobals() {
}
void WasmBinaryWriter::writeExports() {
- if (wasm->exports.size() == 0)
+ if (wasm->exports.size() == 0) {
return;
- if (debug)
+ }
+ if (debug) {
std::cerr << "== writeexports" << std::endl;
+ }
auto start = startSection(BinaryConsts::Section::Export);
o << U32LEB(wasm->exports.size());
for (auto& curr : wasm->exports) {
- if (debug)
+ if (debug) {
std::cerr << "write one" << std::endl;
+ }
writeInlineString(curr->name.str);
o << U32LEB(int32_t(curr->kind));
switch (curr->kind) {
@@ -383,8 +418,9 @@ void WasmBinaryWriter::writeDataCount() {
}
void WasmBinaryWriter::writeDataSegments() {
- if (wasm->memory.segments.size() == 0)
+ if (wasm->memory.segments.size() == 0) {
return;
+ }
if (wasm->memory.segments.size() > WebLimitations::MaxDataSegments) {
std::cerr << "Some VMs may not accept this binary because it has a large "
<< "number of data segments. Run the limit-segments pass to "
@@ -418,10 +454,12 @@ uint32_t WasmBinaryWriter::getGlobalIndex(Name name) {
}
void WasmBinaryWriter::writeFunctionTableDeclaration() {
- if (!wasm->table.exists || wasm->table.imported())
+ if (!wasm->table.exists || wasm->table.imported()) {
return;
- if (debug)
+ }
+ if (debug) {
std::cerr << "== writeFunctionTableDeclaration" << std::endl;
+ }
auto start = startSection(BinaryConsts::Section::Table);
o << U32LEB(1); // Declare 1 table.
o << S32LEB(BinaryConsts::EncodedType::AnyFunc);
@@ -436,8 +474,9 @@ void WasmBinaryWriter::writeTableElements() {
if (!wasm->table.exists || wasm->table.segments.size() == 0) {
return;
}
- if (debug)
+ if (debug) {
std::cerr << "== writeTableElements" << std::endl;
+ }
auto start = startSection(BinaryConsts::Section::Element);
o << U32LEB(wasm->table.segments.size());
@@ -460,10 +499,12 @@ void WasmBinaryWriter::writeNames() {
hasContents = true;
getFunctionIndex(wasm->functions[0]->name); // generate mappedFunctions
}
- if (!hasContents)
+ if (!hasContents) {
return;
- if (debug)
+ }
+ if (debug) {
std::cerr << "== writeNames" << std::endl;
+ }
auto start = startSection(BinaryConsts::Section::User);
writeInlineString(BinaryConsts::UserSections::Name);
auto substart =
@@ -484,8 +525,9 @@ void WasmBinaryWriter::writeNames() {
}
void WasmBinaryWriter::writeSourceMapUrl() {
- if (debug)
+ if (debug) {
std::cerr << "== writeSourceMapUrl" << std::endl;
+ }
auto start = startSection(BinaryConsts::Section::User);
writeInlineString(BinaryConsts::UserSections::SourceMapUrl);
writeInlineString(sourceMapUrl.c_str());
@@ -509,8 +551,9 @@ void WasmBinaryWriter::initializeDebugInfo() {
void WasmBinaryWriter::writeSourceMapProlog() {
*sourceMap << "{\"version\":3,\"sources\":[";
for (size_t i = 0; i < wasm->debugInfoFileNames.size(); i++) {
- if (i > 0)
+ if (i > 0) {
*sourceMap << ",";
+ }
// TODO respect JSON string encoding, e.g. quotes and control chars.
*sourceMap << "\"" << wasm->debugInfoFileNames[i] << "\"";
}
@@ -695,20 +738,23 @@ void WasmBinaryWriter::emitBuffer(const char* data, size_t size) {
}
void WasmBinaryWriter::emitString(const char* str) {
- if (debug)
+ if (debug) {
std::cerr << "emitString " << str << std::endl;
+ }
emitBuffer(str, strlen(str) + 1);
}
void WasmBinaryWriter::finishUp() {
- if (debug)
+ if (debug) {
std::cerr << "finishUp" << std::endl;
+ }
// finish buffers
for (const auto& buffer : buffersToWrite) {
- if (debug)
+ if (debug) {
std::cerr << "writing buffer" << (int)buffer.data[0] << ","
<< (int)buffer.data[1] << " at " << o.size()
<< " and pointer is at " << buffer.pointerLocation << std::endl;
+ }
o.writeAt(buffer.pointerLocation, (uint32_t)o.size());
for (size_t i = 0; i < buffer.size; i++) {
o << (uint8_t)buffer.data[i];
@@ -727,8 +773,9 @@ void WasmBinaryBuilder::read() {
while (more()) {
uint32_t sectionCode = getU32LEB();
uint32_t payloadLen = getU32LEB();
- if (pos + payloadLen > input.size())
+ if (pos + payloadLen > input.size()) {
throwError("Section extends beyond end of input");
+ }
auto oldPos = pos;
@@ -840,129 +887,154 @@ void WasmBinaryBuilder::readUserSection(size_t payloadLen) {
}
uint8_t WasmBinaryBuilder::getInt8() {
- if (!more())
+ if (!more()) {
throwError("unexpected end of input");
- if (debug)
+ }
+ if (debug) {
std::cerr << "getInt8: " << (int)(uint8_t)input[pos] << " (at " << pos
<< ")" << std::endl;
+ }
return input[pos++];
}
uint16_t WasmBinaryBuilder::getInt16() {
- if (debug)
+ if (debug) {
std::cerr << "<==" << std::endl;
+ }
auto ret = uint16_t(getInt8());
ret |= uint16_t(getInt8()) << 8;
- if (debug)
+ if (debug) {
std::cerr << "getInt16: " << ret << "/0x" << std::hex << ret << std::dec
<< " ==>" << std::endl;
+ }
return ret;
}
uint32_t WasmBinaryBuilder::getInt32() {
- if (debug)
+ if (debug) {
std::cerr << "<==" << std::endl;
+ }
auto ret = uint32_t(getInt16());
ret |= uint32_t(getInt16()) << 16;
- if (debug)
+ if (debug) {
std::cerr << "getInt32: " << ret << "/0x" << std::hex << ret << std::dec
<< " ==>" << std::endl;
+ }
return ret;
}
uint64_t WasmBinaryBuilder::getInt64() {
- if (debug)
+ if (debug) {
std::cerr << "<==" << std::endl;
+ }
auto ret = uint64_t(getInt32());
ret |= uint64_t(getInt32()) << 32;
- if (debug)
+ if (debug) {
std::cerr << "getInt64: " << ret << "/0x" << std::hex << ret << std::dec
<< " ==>" << std::endl;
+ }
return ret;
}
uint8_t WasmBinaryBuilder::getLaneIndex(size_t lanes) {
- if (debug)
+ if (debug) {
std::cerr << "<==" << std::endl;
+ }
auto ret = getInt8();
- if (ret >= lanes)
+ if (ret >= lanes) {
throwError("Illegal lane index");
- if (debug)
+ }
+ if (debug) {
std::cerr << "getLaneIndex(" << lanes << "): " << ret << " ==>"
<< std::endl;
+ }
return ret;
}
Literal WasmBinaryBuilder::getFloat32Literal() {
- if (debug)
+ if (debug) {
std::cerr << "<==" << std::endl;
+ }
auto ret = Literal(getInt32());
ret = ret.castToF32();
- if (debug)
+ if (debug) {
std::cerr << "getFloat32: " << ret << " ==>" << std::endl;
+ }
return ret;
}
Literal WasmBinaryBuilder::getFloat64Literal() {
- if (debug)
+ if (debug) {
std::cerr << "<==" << std::endl;
+ }
auto ret = Literal(getInt64());
ret = ret.castToF64();
- if (debug)
+ if (debug) {
std::cerr << "getFloat64: " << ret << " ==>" << std::endl;
+ }
return ret;
}
Literal WasmBinaryBuilder::getVec128Literal() {
- if (debug)
+ if (debug) {
std::cerr << "<==" << std::endl;
+ }
std::array<uint8_t, 16> bytes;
for (auto i = 0; i < 16; ++i) {
bytes[i] = getInt8();
}
auto ret = Literal(bytes.data());
- if (debug)
+ if (debug) {
std::cerr << "getVec128: " << ret << " ==>" << std::endl;
+ }
return ret;
}
uint32_t WasmBinaryBuilder::getU32LEB() {
- if (debug)
+ if (debug) {
std::cerr << "<==" << std::endl;
+ }
U32LEB ret;
ret.read([&]() { return getInt8(); });
- if (debug)
+ if (debug) {
std::cerr << "getU32LEB: " << ret.value << " ==>" << std::endl;
+ }
return ret.value;
}
uint64_t WasmBinaryBuilder::getU64LEB() {
- if (debug)
+ if (debug) {
std::cerr << "<==" << std::endl;
+ }
U64LEB ret;
ret.read([&]() { return getInt8(); });
- if (debug)
+ if (debug) {
std::cerr << "getU64LEB: " << ret.value << " ==>" << std::endl;
+ }
return ret.value;
}
int32_t WasmBinaryBuilder::getS32LEB() {
- if (debug)
+ if (debug) {
std::cerr << "<==" << std::endl;
+ }
S32LEB ret;
ret.read([&]() { return (int8_t)getInt8(); });
- if (debug)
+ if (debug) {
std::cerr << "getS32LEB: " << ret.value << " ==>" << std::endl;
+ }
return ret.value;
}
int64_t WasmBinaryBuilder::getS64LEB() {
- if (debug)
+ if (debug) {
std::cerr << "<==" << std::endl;
+ }
S64LEB ret;
ret.read([&]() { return (int8_t)getInt8(); });
- if (debug)
+ if (debug) {
std::cerr << "getS64LEB: " << ret.value << " ==>" << std::endl;
+ }
return ret.value;
}
@@ -996,8 +1068,9 @@ Type WasmBinaryBuilder::getConcreteType() {
}
Name WasmBinaryBuilder::getInlineString() {
- if (debug)
+ if (debug) {
std::cerr << "<==" << std::endl;
+ }
auto len = getU32LEB();
std::string str;
for (size_t i = 0; i < len; i++) {
@@ -1009,61 +1082,71 @@ Name WasmBinaryBuilder::getInlineString() {
}
str = str + curr;
}
- if (debug)
+ if (debug) {
std::cerr << "getInlineString: " << str << " ==>" << std::endl;
+ }
return Name(str);
}
void WasmBinaryBuilder::verifyInt8(int8_t x) {
int8_t y = getInt8();
- if (x != y)
+ if (x != y) {
throwError("surprising value");
+ }
}
void WasmBinaryBuilder::verifyInt16(int16_t x) {
int16_t y = getInt16();
- if (x != y)
+ if (x != y) {
throwError("surprising value");
+ }
}
void WasmBinaryBuilder::verifyInt32(int32_t x) {
int32_t y = getInt32();
- if (x != y)
+ if (x != y) {
throwError("surprising value");
+ }
}
void WasmBinaryBuilder::verifyInt64(int64_t x) {
int64_t y = getInt64();
- if (x != y)
+ if (x != y) {
throwError("surprising value");
+ }
}
void WasmBinaryBuilder::ungetInt8() {
assert(pos > 0);
- if (debug)
+ if (debug) {
std::cerr << "ungetInt8 (at " << pos << ")" << std::endl;
+ }
pos--;
}
void WasmBinaryBuilder::readHeader() {
- if (debug)
+ if (debug) {
std::cerr << "== readHeader" << std::endl;
+ }
verifyInt32(BinaryConsts::Magic);
verifyInt32(BinaryConsts::Version);
}
void WasmBinaryBuilder::readStart() {
- if (debug)
+ if (debug) {
std::cerr << "== readStart" << std::endl;
+ }
startIndex = getU32LEB();
}
void WasmBinaryBuilder::readMemory() {
- if (debug)
+ if (debug) {
std::cerr << "== readMemory" << std::endl;
+ }
auto numMemories = getU32LEB();
- if (!numMemories)
+ if (!numMemories) {
return;
+ }
if (numMemories != 1) {
throwError("Must be exactly 1 memory");
}
@@ -1078,22 +1161,26 @@ void WasmBinaryBuilder::readMemory() {
}
void WasmBinaryBuilder::readSignatures() {
- if (debug)
+ if (debug) {
std::cerr << "== readSignatures" << std::endl;
+ }
size_t numTypes = getU32LEB();
- if (debug)
+ if (debug) {
std::cerr << "num: " << numTypes << std::endl;
+ }
for (size_t i = 0; i < numTypes; i++) {
- if (debug)
+ if (debug) {
std::cerr << "read one" << std::endl;
+ }
auto curr = make_unique<FunctionType>();
auto form = getS32LEB();
if (form != BinaryConsts::EncodedType::Func) {
throwError("bad signature form " + std::to_string(form));
}
size_t numParams = getU32LEB();
- if (debug)
+ if (debug) {
std::cerr << "num params: " << numParams << std::endl;
+ }
for (size_t j = 0; j < numParams; j++) {
curr->params.push_back(getConcreteType());
}
@@ -1126,25 +1213,30 @@ void WasmBinaryBuilder::getResizableLimits(Address& initial,
initial = getU32LEB();
bool hasMax = (flags & BinaryConsts::HasMaximum) != 0;
bool isShared = (flags & BinaryConsts::IsShared) != 0;
- if (isShared && !hasMax)
+ if (isShared && !hasMax) {
throwError("shared memory must have max size");
+ }
shared = isShared;
- if (hasMax)
+ if (hasMax) {
max = getU32LEB();
- else
+ } else {
max = defaultIfNoMax;
+ }
}
void WasmBinaryBuilder::readImports() {
- if (debug)
+ if (debug) {
std::cerr << "== readImports" << std::endl;
+ }
size_t num = getU32LEB();
- if (debug)
+ if (debug) {
std::cerr << "num: " << num << std::endl;
+ }
Builder builder(wasm);
for (size_t i = 0; i < num; i++) {
- if (debug)
+ if (debug) {
std::cerr << "read one" << std::endl;
+ }
auto module = getInlineString();
auto base = getInlineString();
auto kind = (ExternalKind)getU32LEB();
@@ -1176,14 +1268,16 @@ void WasmBinaryBuilder::readImports() {
wasm.table.name = Name(std::string("timport$") + std::to_string(i));
auto elementType = getS32LEB();
WASM_UNUSED(elementType);
- if (elementType != BinaryConsts::EncodedType::AnyFunc)
+ if (elementType != BinaryConsts::EncodedType::AnyFunc) {
throwError("Imported table type is not AnyFunc");
+ }
wasm.table.exists = true;
bool is_shared;
getResizableLimits(
wasm.table.initial, wasm.table.max, is_shared, Table::kUnlimitedSize);
- if (is_shared)
+ if (is_shared) {
throwError("Tables may not be shared");
+ }
break;
}
case ExternalKind::Memory: {
@@ -1228,14 +1322,17 @@ void WasmBinaryBuilder::requireFunctionContext(const char* error) {
}
void WasmBinaryBuilder::readFunctionSignatures() {
- if (debug)
+ if (debug) {
std::cerr << "== readFunctionSignatures" << std::endl;
+ }
size_t num = getU32LEB();
- if (debug)
+ if (debug) {
std::cerr << "num: " << num << std::endl;
+ }
for (size_t i = 0; i < num; i++) {
- if (debug)
+ if (debug) {
std::cerr << "read one" << std::endl;
+ }
auto index = getU32LEB();
if (index >= wasm.functionTypes.size()) {
throwError("invalid function type index for function");
@@ -1245,15 +1342,17 @@ void WasmBinaryBuilder::readFunctionSignatures() {
}
void WasmBinaryBuilder::readFunctions() {
- if (debug)
+ if (debug) {
std::cerr << "== readFunctions" << std::endl;
+ }
size_t total = getU32LEB();
if (total != functionTypes.size()) {
throwError("invalid function section size, must equal types");
}
for (size_t i = 0; i < total; i++) {
- if (debug)
+ if (debug) {
std::cerr << "read one at " << pos << std::endl;
+ }
size_t size = getU32LEB();
if (size == 0) {
throwError("empty function size");
@@ -1267,8 +1366,9 @@ void WasmBinaryBuilder::readFunctions() {
readNextDebugLocation();
auto type = functionTypes[i];
- if (debug)
+ if (debug) {
std::cerr << "reading " << i << std::endl;
+ }
func->type = type->name;
func->result = type->result;
for (size_t j = 0; j < type->params.size(); j++) {
@@ -1286,8 +1386,9 @@ void WasmBinaryBuilder::readFunctions() {
std::swap(func->prologLocation, debugLocation);
{
// process the function body
- if (debug)
+ if (debug) {
std::cerr << "processing function: " << i << std::endl;
+ }
nextLabel = 0;
debugLocation.clear();
willBeIgnored = false;
@@ -1312,20 +1413,24 @@ void WasmBinaryBuilder::readFunctions() {
debugLocation.clear();
functions.push_back(func);
}
- if (debug)
+ if (debug) {
std::cerr << " end function bodies" << std::endl;
+ }
}
void WasmBinaryBuilder::readExports() {
- if (debug)
+ if (debug) {
std::cerr << "== readExports" << std::endl;
+ }
size_t num = getU32LEB();
- if (debug)
+ if (debug) {
std::cerr << "num: " << num << std::endl;
+ }
std::set<Name> names;
for (size_t i = 0; i < num; i++) {
- if (debug)
+ if (debug) {
std::cerr << "read one" << std::endl;
+ }
auto curr = new Export;
curr->name = getInlineString();
if (names.count(curr->name) > 0) {
@@ -1344,8 +1449,9 @@ static int32_t readBase64VLQ(std::istream& in) {
uint32_t shift = 0;
while (1) {
auto ch = in.get();
- if (ch == EOF)
+ if (ch == EOF) {
throw MapParseException("unexpected EOF in the middle of VLQ");
+ }
if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch < 'g')) {
// last number digit
uint32_t digit = ch < 'a' ? ch - 'A' : ch - 'a' + 26;
@@ -1365,17 +1471,20 @@ static int32_t readBase64VLQ(std::istream& in) {
}
void WasmBinaryBuilder::readSourceMapHeader() {
- if (!sourceMap)
+ if (!sourceMap) {
return;
+ }
auto skipWhitespace = [&]() {
- while (sourceMap->peek() == ' ' || sourceMap->peek() == '\n')
+ while (sourceMap->peek() == ' ' || sourceMap->peek() == '\n') {
sourceMap->get();
+ }
};
auto maybeReadChar = [&](char expected) {
- if (sourceMap->peek() != expected)
+ if (sourceMap->peek() != expected) {
return false;
+ }
sourceMap->get();
return true;
};
@@ -1394,13 +1503,15 @@ void WasmBinaryBuilder::readSourceMapHeader() {
size_t pos;
while (1) {
int ch = sourceMap->get();
- if (ch == EOF)
+ if (ch == EOF) {
return false;
+ }
if (ch == '\"') {
if (matching) {
// we matched a terminating quote.
- if (pos == len)
+ if (pos == len) {
break;
+ }
matching = false;
} else {
matching = true;
@@ -1428,8 +1539,9 @@ void WasmBinaryBuilder::readSourceMapHeader() {
if (ch == EOF) {
throw MapParseException("unexpected EOF in the middle of string");
}
- if (ch == '\"')
+ if (ch == '\"') {
break;
+ }
vec.push_back(ch);
}
}
@@ -1473,8 +1585,9 @@ void WasmBinaryBuilder::readSourceMapHeader() {
}
void WasmBinaryBuilder::readNextDebugLocation() {
- if (!sourceMap)
+ if (!sourceMap) {
return;
+ }
while (nextDebugLocation.first && nextDebugLocation.first <= pos) {
if (nextDebugLocation.first < pos) {
@@ -1523,18 +1636,22 @@ Expression* WasmBinaryBuilder::readExpression() {
}
void WasmBinaryBuilder::readGlobals() {
- if (debug)
+ if (debug) {
std::cerr << "== readGlobals" << std::endl;
+ }
size_t num = getU32LEB();
- if (debug)
+ if (debug) {
std::cerr << "num: " << num << std::endl;
+ }
for (size_t i = 0; i < num; i++) {
- if (debug)
+ if (debug) {
std::cerr << "read one" << std::endl;
+ }
auto type = getConcreteType();
auto mutable_ = getU32LEB();
- if (mutable_ & ~1)
+ if (mutable_ & ~1) {
throwError("Global mutability must be 0 or 1");
+ }
auto* init = readExpression();
wasm.addGlobal(
Builder::makeGlobal("global$" + std::to_string(i),
@@ -1545,16 +1662,18 @@ void WasmBinaryBuilder::readGlobals() {
}
void WasmBinaryBuilder::processExpressions() {
- if (debug)
+ if (debug) {
std::cerr << "== processExpressions" << std::endl;
+ }
unreachableInTheWasmSense = false;
while (1) {
Expression* curr;
auto ret = readExpression(curr);
if (!curr) {
lastSeparator = ret;
- if (debug)
+ if (debug) {
std::cerr << "== processExpressions finished" << std::endl;
+ }
return;
}
expressionStack.push_back(curr);
@@ -1567,13 +1686,15 @@ void WasmBinaryBuilder::processExpressions() {
if (pos == endOfFunction) {
throwError("Reached function end without seeing End opcode");
}
- if (!more())
+ if (!more()) {
throwError("unexpected end of input");
+ }
auto peek = input[pos];
if (peek == BinaryConsts::End || peek == BinaryConsts::Else) {
- if (debug)
+ if (debug) {
std::cerr << "== processExpressions finished with unreachable"
<< std::endl;
+ }
readNextDebugLocation();
lastSeparator = BinaryConsts::ASTNodes(peek);
pos++;
@@ -1587,8 +1708,9 @@ void WasmBinaryBuilder::processExpressions() {
}
void WasmBinaryBuilder::skipUnreachableCode() {
- if (debug)
+ if (debug) {
std::cerr << "== skipUnreachableCode" << std::endl;
+ }
// preserve the stack, and restore it. it contains the instruction that made
// us unreachable, and we can ignore anything after it. things after it may
// pop, we want to undo that
@@ -1608,8 +1730,9 @@ void WasmBinaryBuilder::skipUnreachableCode() {
Expression* curr;
auto ret = readExpression(curr);
if (!curr) {
- if (debug)
+ if (debug) {
std::cerr << "== skipUnreachableCode finished" << std::endl;
+ }
lastSeparator = ret;
unreachableInTheWasmSense = false;
willBeIgnored = before;
@@ -1621,15 +1744,17 @@ void WasmBinaryBuilder::skipUnreachableCode() {
}
Expression* WasmBinaryBuilder::popExpression() {
- if (debug)
+ if (debug) {
std::cerr << "== popExpression" << std::endl;
+ }
if (expressionStack.empty()) {
if (unreachableInTheWasmSense) {
// in unreachable code, trying to pop past the polymorphic stack
// area results in receiving unreachables
- if (debug)
+ if (debug) {
std::cerr << "== popping unreachable from polymorphic stack"
<< std::endl;
+ }
return allocator.alloc<Unreachable>();
}
throwError(
@@ -1644,8 +1769,9 @@ Expression* WasmBinaryBuilder::popExpression() {
Expression* WasmBinaryBuilder::popNonVoidExpression() {
auto* ret = popExpression();
- if (ret->type != none)
+ if (ret->type != none) {
return ret;
+ }
// we found a void, so this is stacky code that we must handle carefully
Builder builder(wasm);
// add elements until we find a non-void
@@ -1654,8 +1780,9 @@ Expression* WasmBinaryBuilder::popNonVoidExpression() {
while (1) {
auto* curr = popExpression();
expressions.push_back(curr);
- if (curr->type != none)
+ if (curr->type != none) {
break;
+ }
}
auto* block = builder.makeBlock();
while (!expressions.empty()) {
@@ -1686,8 +1813,9 @@ Name WasmBinaryBuilder::getGlobalName(Index index) {
ModuleUtils::iterImportedGlobals(wasm, add);
ModuleUtils::iterDefinedGlobals(wasm, add);
}
- if (index == Index(-1))
+ if (index == Index(-1)) {
return Name("null"); // just a force-rebuild
+ }
if (mappedGlobals.count(index) == 0) {
throwError("bad global index");
}
@@ -1755,15 +1883,17 @@ void WasmBinaryBuilder::processFunctions() {
}
void WasmBinaryBuilder::readDataCount() {
- if (debug)
+ if (debug) {
std::cerr << "== readDataCount" << std::endl;
+ }
hasDataCount = true;
dataCount = getU32LEB();
}
void WasmBinaryBuilder::readDataSegments() {
- if (debug)
+ if (debug) {
std::cerr << "== readDataSegments" << std::endl;
+ }
auto num = getU32LEB();
for (size_t i = 0; i < num; i++) {
Memory::Segment curr;
@@ -1792,34 +1922,42 @@ void WasmBinaryBuilder::readDataSegments() {
}
void WasmBinaryBuilder::readFunctionTableDeclaration() {
- if (debug)
+ if (debug) {
std::cerr << "== readFunctionTableDeclaration" << std::endl;
+ }
auto numTables = getU32LEB();
- if (numTables != 1)
+ if (numTables != 1) {
throwError("Only 1 table definition allowed in MVP");
- if (wasm.table.exists)
+ }
+ if (wasm.table.exists) {
throwError("Table cannot be both imported and defined");
+ }
wasm.table.exists = true;
auto elemType = getS32LEB();
- if (elemType != BinaryConsts::EncodedType::AnyFunc)
+ if (elemType != BinaryConsts::EncodedType::AnyFunc) {
throwError("ElementType must be AnyFunc in MVP");
+ }
bool is_shared;
getResizableLimits(
wasm.table.initial, wasm.table.max, is_shared, Table::kUnlimitedSize);
- if (is_shared)
+ if (is_shared) {
throwError("Tables may not be shared");
+ }
}
void WasmBinaryBuilder::readTableElements() {
- if (debug)
+ if (debug) {
std::cerr << "== readTableElements" << std::endl;
+ }
auto numSegments = getU32LEB();
- if (numSegments >= Table::kMaxSize)
+ if (numSegments >= Table::kMaxSize) {
throwError("Too many segments");
+ }
for (size_t i = 0; i < numSegments; i++) {
auto tableIndex = getU32LEB();
- if (tableIndex != 0)
+ if (tableIndex != 0) {
throwError("Table elements must refer to table 0 in MVP");
+ }
wasm.table.segments.emplace_back(readExpression());
auto& indexSegment = functionTable[i];
@@ -1868,8 +2006,9 @@ static void escapeName(Name& name) {
}
void WasmBinaryBuilder::readNames(size_t payloadLen) {
- if (debug)
+ if (debug) {
std::cerr << "== readNames" << std::endl;
+ }
auto sectionPos = pos;
while (pos < sectionPos + payloadLen) {
auto nameType = getU32LEB();
@@ -1958,16 +2097,18 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) {
if (pos == endOfFunction) {
throwError("Reached function end without seeing End opcode");
}
- if (debug)
+ if (debug) {
std::cerr << "zz recurse into " << ++depth << " at " << pos << std::endl;
+ }
readNextDebugLocation();
std::set<Function::DebugLocation> currDebugLocation;
if (debugLocation.size()) {
currDebugLocation.insert(*debugLocation.begin());
}
uint8_t code = getInt8();
- if (debug)
+ if (debug) {
std::cerr << "readExpression seeing " << (int)code << std::endl;
+ }
switch (code) {
case BinaryConsts::Block:
visitBlock((curr = allocator.alloc<Block>())->cast<Block>());
@@ -2028,76 +2169,103 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) {
break;
case BinaryConsts::AtomicPrefix: {
code = static_cast<uint8_t>(getU32LEB());
- if (maybeVisitLoad(curr, code, /*isAtomic=*/true))
+ if (maybeVisitLoad(curr, code, /*isAtomic=*/true)) {
break;
- if (maybeVisitStore(curr, code, /*isAtomic=*/true))
+ }
+ if (maybeVisitStore(curr, code, /*isAtomic=*/true)) {
break;
- if (maybeVisitAtomicRMW(curr, code))
+ }
+ if (maybeVisitAtomicRMW(curr, code)) {
break;
- if (maybeVisitAtomicCmpxchg(curr, code))
+ }
+ if (maybeVisitAtomicCmpxchg(curr, code)) {
break;
- if (maybeVisitAtomicWait(curr, code))
+ }
+ if (maybeVisitAtomicWait(curr, code)) {
break;
- if (maybeVisitAtomicNotify(curr, code))
+ }
+ if (maybeVisitAtomicNotify(curr, code)) {
break;
+ }
throwError("invalid code after atomic prefix: " + std::to_string(code));
break;
}
case BinaryConsts::MiscPrefix: {
auto opcode = getU32LEB();
- if (maybeVisitTruncSat(curr, opcode))
+ if (maybeVisitTruncSat(curr, opcode)) {
break;
- if (maybeVisitMemoryInit(curr, opcode))
+ }
+ if (maybeVisitMemoryInit(curr, opcode)) {
break;
- if (maybeVisitDataDrop(curr, opcode))
+ }
+ if (maybeVisitDataDrop(curr, opcode)) {
break;
- if (maybeVisitMemoryCopy(curr, opcode))
+ }
+ if (maybeVisitMemoryCopy(curr, opcode)) {
break;
- if (maybeVisitMemoryFill(curr, opcode))
+ }
+ if (maybeVisitMemoryFill(curr, opcode)) {
break;
+ }
throwError("invalid code after nontrapping float-to-int prefix: " +
std::to_string(opcode));
break;
}
case BinaryConsts::SIMDPrefix: {
auto opcode = getU32LEB();
- if (maybeVisitSIMDBinary(curr, opcode))
+ if (maybeVisitSIMDBinary(curr, opcode)) {
break;
- if (maybeVisitSIMDUnary(curr, opcode))
+ }
+ if (maybeVisitSIMDUnary(curr, opcode)) {
break;
- if (maybeVisitSIMDConst(curr, opcode))
+ }
+ if (maybeVisitSIMDConst(curr, opcode)) {
break;
- if (maybeVisitSIMDLoad(curr, opcode))
+ }
+ if (maybeVisitSIMDLoad(curr, opcode)) {
break;
- if (maybeVisitSIMDStore(curr, opcode))
+ }
+ if (maybeVisitSIMDStore(curr, opcode)) {
break;
- if (maybeVisitSIMDExtract(curr, opcode))
+ }
+ if (maybeVisitSIMDExtract(curr, opcode)) {
break;
- if (maybeVisitSIMDReplace(curr, opcode))
+ }
+ if (maybeVisitSIMDReplace(curr, opcode)) {
break;
- if (maybeVisitSIMDShuffle(curr, opcode))
+ }
+ if (maybeVisitSIMDShuffle(curr, opcode)) {
break;
- if (maybeVisitSIMDBitselect(curr, opcode))
+ }
+ if (maybeVisitSIMDBitselect(curr, opcode)) {
break;
- if (maybeVisitSIMDShift(curr, opcode))
+ }
+ if (maybeVisitSIMDShift(curr, opcode)) {
break;
+ }
throwError("invalid code after SIMD prefix: " + std::to_string(opcode));
break;
}
default: {
// otherwise, the code is a subcode TODO: optimize
- if (maybeVisitBinary(curr, code))
+ if (maybeVisitBinary(curr, code)) {
break;
- if (maybeVisitUnary(curr, code))
+ }
+ if (maybeVisitUnary(curr, code)) {
break;
- if (maybeVisitConst(curr, code))
+ }
+ if (maybeVisitConst(curr, code)) {
break;
- if (maybeVisitLoad(curr, code, /*isAtomic=*/false))
+ }
+ if (maybeVisitLoad(curr, code, /*isAtomic=*/false)) {
break;
- if (maybeVisitStore(curr, code, /*isAtomic=*/false))
+ }
+ if (maybeVisitStore(curr, code, /*isAtomic=*/false)) {
break;
- if (maybeVisitHost(curr, code))
+ }
+ if (maybeVisitHost(curr, code)) {
break;
+ }
throwError("bad node code " + std::to_string(code));
break;
}
@@ -2105,8 +2273,9 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) {
if (curr && currDebugLocation.size()) {
currFunction->debugLocations[curr] = *currDebugLocation.begin();
}
- if (debug)
+ if (debug) {
std::cerr << "zz recurse from " << depth-- << " at " << pos << std::endl;
+ }
return BinaryConsts::ASTNodes(code);
}
@@ -2153,8 +2322,9 @@ void WasmBinaryBuilder::pushBlockElements(Block* curr,
}
void WasmBinaryBuilder::visitBlock(Block* curr) {
- if (debug)
+ if (debug) {
std::cerr << "zz node: Block" << std::endl;
+ }
// special-case Block and de-recurse nested blocks in their first position, as
// that is a common pattern that can be very highly nested.
std::vector<Block*> stack;
@@ -2228,8 +2398,9 @@ Expression* WasmBinaryBuilder::getBlockOrSingleton(Type type) {
}
void WasmBinaryBuilder::visitIf(If* curr) {
- if (debug)
+ if (debug) {
std::cerr << "zz node: If" << std::endl;
+ }
curr->type = getType();
curr->condition = popNonVoidExpression();
curr->ifTrue = getBlockOrSingleton(curr->type);
@@ -2243,8 +2414,9 @@ void WasmBinaryBuilder::visitIf(If* curr) {
}
void WasmBinaryBuilder::visitLoop(Loop* curr) {
- if (debug)
+ if (debug) {
std::cerr << "zz node: Loop" << std::endl;
+ }
curr->type = getType();
curr->name = getNextLabel();
breakStack.push_back({curr->name, 0});
@@ -2274,8 +2446,9 @@ void WasmBinaryBuilder::visitLoop(Loop* curr) {
WasmBinaryBuilder::BreakTarget
WasmBinaryBuilder::getBreakTarget(int32_t offset) {
- if (debug)
+ if (debug) {
std::cerr << "getBreakTarget " << offset << std::endl;
+ }
if (breakStack.size() < 1 + size_t(offset)) {
throwError("bad breakindex (low)");
}
@@ -2283,9 +2456,10 @@ WasmBinaryBuilder::getBreakTarget(int32_t offset) {
if (index >= breakStack.size()) {
throwError("bad breakindex (high)");
}
- if (debug)
+ if (debug) {
std::cerr << "breaktarget " << breakStack[index].name << " arity "
<< breakStack[index].arity << std::endl;
+ }
auto& ret = breakStack[index];
// if the break is in literally unreachable code, then we will not emit it
// anyhow, so do not note that the target has breaks to it
@@ -2296,39 +2470,47 @@ WasmBinaryBuilder::getBreakTarget(int32_t offset) {
}
void WasmBinaryBuilder::visitBreak(Break* curr, uint8_t code) {
- if (debug)
+ if (debug) {
std::cerr << "zz node: Break, code " << int32_t(code) << std::endl;
+ }
BreakTarget target = getBreakTarget(getU32LEB());
curr->name = target.name;
- if (code == BinaryConsts::BrIf)
+ if (code == BinaryConsts::BrIf) {
curr->condition = popNonVoidExpression();
- if (target.arity)
+ }
+ if (target.arity) {
curr->value = popNonVoidExpression();
+ }
curr->finalize();
}
void WasmBinaryBuilder::visitSwitch(Switch* curr) {
- if (debug)
+ if (debug) {
std::cerr << "zz node: Switch" << std::endl;
+ }
curr->condition = popNonVoidExpression();
auto numTargets = getU32LEB();
- if (debug)
+ if (debug) {
std::cerr << "targets: " << numTargets << std::endl;
+ }
for (size_t i = 0; i < numTargets; i++) {
curr->targets.push_back(getBreakTarget(getU32LEB()).name);
}
auto defaultTarget = getBreakTarget(getU32LEB());
curr->default_ = defaultTarget.name;
- if (debug)
+ if (debug) {
std::cerr << "default: " << curr->default_ << std::endl;
- if (defaultTarget.arity)
+ }
+ if (defaultTarget.arity) {
curr->value = popNonVoidExpression();
+ }
curr->finalize();
}
void WasmBinaryBuilder::visitCall(Call* curr) {
- if (debug)
+ if (debug) {
std::cerr << "zz node: Call" << std::endl;
+ }
auto index = getU32LEB();
FunctionType* type;
if (index < functionImports.size()) {
@@ -2353,16 +2535,18 @@ void WasmBinaryBuilder::visitCall(Call* curr) {
}
void WasmBinaryBuilder::visitCallIndirect(CallIndirect* curr) {
- if (debug)
+ if (debug) {
std::cerr << "zz node: CallIndirect" << std::endl;
+ }
auto index = getU32LEB();
if (index >= wasm.functionTypes.size()) {
throwError("bad call_indirect function index");
}
auto* fullType = wasm.functionTypes[index].get();
auto reserved = getU32LEB();
- if (reserved != 0)
+ if (reserved != 0) {
throwError("Invalid flags field in call_indirect");
+ }
curr->fullType = fullType->name;
auto num = fullType->params.size();
curr->operands.resize(num);
@@ -2375,8 +2559,9 @@ void WasmBinaryBuilder::visitCallIndirect(CallIndirect* curr) {
}
void WasmBinaryBuilder::visitGetLocal(GetLocal* curr) {
- if (debug)
+ if (debug) {
std::cerr << "zz node: GetLocal " << pos << std::endl;
+ }
requireFunctionContext("local.get");
curr->index = getU32LEB();
if (curr->index >= currFunction->getNumLocals()) {
@@ -2387,8 +2572,9 @@ void WasmBinaryBuilder::visitGetLocal(GetLocal* curr) {
}
void WasmBinaryBuilder::visitSetLocal(SetLocal* curr, uint8_t code) {
- if (debug)
+ if (debug) {
std::cerr << "zz node: Set|TeeLocal" << std::endl;
+ }
requireFunctionContext("local.set outside of function");
curr->index = getU32LEB();
if (curr->index >= currFunction->getNumLocals()) {
@@ -2401,16 +2587,18 @@ void WasmBinaryBuilder::visitSetLocal(SetLocal* curr, uint8_t code) {
}
void WasmBinaryBuilder::visitGetGlobal(GetGlobal* curr) {
- if (debug)
+ if (debug) {
std::cerr << "zz node: GetGlobal " << pos << std::endl;
+ }
auto index = getU32LEB();
curr->name = getGlobalName(index);
curr->type = wasm.getGlobal(curr->name)->type;
}
void WasmBinaryBuilder::visitSetGlobal(SetGlobal* curr) {
- if (debug)
+ if (debug) {
std::cerr << "zz node: SetGlobal" << std::endl;
+ }
auto index = getU32LEB();
curr->name = getGlobalName(index);
curr->value = popNonVoidExpression();
@@ -2419,8 +2607,9 @@ void WasmBinaryBuilder::visitSetGlobal(SetGlobal* curr) {
void WasmBinaryBuilder::readMemoryAccess(Address& alignment, Address& offset) {
auto rawAlignment = getU32LEB();
- if (rawAlignment > 4)
+ if (rawAlignment > 4) {
throwError("Alignment must be of a reasonable size");
+ }
alignment = Pow2(rawAlignment);
offset = getU32LEB();
}
@@ -2514,8 +2703,9 @@ bool WasmBinaryBuilder::maybeVisitLoad(Expression*& out,
default:
return false;
}
- if (debug)
+ if (debug) {
std::cerr << "zz node: Load" << std::endl;
+ }
} else {
switch (code) {
case BinaryConsts::I32AtomicLoad8U:
@@ -2557,8 +2747,9 @@ bool WasmBinaryBuilder::maybeVisitLoad(Expression*& out,
return false;
}
curr->signed_ = false;
- if (debug)
+ if (debug) {
std::cerr << "zz node: AtomicLoad" << std::endl;
+ }
}
curr->isAtomic = isAtomic;
@@ -2666,8 +2857,9 @@ bool WasmBinaryBuilder::maybeVisitStore(Expression*& out,
}
curr->isAtomic = isAtomic;
- if (debug)
+ if (debug) {
std::cerr << "zz node: Store" << std::endl;
+ }
readMemoryAccess(curr->align, curr->offset);
curr->value = popNonVoidExpression();
curr->ptr = popNonVoidExpression();
@@ -2678,8 +2870,9 @@ bool WasmBinaryBuilder::maybeVisitStore(Expression*& out,
bool WasmBinaryBuilder::maybeVisitAtomicRMW(Expression*& out, uint8_t code) {
if (code < BinaryConsts::AtomicRMWOps_Begin ||
- code > BinaryConsts::AtomicRMWOps_End)
+ code > BinaryConsts::AtomicRMWOps_End) {
return false;
+ }
auto* curr = allocator.alloc<AtomicRMW>();
// Set curr to the given opcode, type and size.
@@ -2725,12 +2918,14 @@ bool WasmBinaryBuilder::maybeVisitAtomicRMW(Expression*& out, uint8_t code) {
#undef SET_FOR_OP
#undef SET
- if (debug)
+ if (debug) {
std::cerr << "zz node: AtomicRMW" << std::endl;
+ }
Address readAlign;
readMemoryAccess(readAlign, curr->offset);
- if (readAlign != curr->bytes)
+ if (readAlign != curr->bytes) {
throwError("Align of AtomicRMW must match size");
+ }
curr->value = popNonVoidExpression();
curr->ptr = popNonVoidExpression();
curr->finalize();
@@ -2741,8 +2936,9 @@ bool WasmBinaryBuilder::maybeVisitAtomicRMW(Expression*& out, uint8_t code) {
bool WasmBinaryBuilder::maybeVisitAtomicCmpxchg(Expression*& out,
uint8_t code) {
if (code < BinaryConsts::AtomicCmpxchgOps_Begin ||
- code > BinaryConsts::AtomicCmpxchgOps_End)
+ code > BinaryConsts::AtomicCmpxchgOps_End) {
return false;
+ }
auto* curr = allocator.alloc<AtomicCmpxchg>();
// Set curr to the given type and size.
@@ -2776,12 +2972,14 @@ bool WasmBinaryBuilder::maybeVisitAtomicCmpxchg(Expression*& out,
WASM_UNREACHABLE();
}
- if (debug)
+ if (debug) {
std::cerr << "zz node: AtomicCmpxchg" << std::endl;
+ }
Address readAlign;
readMemoryAccess(readAlign, curr->offset);
- if (readAlign != curr->bytes)
+ if (readAlign != curr->bytes) {
throwError("Align of AtomicCpxchg must match size");
+ }
curr->replacement = popNonVoidExpression();
curr->expected = popNonVoidExpression();
curr->ptr = popNonVoidExpression();
@@ -2791,8 +2989,10 @@ bool WasmBinaryBuilder::maybeVisitAtomicCmpxchg(Expression*& out,
}
bool WasmBinaryBuilder::maybeVisitAtomicWait(Expression*& out, uint8_t code) {
- if (code < BinaryConsts::I32AtomicWait || code > BinaryConsts::I64AtomicWait)
+ if (code < BinaryConsts::I32AtomicWait ||
+ code > BinaryConsts::I64AtomicWait) {
return false;
+ }
auto* curr = allocator.alloc<AtomicWait>();
switch (code) {
@@ -2806,34 +3006,39 @@ bool WasmBinaryBuilder::maybeVisitAtomicWait(Expression*& out, uint8_t code) {
WASM_UNREACHABLE();
}
curr->type = i32;
- if (debug)
+ if (debug) {
std::cerr << "zz node: AtomicWait" << std::endl;
+ }
curr->timeout = popNonVoidExpression();
curr->expected = popNonVoidExpression();
curr->ptr = popNonVoidExpression();
Address readAlign;
readMemoryAccess(readAlign, curr->offset);
- if (readAlign != getTypeSize(curr->expectedType))
+ if (readAlign != getTypeSize(curr->expectedType)) {
throwError("Align of AtomicWait must match size");
+ }
curr->finalize();
out = curr;
return true;
}
bool WasmBinaryBuilder::maybeVisitAtomicNotify(Expression*& out, uint8_t code) {
- if (code != BinaryConsts::AtomicNotify)
+ if (code != BinaryConsts::AtomicNotify) {
return false;
+ }
auto* curr = allocator.alloc<AtomicNotify>();
- if (debug)
+ if (debug) {
std::cerr << "zz node: AtomicNotify" << std::endl;
+ }
curr->type = i32;
curr->notifyCount = popNonVoidExpression();
curr->ptr = popNonVoidExpression();
Address readAlign;
readMemoryAccess(readAlign, curr->offset);
- if (readAlign != getTypeSize(curr->type))
+ if (readAlign != getTypeSize(curr->type)) {
throwError("Align of AtomicNotify must match size");
+ }
curr->finalize();
out = curr;
return true;
@@ -2841,8 +3046,9 @@ bool WasmBinaryBuilder::maybeVisitAtomicNotify(Expression*& out, uint8_t code) {
bool WasmBinaryBuilder::maybeVisitConst(Expression*& out, uint8_t code) {
Const* curr;
- if (debug)
+ if (debug) {
std::cerr << "zz node: Const, code " << code << std::endl;
+ }
switch (code) {
case BinaryConsts::I32Const:
curr = allocator.alloc<Const>();
@@ -3089,8 +3295,9 @@ bool WasmBinaryBuilder::maybeVisitUnary(Expression*& out, uint8_t code) {
default:
return false;
}
- if (debug)
+ if (debug) {
std::cerr << "zz node: Unary" << std::endl;
+ }
curr->value = popNonVoidExpression();
curr->finalize();
out = curr;
@@ -3135,8 +3342,9 @@ bool WasmBinaryBuilder::maybeVisitTruncSat(Expression*& out, uint32_t code) {
default:
return false;
}
- if (debug)
+ if (debug) {
std::cerr << "zz node: Unary (nontrapping float-to-int)" << std::endl;
+ }
curr->value = popNonVoidExpression();
curr->finalize();
out = curr;
@@ -3270,8 +3478,9 @@ bool WasmBinaryBuilder::maybeVisitBinary(Expression*& out, uint8_t code) {
default:
return false;
}
- if (debug)
+ if (debug) {
std::cerr << "zz node: Binary" << std::endl;
+ }
curr->right = popNonVoidExpression();
curr->left = popNonVoidExpression();
curr->finalize();
@@ -3592,8 +3801,9 @@ bool WasmBinaryBuilder::maybeVisitSIMDBinary(Expression*& out, uint32_t code) {
default:
return false;
}
- if (debug)
+ if (debug) {
std::cerr << "zz node: Binary" << std::endl;
+ }
curr->right = popNonVoidExpression();
curr->left = popNonVoidExpression();
curr->finalize();
@@ -3972,8 +4182,9 @@ bool WasmBinaryBuilder::maybeVisitSIMDShift(Expression*& out, uint32_t code) {
}
void WasmBinaryBuilder::visitSelect(Select* curr) {
- if (debug)
+ if (debug) {
std::cerr << "zz node: Select" << std::endl;
+ }
curr->condition = popNonVoidExpression();
curr->ifFalse = popNonVoidExpression();
curr->ifTrue = popNonVoidExpression();
@@ -3981,8 +4192,9 @@ void WasmBinaryBuilder::visitSelect(Select* curr) {
}
void WasmBinaryBuilder::visitReturn(Return* curr) {
- if (debug)
+ if (debug) {
std::cerr << "zz node: Return" << std::endl;
+ }
requireFunctionContext("return");
if (currFunction->result != none) {
curr->value = popNonVoidExpression();
@@ -4008,29 +4220,34 @@ bool WasmBinaryBuilder::maybeVisitHost(Expression*& out, uint8_t code) {
default:
return false;
}
- if (debug)
+ if (debug) {
std::cerr << "zz node: Host" << std::endl;
+ }
auto reserved = getU32LEB();
- if (reserved != 0)
+ if (reserved != 0) {
throwError("Invalid reserved field on grow_memory/current_memory");
+ }
curr->finalize();
out = curr;
return true;
}
void WasmBinaryBuilder::visitNop(Nop* curr) {
- if (debug)
+ if (debug) {
std::cerr << "zz node: Nop" << std::endl;
+ }
}
void WasmBinaryBuilder::visitUnreachable(Unreachable* curr) {
- if (debug)
+ if (debug) {
std::cerr << "zz node: Unreachable" << std::endl;
+ }
}
void WasmBinaryBuilder::visitDrop(Drop* curr) {
- if (debug)
+ if (debug) {
std::cerr << "zz node: Drop" << std::endl;
+ }
curr->value = popNonVoidExpression();
curr->finalize();
}
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp
index a6a84a974..453780720 100644
--- a/src/wasm/wasm-emscripten.cpp
+++ b/src/wasm/wasm-emscripten.cpp
@@ -86,8 +86,9 @@ Expression* EmscriptenGlueGenerator::generateLoadStackPointer() {
/* type =*/i32);
}
Global* stackPointer = getStackPointerGlobal();
- if (!stackPointer)
+ if (!stackPointer) {
Fatal() << "stack pointer global not found";
+ }
return builder.makeGetGlobal(stackPointer->name, i32);
}
@@ -103,8 +104,9 @@ EmscriptenGlueGenerator::generateStoreStackPointer(Expression* value) {
/* type =*/i32);
}
Global* stackPointer = getStackPointerGlobal();
- if (!stackPointer)
+ if (!stackPointer) {
Fatal() << "stack pointer global not found";
+ }
return builder.makeSetGlobal(stackPointer->name, value);
}
@@ -312,8 +314,9 @@ Function* EmscriptenGlueGenerator::generateMemoryGrowthFunction() {
void EmscriptenGlueGenerator::generateStackInitialization(Address addr) {
auto* stackPointer = getStackPointerGlobal();
assert(!stackPointer->imported());
- if (!stackPointer->init || !stackPointer->init->is<Const>())
+ if (!stackPointer->init || !stackPointer->init->is<Const>()) {
Fatal() << "stack pointer global is not assignable";
+ }
stackPointer->init->cast<Const>()->value = Literal(int32_t(addr));
}
@@ -322,8 +325,9 @@ inline void exportFunction(Module& wasm, Name name, bool must_export) {
assert(!must_export);
return;
}
- if (wasm.getExportOrNull(name))
+ if (wasm.getExportOrNull(name)) {
return; // Already exported
+ }
auto exp = new Export;
exp->name = exp->value = name;
exp->kind = ExternalKind::Function;
@@ -350,8 +354,9 @@ void EmscriptenGlueGenerator::generateDynCallThunks() {
std::vector<NameType> params;
params.emplace_back("fptr", i32); // function pointer param
int p = 0;
- for (const auto& ty : funcType->params)
+ for (const auto& ty : funcType->params) {
params.emplace_back(std::to_string(p++), ty);
+ }
Function* f =
builder.makeFunction(name, std::move(params), funcType->result, {});
Expression* fptr = builder.makeGetLocal(0, i32);
@@ -373,8 +378,9 @@ struct RemoveStackPointer : public PostWalker<RemoveStackPointer> {
void visitGetGlobal(GetGlobal* curr) {
if (getModule()->getGlobalOrNull(curr->name) == stackPointer) {
needStackSave = true;
- if (!builder)
+ if (!builder) {
builder = make_unique<Builder>(*getModule());
+ }
replaceCurrent(builder->makeCall(STACK_SAVE, {}, i32));
}
}
@@ -382,8 +388,9 @@ struct RemoveStackPointer : public PostWalker<RemoveStackPointer> {
void visitSetGlobal(SetGlobal* curr) {
if (getModule()->getGlobalOrNull(curr->name) == stackPointer) {
needStackRestore = true;
- if (!builder)
+ if (!builder) {
builder = make_unique<Builder>(*getModule());
+ }
replaceCurrent(builder->makeCall(STACK_RESTORE, {curr->value}, none));
}
}
@@ -398,8 +405,9 @@ private:
void EmscriptenGlueGenerator::replaceStackPointerGlobal() {
Global* stackPointer = getStackPointerGlobal();
- if (!stackPointer)
+ if (!stackPointer) {
return;
+ }
// Replace all uses of stack pointer global
RemoveStackPointer walker(stackPointer);
@@ -796,8 +804,9 @@ struct FixInvokeFunctionNamesWalker
}
static Name fixEmEHSjLjNames(const Name& name, const std::string& sig) {
- if (name == "emscripten_longjmp_jmpbuf")
+ if (name == "emscripten_longjmp_jmpbuf") {
return "emscripten_longjmp";
+ }
return fixEmExceptionInvoke(name, sig);
}
@@ -840,10 +849,11 @@ template<class C> void printSet(std::ostream& o, C& c) {
o << "[";
bool first = true;
for (auto& item : c) {
- if (first)
+ if (first) {
first = false;
- else
+ } else {
o << ",";
+ }
o << '"' << item << '"';
}
o << "]";
diff --git a/src/wasm/wasm-io.cpp b/src/wasm/wasm-io.cpp
index 1bdb76d5f..90df2de12 100644
--- a/src/wasm/wasm-io.cpp
+++ b/src/wasm/wasm-io.cpp
@@ -37,8 +37,9 @@ static void readTextData(std::string& input, Module& wasm) {
}
void ModuleReader::readText(std::string filename, Module& wasm) {
- if (debug)
+ if (debug) {
std::cerr << "reading text from " << filename << "\n";
+ }
auto input(read_file<std::string>(
filename, Flags::Text, debug ? Flags::Debug : Flags::Release));
readTextData(input, wasm);
@@ -64,8 +65,9 @@ static void readBinaryData(std::vector<char>& input,
void ModuleReader::readBinary(std::string filename,
Module& wasm,
std::string sourceMapFilename) {
- if (debug)
+ if (debug) {
std::cerr << "reading binary from " << filename << "\n";
+ }
auto input(read_file<std::vector<char>>(
filename, Flags::Binary, debug ? Flags::Debug : Flags::Release));
readBinaryData(input, wasm, sourceMapFilename, debug);
@@ -123,8 +125,9 @@ void ModuleWriter::writeText(Module& wasm, Output& output) {
}
void ModuleWriter::writeText(Module& wasm, std::string filename) {
- if (debug)
+ if (debug) {
std::cerr << "writing text to " << filename << "\n";
+ }
Output output(filename, Flags::Text, debug ? Flags::Debug : Flags::Release);
writeText(wasm, output);
}
@@ -140,8 +143,9 @@ void ModuleWriter::writeBinary(Module& wasm, Output& output) {
sourceMapStream->open(sourceMapFilename);
writer.setSourceMap(sourceMapStream.get(), sourceMapUrl);
}
- if (symbolMap.size() > 0)
+ if (symbolMap.size() > 0) {
writer.setSymbolMap(symbolMap);
+ }
writer.write();
buffer.writeTo(output);
if (sourceMapStream) {
@@ -150,8 +154,9 @@ void ModuleWriter::writeBinary(Module& wasm, Output& output) {
}
void ModuleWriter::writeBinary(Module& wasm, std::string filename) {
- if (debug)
+ if (debug) {
std::cerr << "writing binary to " << filename << "\n";
+ }
Output output(filename, Flags::Binary, debug ? Flags::Debug : Flags::Release);
writeBinary(wasm, output);
}
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index bb498329f..cd9eb690a 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -37,12 +37,15 @@ using cashew::IString;
namespace {
int unhex(char c) {
- if (c >= '0' && c <= '9')
+ if (c >= '0' && c <= '9') {
return c - '0';
- if (c >= 'a' && c <= 'f')
+ }
+ if (c >= 'a' && c <= 'f') {
return c - 'a' + 10;
- if (c >= 'A' && c <= 'F')
+ }
+ if (c >= 'A' && c <= 'F') {
return c - 'A' + 10;
+ }
throw wasm::ParseException("invalid hexadecimal");
}
} // namespace
@@ -58,28 +61,33 @@ static Address getCheckedAddress(const Element* s, const char* errorText) {
}
Element::List& Element::list() {
- if (!isList())
+ if (!isList()) {
throw ParseException("expected list", line, col);
+ }
return list_;
}
Element* Element::operator[](unsigned i) {
- if (!isList())
+ if (!isList()) {
throw ParseException("expected list", line, col);
- if (i >= list().size())
+ }
+ if (i >= list().size()) {
throw ParseException("expected more elements in list", line, col);
+ }
return list()[i];
}
IString Element::str() const {
- if (!isStr())
+ if (!isStr()) {
throw ParseException("expected string", line, col);
+ }
return str_;
}
const char* Element::c_str() const {
- if (!isStr())
+ if (!isStr()) {
throw ParseException("expected string", line, col);
+ }
return str_.str;
}
@@ -102,8 +110,9 @@ Element::setMetadata(size_t line_, size_t col_, SourceLocation* startLoc_) {
std::ostream& operator<<(std::ostream& o, Element& e) {
if (e.isList_) {
o << '(';
- for (auto item : e.list_)
+ for (auto item : e.list_) {
o << ' ' << *item;
+ }
o << " )";
} else {
o << e.str_.str;
@@ -130,8 +139,9 @@ Element* SExpressionParser::parse() {
Element* curr = allocator.alloc<Element>();
while (1) {
skipWhitespace();
- if (input[0] == 0)
+ if (input[0] == 0) {
break;
+ }
if (input[0] == '(') {
input++;
stack.push_back(curr);
@@ -156,29 +166,34 @@ Element* SExpressionParser::parse() {
curr->list().push_back(parseString());
}
}
- if (stack.size() != 0)
+ if (stack.size() != 0) {
throw ParseException("stack is not empty", curr->line, curr->col);
+ }
return curr;
}
void SExpressionParser::parseDebugLocation() {
// Extracting debug location (if valid)
char* debugLoc = input + 3; // skipping ";;@"
- while (debugLoc[0] && debugLoc[0] == ' ')
+ while (debugLoc[0] && debugLoc[0] == ' ') {
debugLoc++;
+ }
char* debugLocEnd = debugLoc;
- while (debugLocEnd[0] && debugLocEnd[0] != '\n')
+ while (debugLocEnd[0] && debugLocEnd[0] != '\n') {
debugLocEnd++;
+ }
char* pos = debugLoc;
- while (pos < debugLocEnd && pos[0] != ':')
+ while (pos < debugLocEnd && pos[0] != ':') {
pos++;
+ }
if (pos >= debugLocEnd) {
return; // no line number
}
std::string name(debugLoc, pos);
char* lineStart = ++pos;
- while (pos < debugLocEnd && pos[0] != ':')
+ while (pos < debugLocEnd && pos[0] != ':') {
pos++;
+ }
std::string lineStr(lineStart, pos);
if (pos >= debugLocEnd) {
return; // no column number
@@ -203,19 +218,22 @@ void SExpressionParser::skipWhitespace() {
if (input[2] == '@') {
parseDebugLocation();
}
- while (input[0] && input[0] != '\n')
+ while (input[0] && input[0] != '\n') {
input++;
+ }
line++;
- if (!input[0])
+ if (!input[0]) {
return;
+ }
lineStart = ++input;
} else if (input[0] == '(' && input[1] == ';') {
// Skip nested block comments.
input += 2;
int depth = 1;
while (1) {
- if (!input[0])
+ if (!input[0]) {
return;
+ }
if (input[0] == '(' && input[1] == ';') {
input += 2;
depth++;
@@ -252,15 +270,18 @@ Element* SExpressionParser::parseString() {
input++;
std::string str;
while (1) {
- if (input[0] == 0)
+ if (input[0] == 0) {
throw ParseException("unterminated string", line, start - lineStart);
- if (input[0] == '"')
+ }
+ if (input[0] == '"') {
break;
+ }
if (input[0] == '\\') {
str += input[0];
- if (input[1] == 0)
+ if (input[1] == 0) {
throw ParseException(
"unterminated string escape", line, start - lineStart);
+ }
str += input[1];
input += 2;
continue;
@@ -274,10 +295,12 @@ Element* SExpressionParser::parseString() {
->setMetadata(line, start - lineStart, loc);
}
while (input[0] && !isspace(input[0]) && input[0] != ')' && input[0] != '(' &&
- input[0] != ';')
+ input[0] != ';') {
input++;
- if (start == input)
+ }
+ if (start == input) {
throw ParseException("expected string", line, input - lineStart);
+ }
char temp = input[0];
input[0] = 0;
auto ret = allocator.alloc<Element>()
@@ -291,12 +314,15 @@ SExpressionWasmBuilder::SExpressionWasmBuilder(Module& wasm,
Element& module,
Name* moduleName)
: wasm(wasm), allocator(wasm.allocator) {
- if (module.size() == 0)
+ if (module.size() == 0) {
throw ParseException("empty toplevel, expected module");
- if (module[0]->str() != MODULE)
+ }
+ if (module[0]->str() != MODULE) {
throw ParseException("toplevel does not start with module");
- if (module.size() == 1)
+ }
+ if (module.size() == 1) {
return;
+ }
Index i = 1;
if (module[i]->dollared()) {
if (moduleName) {
@@ -338,55 +364,69 @@ SExpressionWasmBuilder::SExpressionWasmBuilder(Module& wasm,
bool SExpressionWasmBuilder::isImport(Element& curr) {
for (Index i = 0; i < curr.size(); i++) {
auto& x = *curr[i];
- if (x.isList() && x.size() > 0 && x[0]->isStr() && x[0]->str() == IMPORT)
+ if (x.isList() && x.size() > 0 && x[0]->isStr() && x[0]->str() == IMPORT) {
return true;
+ }
}
return false;
}
void SExpressionWasmBuilder::preParseImports(Element& curr) {
IString id = curr[0]->str();
- if (id == IMPORT)
+ if (id == IMPORT) {
parseImport(curr);
+ }
if (isImport(curr)) {
- if (id == FUNC)
+ if (id == FUNC) {
parseFunction(curr, true /* preParseImport */);
- else if (id == GLOBAL)
+ } else if (id == GLOBAL) {
parseGlobal(curr, true /* preParseImport */);
- else if (id == TABLE)
+ } else if (id == TABLE) {
parseTable(curr, true /* preParseImport */);
- else if (id == MEMORY)
+ } else if (id == MEMORY) {
parseMemory(curr, true /* preParseImport */);
- else
+ } else {
throw ParseException(
"fancy import we don't support yet", curr.line, curr.col);
+ }
}
}
void SExpressionWasmBuilder::parseModuleElement(Element& curr) {
- if (isImport(curr))
+ if (isImport(curr)) {
return; // already done
+ }
IString id = curr[0]->str();
- if (id == START)
+ if (id == START) {
return parseStart(curr);
- if (id == FUNC)
+ }
+ if (id == FUNC) {
return parseFunction(curr);
- if (id == MEMORY)
+ }
+ if (id == MEMORY) {
return parseMemory(curr);
- if (id == DATA)
+ }
+ if (id == DATA) {
return parseData(curr);
- if (id == EXPORT)
+ }
+ if (id == EXPORT) {
return parseExport(curr);
- if (id == IMPORT)
+ }
+ if (id == IMPORT) {
return; // already done
- if (id == GLOBAL)
+ }
+ if (id == GLOBAL) {
return parseGlobal(curr);
- if (id == TABLE)
+ }
+ if (id == TABLE) {
return parseTable(curr);
- if (id == ELEM)
+ }
+ if (id == ELEM) {
return parseElem(curr);
- if (id == TYPE)
+ }
+ if (id == TYPE) {
return; // already done
+ }
std::cerr << "bad module element " << id.str << '\n';
throw ParseException("unknown module element", curr.line, curr.col);
}
@@ -397,8 +437,9 @@ Name SExpressionWasmBuilder::getFunctionName(Element& s) {
} else {
// index
size_t offset = atoi(s.str().c_str());
- if (offset >= functionNames.size())
+ if (offset >= functionNames.size()) {
throw ParseException("unknown function in getFunctionName");
+ }
return functionNames[offset];
}
}
@@ -409,8 +450,9 @@ Name SExpressionWasmBuilder::getFunctionTypeName(Element& s) {
} else {
// index
size_t offset = atoi(s.str().c_str());
- if (offset >= functionTypeNames.size())
+ if (offset >= functionTypeNames.size()) {
throw ParseException("unknown function type in getFunctionTypeName");
+ }
return functionTypeNames[offset];
}
}
@@ -421,18 +463,21 @@ Name SExpressionWasmBuilder::getGlobalName(Element& s) {
} else {
// index
size_t offset = atoi(s.str().c_str());
- if (offset >= globalNames.size())
+ if (offset >= globalNames.size()) {
throw ParseException("unknown global in getGlobalName");
+ }
return globalNames[offset];
}
}
void SExpressionWasmBuilder::preParseFunctionType(Element& s) {
IString id = s[0]->str();
- if (id == TYPE)
+ if (id == TYPE) {
return parseType(s);
- if (id != FUNC)
+ }
+ if (id != FUNC) {
return;
+ }
size_t i = 1;
Name name, exportName;
i = parseFunctionNames(s, name, exportName);
@@ -449,13 +494,15 @@ void SExpressionWasmBuilder::preParseFunctionType(Element& s) {
Element& curr = *s[i];
IString id = curr[0]->str();
if (id == RESULT) {
- if (curr.size() > 2)
+ if (curr.size() > 2) {
throw ParseException("invalid result arity", curr.line, curr.col);
+ }
functionTypes[name] = stringToType(curr[1]->str());
} else if (id == TYPE) {
Name typeName = getFunctionTypeName(*curr[1]);
- if (!wasm.getFunctionTypeOrNull(typeName))
+ if (!wasm.getFunctionTypeOrNull(typeName)) {
throw ParseException("unknown function type", curr.line, curr.col);
+ }
type = wasm.getFunctionType(typeName);
functionTypes[name] = type->result;
} else if (id == PARAM && curr.size() > 1) {
@@ -487,8 +534,9 @@ void SExpressionWasmBuilder::preParseFunctionType(Element& s) {
if (need) {
functionType->name = Name::fromInt(wasm.functionTypes.size());
functionTypeNames.push_back(functionType->name);
- if (wasm.getFunctionTypeOrNull(functionType->name))
+ if (wasm.getFunctionTypeOrNull(functionType->name)) {
throw ParseException("duplicate function type", s.line, s.col);
+ }
wasm.addFunctionType(std::move(functionType));
}
}
@@ -547,8 +595,9 @@ void SExpressionWasmBuilder::parseFunction(Element& s, bool preParseImport) {
ex->name = exportName;
ex->value = name;
ex->kind = ExternalKind::Function;
- if (wasm.getExportOrNull(ex->name))
+ if (wasm.getExportOrNull(ex->name)) {
throw ParseException("duplicate export", s.line, s.col);
+ }
wasm.addExport(ex.release());
}
Expression* body = nullptr;
@@ -604,14 +653,16 @@ void SExpressionWasmBuilder::parseFunction(Element& s, bool preParseImport) {
currLocalTypes[name] = type;
}
} else if (id == RESULT) {
- if (curr.size() > 2)
+ if (curr.size() > 2) {
throw ParseException("invalid result arity", curr.line, curr.col);
+ }
result = stringToType(curr[1]->str());
} else if (id == TYPE) {
Name name = getFunctionTypeName(*curr[1]);
type = name;
- if (!wasm.getFunctionTypeOrNull(name))
+ if (!wasm.getFunctionTypeOrNull(name)) {
throw ParseException("unknown function type");
+ }
FunctionType* type = wasm.getFunctionType(name);
result = type->result;
for (size_t j = 0; j < type->params.size(); j++) {
@@ -628,8 +679,9 @@ void SExpressionWasmBuilder::parseFunction(Element& s, bool preParseImport) {
if (typeParams.size() > 0 && params.size() == 0) {
params = typeParams;
}
- if (!currFunction)
+ if (!currFunction) {
makeFunction();
+ }
Expression* ex = parseExpression(curr);
if (!body) {
body = ex;
@@ -650,15 +702,18 @@ void SExpressionWasmBuilder::parseFunction(Element& s, bool preParseImport) {
break;
}
}
- if (!type.is())
+ if (!type.is()) {
throw ParseException("no function type [internal error?]", s.line, s.col);
+ }
}
if (importModule.is()) {
// this is an import, actually
- if (!importBase.size())
+ if (!importBase.size()) {
throw ParseException("module but no base for import");
- if (!preParseImport)
+ }
+ if (!preParseImport) {
throw ParseException("!preParseImport in func");
+ }
auto im = make_unique<Function>();
im->name = name;
im->module = importModule;
@@ -666,17 +721,20 @@ void SExpressionWasmBuilder::parseFunction(Element& s, bool preParseImport) {
im->type = type;
FunctionTypeUtils::fillFunction(im.get(), wasm.getFunctionType(type));
functionTypes[name] = im->result;
- if (wasm.getFunctionOrNull(im->name))
+ if (wasm.getFunctionOrNull(im->name)) {
throw ParseException("duplicate import", s.line, s.col);
+ }
wasm.addFunction(im.release());
- if (currFunction)
+ if (currFunction) {
throw ParseException("import module inside function dec");
+ }
currLocalTypes.clear();
nameMapper.clear();
return;
}
- if (preParseImport)
+ if (preParseImport) {
throw ParseException("preParseImport in func");
+ }
if (brokeToAutoBlock) {
ensureAutoBlock();
autoBlock->name = FAKE_RETURN;
@@ -688,8 +746,9 @@ void SExpressionWasmBuilder::parseFunction(Element& s, bool preParseImport) {
makeFunction();
body = allocator.alloc<Nop>();
}
- if (currFunction->result != result)
+ if (currFunction->result != result) {
throw ParseException("bad func declaration", s.line, s.col);
+ }
currFunction->body = body;
currFunction->type = type;
if (s.startLoc) {
@@ -698,8 +757,9 @@ void SExpressionWasmBuilder::parseFunction(Element& s, bool preParseImport) {
if (s.endLoc) {
currFunction->epilogLocation.insert(getDebugLocation(*s.endLoc));
}
- if (wasm.getFunctionOrNull(currFunction->name))
+ if (wasm.getFunctionOrNull(currFunction->name)) {
throw ParseException("duplicate function", s.line, s.col);
+ }
wasm.addFunction(currFunction.release());
currLocalTypes.clear();
nameMapper.clear();
@@ -709,16 +769,20 @@ Type SExpressionWasmBuilder::stringToType(const char* str,
bool allowError,
bool prefix) {
if (str[0] == 'i') {
- if (str[1] == '3' && str[2] == '2' && (prefix || str[3] == 0))
+ if (str[1] == '3' && str[2] == '2' && (prefix || str[3] == 0)) {
return i32;
- if (str[1] == '6' && str[2] == '4' && (prefix || str[3] == 0))
+ }
+ if (str[1] == '6' && str[2] == '4' && (prefix || str[3] == 0)) {
return i64;
+ }
}
if (str[0] == 'f') {
- if (str[1] == '3' && str[2] == '2' && (prefix || str[3] == 0))
+ if (str[1] == '3' && str[2] == '2' && (prefix || str[3] == 0)) {
return f32;
- if (str[1] == '6' && str[2] == '4' && (prefix || str[3] == 0))
+ }
+ if (str[1] == '6' && str[2] == '4' && (prefix || str[3] == 0)) {
return f64;
+ }
}
if (str[0] == 'v') {
if (str[1] == '1' && str[2] == '2' && str[3] == '8' &&
@@ -726,24 +790,31 @@ Type SExpressionWasmBuilder::stringToType(const char* str,
return v128;
}
}
- if (allowError)
+ if (allowError) {
return none;
+ }
throw ParseException("invalid wasm type");
}
Type SExpressionWasmBuilder::stringToLaneType(const char* str) {
- if (strcmp(str, "i8x16") == 0)
+ if (strcmp(str, "i8x16") == 0) {
return i32;
- if (strcmp(str, "i16x8") == 0)
+ }
+ if (strcmp(str, "i16x8") == 0) {
return i32;
- if (strcmp(str, "i32x4") == 0)
+ }
+ if (strcmp(str, "i32x4") == 0) {
return i32;
- if (strcmp(str, "i64x2") == 0)
+ }
+ if (strcmp(str, "i64x2") == 0) {
return i64;
- if (strcmp(str, "f32x4") == 0)
+ }
+ if (strcmp(str, "f32x4") == 0) {
return f32;
- if (strcmp(str, "f64x2") == 0)
+ }
+ if (strcmp(str, "f64x2") == 0) {
return f64;
+ }
return none;
}
@@ -831,18 +902,21 @@ Expression* SExpressionWasmBuilder::makeHost(Element& s, HostOp op) {
}
Index SExpressionWasmBuilder::getLocalIndex(Element& s) {
- if (!currFunction)
+ if (!currFunction) {
throw ParseException("local access in non-function scope", s.line, s.col);
+ }
if (s.dollared()) {
auto ret = s.str();
- if (currFunction->localIndices.count(ret) == 0)
+ if (currFunction->localIndices.count(ret) == 0) {
throw ParseException("bad local name", s.line, s.col);
+ }
return currFunction->getLocalIndex(ret);
}
// this is a numeric index
Index ret = atoi(s.c_str());
- if (ret >= currFunction->getNumLocals())
+ if (ret >= currFunction->getNumLocals()) {
throw ParseException("bad local index", s.line, s.col);
+ }
return ret;
}
@@ -886,16 +960,18 @@ Expression* SExpressionWasmBuilder::makeSetGlobal(Element& s) {
auto ret = allocator.alloc<SetGlobal>();
ret->name = getGlobalName(*s[1]);
if (wasm.getGlobalOrNull(ret->name) &&
- !wasm.getGlobalOrNull(ret->name)->mutable_)
+ !wasm.getGlobalOrNull(ret->name)->mutable_) {
throw ParseException("global.set of immutable", s.line, s.col);
+ }
ret->value = parseExpression(s[2]);
ret->finalize();
return ret;
}
Expression* SExpressionWasmBuilder::makeBlock(Element& s) {
- if (!currFunction)
+ if (!currFunction) {
throw ParseException("block is unallowed outside of functions");
+ }
// special-case Block, because Block nesting (in their first element) can be
// incredibly deep
auto curr = allocator.alloc<Block>();
@@ -920,8 +996,9 @@ Expression* SExpressionWasmBuilder::makeBlock(Element& s) {
curr->name = nameMapper.pushLabelName(sName);
// block signature
curr->type = parseOptionalResultType(s, i);
- if (i >= s.size())
+ if (i >= s.size()) {
break; // empty block
+ }
auto& first = *s[i];
if (first[0]->str() == BLOCK) {
// recurse
@@ -994,8 +1071,9 @@ static Literal makeLanes(Element& s, MixedArena& allocator, Type lane_t) {
Expression* SExpressionWasmBuilder::makeConst(Element& s, Type type) {
if (type != v128) {
auto ret = parseConst(s[1]->str(), type, allocator);
- if (!ret)
+ if (!ret) {
throw ParseException("bad const");
+ }
return ret;
}
@@ -1044,14 +1122,15 @@ static uint8_t parseMemBytes(const char*& s, uint8_t fallback) {
ret = 1;
s++;
} else if (s[0] == '1') {
- if (s[1] != '6')
+ if (s[1] != '6') {
throw ParseException("expected 16 for memop size");
+ }
ret = 2;
s += 2;
} else if (s[0] == '3') {
- if (s[1] != '2')
+ if (s[1] != '2') {
throw ParseException("expected 32 for memop size");
- ;
+ };
ret = 4;
s += 2;
} else {
@@ -1070,26 +1149,31 @@ static size_t parseMemAttributes(Element& s,
while (!s[i]->isList()) {
const char* str = s[i]->c_str();
const char* eq = strchr(str, '=');
- if (!eq)
+ if (!eq) {
throw ParseException("missing = in memory attribute");
+ }
eq++;
- if (*eq == 0)
+ if (*eq == 0) {
throw ParseException("missing value in memory attribute", s.line, s.col);
+ }
char* endptr;
uint64_t value = strtoll(eq, &endptr, 10);
if (*endptr != 0) {
throw ParseException("bad memory attribute immediate", s.line, s.col);
}
if (str[0] == 'a') {
- if (value > std::numeric_limits<uint32_t>::max())
+ if (value > std::numeric_limits<uint32_t>::max()) {
throw ParseException("bad align", s.line, s.col);
+ }
*align = value;
} else if (str[0] == 'o') {
- if (value > std::numeric_limits<uint32_t>::max())
+ if (value > std::numeric_limits<uint32_t>::max()) {
throw ParseException("bad offset", s.line, s.col);
+ }
*offset = value;
- } else
+ } else {
throw ParseException("bad memory attribute");
+ }
i++;
}
return i;
@@ -1099,13 +1183,16 @@ static const char* findMemExtra(const Element& s, size_t skip, bool isAtomic) {
auto* str = s.c_str();
auto size = strlen(str);
auto* ret = strchr(str, '.');
- if (!ret)
+ if (!ret) {
throw ParseException("missing '.' in memory access", s.line, s.col);
+ }
ret += skip;
- if (isAtomic)
+ if (isAtomic) {
ret += 7; // after "type.atomic.load"
- if (ret > str + size)
+ }
+ if (ret > str + size) {
throw ParseException("memory access ends abruptly", s.line, s.col);
+ }
return ret;
}
@@ -1143,11 +1230,13 @@ Expression* SExpressionWasmBuilder::makeAtomicRMWOrCmpxchg(Element& s,
*s[0], 11 /* after "type.atomic.rmw" */, /* isAtomic = */ false);
auto bytes = parseMemBytes(extra, getTypeSize(type));
extra = strchr(extra, '.'); // after the optional '_u' and before the opcode
- if (!extra)
+ if (!extra) {
throw ParseException("malformed atomic rmw instruction");
+ }
extra++; // after the '.'
- if (!strncmp(extra, "cmpxchg", 7))
+ if (!strncmp(extra, "cmpxchg", 7)) {
return makeAtomicCmpxchg(s, type, bytes, extra);
+ }
return makeAtomicRMW(s, type, bytes, extra);
}
@@ -1158,24 +1247,26 @@ Expression* SExpressionWasmBuilder::makeAtomicRMW(Element& s,
auto ret = allocator.alloc<AtomicRMW>();
ret->type = type;
ret->bytes = bytes;
- if (!strncmp(extra, "add", 3))
+ if (!strncmp(extra, "add", 3)) {
ret->op = Add;
- else if (!strncmp(extra, "and", 3))
+ } else if (!strncmp(extra, "and", 3)) {
ret->op = And;
- else if (!strncmp(extra, "or", 2))
+ } else if (!strncmp(extra, "or", 2)) {
ret->op = Or;
- else if (!strncmp(extra, "sub", 3))
+ } else if (!strncmp(extra, "sub", 3)) {
ret->op = Sub;
- else if (!strncmp(extra, "xor", 3))
+ } else if (!strncmp(extra, "xor", 3)) {
ret->op = Xor;
- else if (!strncmp(extra, "xchg", 4))
+ } else if (!strncmp(extra, "xchg", 4)) {
ret->op = Xchg;
- else
+ } else {
throw ParseException("bad atomic rmw operator");
+ }
Address align;
size_t i = parseMemAttributes(s, &ret->offset, &align, ret->bytes);
- if (align != ret->bytes)
+ if (align != ret->bytes) {
throw ParseException("Align of Atomic RMW must match size");
+ }
ret->ptr = parseExpression(s[i]);
ret->value = parseExpression(s[i + 1]);
ret->finalize();
@@ -1191,8 +1282,9 @@ Expression* SExpressionWasmBuilder::makeAtomicCmpxchg(Element& s,
ret->bytes = bytes;
Address align;
size_t i = parseMemAttributes(s, &ret->offset, &align, ret->bytes);
- if (align != ret->bytes)
+ if (align != ret->bytes) {
throw ParseException("Align of Atomic Cmpxchg must match size");
+ }
ret->ptr = parseExpression(s[i]);
ret->expected = parseExpression(s[i + 1]);
ret->replacement = parseExpression(s[i + 2]);
@@ -1224,11 +1316,13 @@ static uint8_t parseLaneIndex(const Element* s, size_t lanes) {
const char* str = s->c_str();
char* end;
auto n = static_cast<unsigned long long>(strtoll(str, &end, 10));
- if (end == str || *end != '\0')
+ if (end == str || *end != '\0') {
throw ParseException("Expected lane index");
- if (n > lanes)
+ }
+ if (n > lanes) {
throw ParseException("lane index must be less than " +
std::to_string(lanes));
+ }
return uint8_t(n);
}
@@ -1353,10 +1447,12 @@ Expression* SExpressionWasmBuilder::makeIf(Element& s) {
Expression*
SExpressionWasmBuilder::makeMaybeBlock(Element& s, size_t i, Type type) {
Index stopAt = -1;
- if (s.size() == i)
+ if (s.size() == i) {
return allocator.alloc<Nop>();
- if (s.size() == i + 1)
+ }
+ if (s.size() == i + 1) {
return parseExpression(s[i]);
+ }
auto ret = allocator.alloc<Block>();
for (; i < s.size() && i < stopAt; i++) {
ret->list.push_back(parseExpression(s[i]));
@@ -1369,18 +1465,21 @@ SExpressionWasmBuilder::makeMaybeBlock(Element& s, size_t i, Type type) {
}
Type SExpressionWasmBuilder::parseOptionalResultType(Element& s, Index& i) {
- if (s.size() == i)
+ if (s.size() == i) {
return none;
+ }
// TODO(sbc): Remove support for old result syntax (bare streing) once the
// spec tests are updated.
- if (s[i]->isStr())
+ if (s[i]->isStr()) {
return stringToType(s[i++]->str());
+ }
Element& params = *s[i];
IString id = params[0]->str();
- if (id != RESULT)
+ if (id != RESULT) {
return none;
+ }
i++;
return stringToType(params[1]->str());
@@ -1414,8 +1513,9 @@ Expression* SExpressionWasmBuilder::makeCall(Element& s) {
}
Expression* SExpressionWasmBuilder::makeCallIndirect(Element& s) {
- if (!wasm.table.exists)
+ if (!wasm.table.exists) {
throw ParseException("no table");
+ }
auto ret = allocator.alloc<CallIndirect>();
Index i = 1;
Element& typeElement = *s[i];
@@ -1423,8 +1523,9 @@ Expression* SExpressionWasmBuilder::makeCallIndirect(Element& s) {
// type name given
IString type = typeElement[1]->str();
auto* fullType = wasm.getFunctionTypeOrNull(type);
- if (!fullType)
+ if (!fullType) {
throw ParseException("invalid call_indirect type", s.line, s.col);
+ }
ret->fullType = fullType->name;
i++;
} else {
@@ -1465,8 +1566,9 @@ Name SExpressionWasmBuilder::getLabel(Element& s) {
} catch (std::out_of_range&) {
throw ParseException("out of range break offset");
}
- if (offset > nameMapper.labelStack.size())
+ if (offset > nameMapper.labelStack.size()) {
throw ParseException("invalid label", s.line, s.col);
+ }
if (offset == nameMapper.labelStack.size()) {
// a break to the function's scope. this means we need an automatic block,
// with a name
@@ -1482,8 +1584,9 @@ Expression* SExpressionWasmBuilder::makeBreak(Element& s) {
size_t i = 1;
ret->name = getLabel(*s[i]);
i++;
- if (i == s.size())
+ if (i == s.size()) {
return ret;
+ }
if (s[0]->str() == BR_IF) {
if (i + 1 < s.size()) {
ret->value = parseExpression(s[i]);
@@ -1503,8 +1606,9 @@ Expression* SExpressionWasmBuilder::makeBreakTable(Element& s) {
while (!s[i]->isList()) {
ret->targets.push_back(getLabel(*s[i++]));
}
- if (ret->targets.size() == 0)
+ if (ret->targets.size() == 0) {
throw ParseException("switch with no targets");
+ }
ret->default_ = ret->targets.back();
ret->targets.pop_back();
ret->condition = parseExpression(s[i++]);
@@ -1533,8 +1637,9 @@ void SExpressionWasmBuilder::stringToBinary(const char* input,
data.resize(originalSize + size);
char* write = data.data() + originalSize;
while (1) {
- if (input[0] == 0)
+ if (input[0] == 0) {
break;
+ }
if (input[0] == '\\') {
if (input[1] == '"') {
*write++ = '"';
@@ -1578,15 +1683,17 @@ Index SExpressionWasmBuilder::parseMemoryLimits(Element& s, Index i) {
return i;
}
uint64_t max = atoll(s[i++]->c_str());
- if (max > Memory::kMaxSize)
+ if (max > Memory::kMaxSize) {
throw ParseException("total memory must be <= 4GB");
+ }
wasm.memory.max = max;
return i;
}
void SExpressionWasmBuilder::parseMemory(Element& s, bool preParseImport) {
- if (wasm.memory.exists)
+ if (wasm.memory.exists) {
throw ParseException("too many memories");
+ }
wasm.memory.exists = true;
wasm.memory.shared = false;
Index i = 1;
@@ -1601,8 +1708,9 @@ void SExpressionWasmBuilder::parseMemory(Element& s, bool preParseImport) {
ex->name = inner[1]->str();
ex->value = wasm.memory.name;
ex->kind = ExternalKind::Memory;
- if (wasm.getExportOrNull(ex->name))
+ if (wasm.getExportOrNull(ex->name)) {
throw ParseException("duplicate export", s.line, s.col);
+ }
wasm.addExport(ex.release());
i++;
} else if (inner[0]->str() == IMPORT) {
@@ -1614,8 +1722,9 @@ void SExpressionWasmBuilder::parseMemory(Element& s, bool preParseImport) {
parseMemoryLimits(inner, 1);
i++;
} else {
- if (!(inner.size() > 0 ? inner[0]->str() != IMPORT : true))
+ if (!(inner.size() > 0 ? inner[0]->str() != IMPORT : true)) {
throw ParseException("bad import ending");
+ }
// (memory (data ..)) format
auto offset = allocator.alloc<Const>()->set(Literal(int32_t(0)));
parseInnerData(*s[i], 1, offset, false);
@@ -1623,8 +1732,9 @@ void SExpressionWasmBuilder::parseMemory(Element& s, bool preParseImport) {
return;
}
}
- if (!wasm.memory.shared)
+ if (!wasm.memory.shared) {
i = parseMemoryLimits(s, i);
+ }
// Parse memory initializers.
while (i < s.size()) {
@@ -1652,8 +1762,9 @@ void SExpressionWasmBuilder::parseMemory(Element& s, bool preParseImport) {
}
void SExpressionWasmBuilder::parseData(Element& s) {
- if (!wasm.memory.exists)
+ if (!wasm.memory.exists) {
throw ParseException("data but no memory");
+ }
bool isPassive = false;
Expression* offset = nullptr;
Index i = 1;
@@ -1703,16 +1814,18 @@ void SExpressionWasmBuilder::parseExport(Element& s) {
} else if (inner[0]->str() == GLOBAL) {
ex->kind = ExternalKind::Global;
if (wasm.getGlobalOrNull(ex->value) &&
- wasm.getGlobal(ex->value)->mutable_)
+ wasm.getGlobal(ex->value)->mutable_) {
throw ParseException("cannot export a mutable global", s.line, s.col);
+ }
} else {
throw ParseException("invalid export");
}
} else if (!s[2]->dollared() && !std::isdigit(s[2]->str()[0])) {
ex->value = s[3]->str();
if (s[2]->str() == MEMORY) {
- if (!wasm.memory.exists)
+ if (!wasm.memory.exists) {
throw ParseException("memory exported but no memory");
+ }
ex->kind = ExternalKind::Memory;
} else if (s[2]->str() == TABLE) {
ex->kind = ExternalKind::Table;
@@ -1726,8 +1839,9 @@ void SExpressionWasmBuilder::parseExport(Element& s) {
ex->value = s[2]->str();
ex->kind = ExternalKind::Function;
}
- if (wasm.getExportOrNull(ex->name))
+ if (wasm.getExportOrNull(ex->name)) {
throw ParseException("duplicate export", s.line, s.col);
+ }
wasm.addExport(ex.release());
}
@@ -1741,13 +1855,15 @@ void SExpressionWasmBuilder::parseImport(Element& s) {
kind = ExternalKind::Function;
} else if ((*s[3])[0]->str() == MEMORY) {
kind = ExternalKind::Memory;
- if (wasm.memory.exists)
+ if (wasm.memory.exists) {
throw ParseException("more than one memory");
+ }
wasm.memory.exists = true;
} else if ((*s[3])[0]->str() == TABLE) {
kind = ExternalKind::Table;
- if (wasm.table.exists)
+ if (wasm.table.exists) {
throw ParseException("more than one table");
+ }
wasm.table.exists = true;
} else if ((*s[3])[0]->str() == GLOBAL) {
kind = ExternalKind::Global;
@@ -1793,11 +1909,13 @@ void SExpressionWasmBuilder::parseImport(Element& s) {
kind = ExternalKind::Function;
}
auto module = s[i++]->str();
- if (!s[i]->isStr())
+ if (!s[i]->isStr()) {
throw ParseException("no name for import");
+ }
auto base = s[i++]->str();
- if (!module.size() || !base.size())
+ if (!module.size() || !base.size()) {
throw ParseException("imports must have module and base");
+ }
// parse internals
Element& inner = newStyle ? *s[3] : s;
Index j = newStyle ? newStyleInner : i;
@@ -1814,16 +1932,18 @@ void SExpressionWasmBuilder::parseImport(Element& s) {
type->result = stringToType(params[1]->str());
} else if (id == TYPE) {
IString name = params[1]->str();
- if (!wasm.getFunctionTypeOrNull(name))
+ if (!wasm.getFunctionTypeOrNull(name)) {
throw ParseException("bad function type for import");
+ }
*type = *wasm.getFunctionType(name);
} else {
throw ParseException("bad import element");
}
if (inner.size() > j + 1) {
Element& result = *inner[j + 1];
- if (result[0]->str() != RESULT)
+ if (result[0]->str() != RESULT) {
throw ParseException("expected result");
+ }
type->result = stringToType(result[1]->str());
}
}
@@ -1843,8 +1963,9 @@ void SExpressionWasmBuilder::parseImport(Element& s) {
type = stringToType(inner[j]->str());
} else {
auto& inner2 = *inner[j];
- if (inner2[0]->str() != MUT)
+ if (inner2[0]->str() != MUT) {
throw ParseException("expected mut");
+ }
type = stringToType(inner2[1]->str());
mutable_ = true;
}
@@ -1874,8 +1995,9 @@ void SExpressionWasmBuilder::parseImport(Element& s) {
wasm.memory.base = base;
if (inner[j]->isList()) {
auto& limits = *inner[j];
- if (!(limits[0]->isStr() && limits[0]->str() == "shared"))
+ if (!(limits[0]->isStr() && limits[0]->str() == "shared")) {
throw ParseException("bad memory limit declaration");
+ }
wasm.memory.shared = true;
parseMemoryLimits(limits, 1);
} else {
@@ -1905,8 +2027,9 @@ void SExpressionWasmBuilder::parseGlobal(Element& s, bool preParseImport) {
ex->name = inner[1]->str();
ex->value = global->name;
ex->kind = ExternalKind::Global;
- if (wasm.getExportOrNull(ex->name))
+ if (wasm.getExportOrNull(ex->name)) {
throw ParseException("duplicate export", s.line, s.col);
+ }
wasm.addExport(ex.release());
exported = true;
i++;
@@ -1922,30 +2045,35 @@ void SExpressionWasmBuilder::parseGlobal(Element& s, bool preParseImport) {
break;
}
}
- if (exported && mutable_)
+ if (exported && mutable_) {
throw ParseException("cannot export a mutable global", s.line, s.col);
+ }
if (type == none) {
type = stringToType(s[i++]->str());
}
if (importModule.is()) {
// this is an import, actually
- if (!importBase.size())
+ if (!importBase.size()) {
throw ParseException("module but no base for import");
- if (!preParseImport)
+ }
+ if (!preParseImport) {
throw ParseException("!preParseImport in global");
+ }
auto im = make_unique<Global>();
im->name = global->name;
im->module = importModule;
im->base = importBase;
im->type = type;
im->mutable_ = mutable_;
- if (wasm.getGlobalOrNull(im->name))
+ if (wasm.getGlobalOrNull(im->name)) {
throw ParseException("duplicate import", s.line, s.col);
+ }
wasm.addGlobal(im.release());
return;
}
- if (preParseImport)
+ if (preParseImport) {
throw ParseException("preParseImport in global");
+ }
global->type = type;
if (i < s.size()) {
global->init = parseExpression(s[i++]);
@@ -1953,25 +2081,30 @@ void SExpressionWasmBuilder::parseGlobal(Element& s, bool preParseImport) {
throw ParseException("global without init", s.line, s.col);
}
global->mutable_ = mutable_;
- if (i != s.size())
+ if (i != s.size()) {
throw ParseException("extra import elements");
- if (wasm.getGlobalOrNull(global->name))
+ }
+ if (wasm.getGlobalOrNull(global->name)) {
throw ParseException("duplicate import", s.line, s.col);
+ }
wasm.addGlobal(global.release());
}
void SExpressionWasmBuilder::parseTable(Element& s, bool preParseImport) {
- if (wasm.table.exists)
+ if (wasm.table.exists) {
throw ParseException("more than one table");
+ }
wasm.table.exists = true;
Index i = 1;
- if (i == s.size())
+ if (i == s.size()) {
return; // empty table in old notation
+ }
if (s[i]->dollared()) {
wasm.table.name = s[i++]->str();
}
- if (i == s.size())
+ if (i == s.size()) {
return;
+ }
Name importModule, importBase;
if (s[i]->isList()) {
auto& inner = *s[i];
@@ -1980,13 +2113,15 @@ void SExpressionWasmBuilder::parseTable(Element& s, bool preParseImport) {
ex->name = inner[1]->str();
ex->value = wasm.table.name;
ex->kind = ExternalKind::Table;
- if (wasm.getExportOrNull(ex->name))
+ if (wasm.getExportOrNull(ex->name)) {
throw ParseException("duplicate export", s.line, s.col);
+ }
wasm.addExport(ex.release());
i++;
} else if (inner[0]->str() == IMPORT) {
- if (!preParseImport)
+ if (!preParseImport) {
throw ParseException("!preParseImport in table");
+ }
wasm.table.module = inner[1]->str();
wasm.table.base = inner[2]->str();
i++;
@@ -1994,8 +2129,9 @@ void SExpressionWasmBuilder::parseTable(Element& s, bool preParseImport) {
throw ParseException("invalid table");
}
}
- if (i == s.size())
+ if (i == s.size()) {
return;
+ }
if (!s[i]->dollared()) {
if (s[i]->str() == FUNCREF) {
// (table type (elem ..))
@@ -2044,8 +2180,9 @@ void SExpressionWasmBuilder::parseElem(Element& s) {
void SExpressionWasmBuilder::parseInnerElem(Element& s,
Index i,
Expression* offset) {
- if (!wasm.table.exists)
+ if (!wasm.table.exists) {
throw ParseException("elem without table", s.line, s.col);
+ }
if (!offset) {
offset = allocator.alloc<Const>()->set(Literal(int32_t(0)));
}
@@ -2071,8 +2208,9 @@ void SExpressionWasmBuilder::parseType(Element& s) {
type->params.push_back(stringToType(curr[j]->str()));
}
} else if (curr[0]->str() == RESULT) {
- if (curr.size() > 2)
+ if (curr.size() > 2) {
throw ParseException("invalid result arity", curr.line, curr.col);
+ }
type->result = stringToType(curr[1]->str());
}
}
@@ -2080,8 +2218,9 @@ void SExpressionWasmBuilder::parseType(Element& s) {
type->name = Name::fromInt(wasm.functionTypes.size());
}
functionTypeNames.push_back(type->name);
- if (wasm.getFunctionTypeOrNull(type->name))
+ if (wasm.getFunctionTypeOrNull(type->name)) {
throw ParseException("duplicate function type", s.line, s.col);
+ }
wasm.addFunctionType(std::move(type));
}
diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp
index 78ad6f628..449dff4db 100644
--- a/src/wasm/wasm-type.cpp
+++ b/src/wasm/wasm-type.cpp
@@ -69,14 +69,18 @@ FeatureSet getFeatures(Type type) {
}
Type getType(unsigned size, bool float_) {
- if (size < 4)
+ if (size < 4) {
return Type::i32;
- if (size == 4)
+ }
+ if (size == 4) {
return float_ ? Type::f32 : Type::i32;
- if (size == 8)
+ }
+ if (size == 8) {
return float_ ? Type::f64 : Type::i64;
- if (size == 16)
+ }
+ if (size == 16) {
return Type::v128;
+ }
WASM_UNREACHABLE();
}
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index ea8e92047..b84105c8d 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -66,8 +66,9 @@ struct ValidationInfo {
std::ostringstream& getStream(Function* func) {
std::unique_lock<std::mutex> lock(mutex);
auto iter = outputs.find(func);
- if (iter != outputs.end())
+ if (iter != outputs.end()) {
return *(iter->second.get());
+ }
auto& ret = outputs[func] = make_unique<std::ostringstream>();
return *ret.get();
}
@@ -78,8 +79,9 @@ struct ValidationInfo {
std::ostream& fail(S text, T curr, Function* func) {
valid.store(false);
auto& stream = getStream(func);
- if (quiet)
+ if (quiet) {
return stream;
+ }
auto& ret = printFailureHeader(func);
ret << text << ", on \n";
return printModuleComponent(curr, ret);
@@ -87,8 +89,9 @@ struct ValidationInfo {
std::ostream& printFailureHeader(Function* func) {
auto& stream = getStream(func);
- if (quiet)
+ if (quiet) {
return stream;
+ }
Colors::red(stream);
if (func) {
stream << "[wasm-validator error in function ";
@@ -220,16 +223,18 @@ public:
static void visitPreBlock(FunctionValidator* self, Expression** currp) {
auto* curr = (*currp)->cast<Block>();
- if (curr->name.is())
+ if (curr->name.is()) {
self->breakInfos[curr->name];
+ }
}
void visitBlock(Block* curr);
static void visitPreLoop(FunctionValidator* self, Expression** currp) {
auto* curr = (*currp)->cast<Loop>();
- if (curr->name.is())
+ if (curr->name.is()) {
self->breakInfos[curr->name];
+ }
}
void visitLoop(Loop* curr);
@@ -240,10 +245,12 @@ public:
PostWalker<FunctionValidator>::scan(self, currp);
auto* curr = *currp;
- if (curr->is<Block>())
+ if (curr->is<Block>()) {
self->pushTask(visitPreBlock, currp);
- if (curr->is<Loop>())
+ }
+ if (curr->is<Loop>()) {
self->pushTask(visitPreLoop, currp);
+ }
}
void noteBreak(Name name, Expression* value, Expression* curr);
@@ -319,8 +326,9 @@ private:
};
void FunctionValidator::noteLabelName(Name name) {
- if (!name.is())
+ if (!name.is()) {
return;
+ }
bool inserted;
std::tie(std::ignore, inserted) = labelNames.insert(name);
shouldBeTrue(
@@ -520,8 +528,9 @@ void FunctionValidator::noteBreak(Name name,
}
auto iter = breakInfos.find(name);
if (!shouldBeTrue(
- iter != breakInfos.end(), curr, "all break targets must be valid"))
+ iter != breakInfos.end(), curr, "all break targets must be valid")) {
return;
+ }
auto& info = iter->second;
if (!info.hasBeenSet()) {
info = BreakInfo(valueType, arity);
@@ -560,15 +569,18 @@ void FunctionValidator::visitSwitch(Switch* curr) {
}
void FunctionValidator::visitCall(Call* curr) {
- if (!info.validateGlobally)
+ if (!info.validateGlobally) {
return;
+ }
auto* target = getModule()->getFunctionOrNull(curr->target);
- if (!shouldBeTrue(!!target, curr, "call target must exist"))
+ if (!shouldBeTrue(!!target, curr, "call target must exist")) {
return;
+ }
if (!shouldBeTrue(curr->operands.size() == target->params.size(),
curr,
- "call param number must match"))
+ "call param number must match")) {
return;
+ }
for (size_t i = 0; i < curr->operands.size(); i++) {
if (!shouldBeEqualOrFirstIsUnreachable(curr->operands[i]->type,
target->params[i],
@@ -581,17 +593,20 @@ void FunctionValidator::visitCall(Call* curr) {
}
void FunctionValidator::visitCallIndirect(CallIndirect* curr) {
- if (!info.validateGlobally)
+ if (!info.validateGlobally) {
return;
+ }
auto* type = getModule()->getFunctionTypeOrNull(curr->fullType);
- if (!shouldBeTrue(!!type, curr, "call_indirect type must exist"))
+ if (!shouldBeTrue(!!type, curr, "call_indirect type must exist")) {
return;
+ }
shouldBeEqualOrFirstIsUnreachable(
curr->target->type, i32, curr, "indirect call target must be an i32");
if (!shouldBeTrue(curr->operands.size() == type->params.size(),
curr,
- "call param number must match"))
+ "call param number must match")) {
return;
+ }
for (size_t i = 0; i < curr->operands.size(); i++) {
if (!shouldBeEqualOrFirstIsUnreachable(curr->operands[i]->type,
type->params[i],
@@ -639,16 +654,18 @@ void FunctionValidator::visitSetLocal(SetLocal* curr) {
}
void FunctionValidator::visitGetGlobal(GetGlobal* curr) {
- if (!info.validateGlobally)
+ if (!info.validateGlobally) {
return;
+ }
shouldBeTrue(getModule()->getGlobalOrNull(curr->name),
curr,
"global.get name must be valid");
}
void FunctionValidator::visitSetGlobal(SetGlobal* curr) {
- if (!info.validateGlobally)
+ if (!info.validateGlobally) {
return;
+ }
auto* global = getModule()->getGlobalOrNull(curr->name);
if (shouldBeTrue(global,
curr,
@@ -674,10 +691,11 @@ void FunctionValidator::visitLoad(Load* curr) {
curr,
"Atomic load should be i32 or i64");
}
- if (curr->type == v128)
+ if (curr->type == v128) {
shouldBeTrue(getModule()->features.hasSIMD(),
curr,
"SIMD operation (SIMD is disabled)");
+ }
shouldBeFalse(curr->isAtomic && !getModule()->memory.shared,
curr,
"Atomic operation with non-shared memory");
@@ -704,10 +722,11 @@ void FunctionValidator::visitStore(Store* curr) {
curr,
"Atomic store should be i32 or i64");
}
- if (curr->valueType == v128)
+ if (curr->valueType == v128) {
shouldBeTrue(getModule()->features.hasSIMD(),
curr,
"SIMD operation (SIMD is disabled)");
+ }
shouldBeFalse(curr->isAtomic && !getModule()->memory.shared,
curr,
"Atomic operation with non-shared memory");
@@ -1232,8 +1251,9 @@ void FunctionValidator::visitUnary(Unary* curr) {
none,
curr,
"unaries must not receive a none as their input");
- if (curr->value->type == unreachable)
+ if (curr->value->type == unreachable) {
return; // nothing to check
+ }
switch (curr->op) {
case ClzInt32:
case CtzInt32:
@@ -1542,11 +1562,13 @@ void FunctionValidator::visitFunction(Function* curr) {
}
static bool checkOffset(Expression* curr, Address add, Address max) {
- if (curr->is<GetGlobal>())
+ if (curr->is<GetGlobal>()) {
return true;
+ }
auto* c = curr->dynCast<Const>();
- if (!c)
+ if (!c) {
return false;
+ }
uint64_t raw = c->value.getInteger();
if (raw > std::numeric_limits<Address::address_t>::max()) {
return false;
@@ -1763,10 +1785,11 @@ static void validateMemory(Module& module, ValidationInfo& info) {
info.shouldBeTrue(!curr.shared || curr.hasMax(),
"memory",
"shared memory must have max size");
- if (curr.shared)
+ if (curr.shared) {
info.shouldBeTrue(module.features.hasAtomics(),
"memory",
"memory is shared, but atomics are disabled");
+ }
for (auto& segment : curr.segments) {
Index size = segment.data.size();
if (segment.isPassive) {
@@ -1781,8 +1804,9 @@ static void validateMemory(Module& module, ValidationInfo& info) {
if (!info.shouldBeEqual(segment.offset->type,
i32,
segment.offset,
- "segment offset should be i32"))
+ "segment offset should be i32")) {
continue;
+ }
info.shouldBeTrue(checkOffset(segment.offset,
segment.data.size(),
curr.initial * Memory::kPageSize),
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index 22cce6e80..bf12c22d4 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -185,11 +185,13 @@ struct TypeSeeker : public PostWalker<TypeSeeker> {
void visitSwitch(Switch* curr) {
for (auto name : curr->targets) {
- if (name == targetName)
+ if (name == targetName) {
types.push_back(curr->value ? curr->value->type : none);
+ }
}
- if (curr->default_ == targetName)
+ if (curr->default_ == targetName) {
types.push_back(curr->value ? curr->value->type : none);
+ }
}
void visitBlock(Block* curr) {
@@ -243,15 +245,18 @@ static Type mergeTypes(std::vector<Type>& types) {
static void handleUnreachable(Block* block,
bool breakabilityKnown = false,
bool hasBreak = false) {
- if (block->type == unreachable)
+ if (block->type == unreachable) {
return; // nothing to do
- if (block->list.size() == 0)
+ }
+ if (block->list.size() == 0) {
return; // nothing to do
+ }
// if we are concrete, stop - even an unreachable child
// won't change that (since we have a break with a value,
// or the final child flows out a value)
- if (isConcreteType(block->type))
+ if (isConcreteType(block->type)) {
return;
+ }
// look for an unreachable child
for (auto* child : block->list) {
if (child->type == unreachable) {
@@ -280,11 +285,13 @@ void Block::finalize() {
// (return)
// (i32.const 10)
// )
- if (isConcreteType(type))
+ if (isConcreteType(type)) {
return;
+ }
// if we are unreachable, we are done
- if (type == unreachable)
+ if (type == unreachable) {
return;
+ }
// we may still be unreachable if we have an unreachable
// child
for (auto* child : list) {
@@ -398,20 +405,24 @@ void CallIndirect::finalize() {
}
bool FunctionType::structuralComparison(FunctionType& b) {
- if (result != b.result)
+ if (result != b.result) {
return false;
- if (params.size() != b.params.size())
+ }
+ if (params.size() != b.params.size()) {
return false;
+ }
for (size_t i = 0; i < params.size(); i++) {
- if (params[i] != b.params[i])
+ if (params[i] != b.params[i]) {
return false;
+ }
}
return true;
}
bool FunctionType::operator==(FunctionType& b) {
- if (name != b.name)
+ if (name != b.name) {
return false;
+ }
return structuralComparison(b);
}
bool FunctionType::operator!=(FunctionType& b) { return !(*this == b); }
@@ -419,10 +430,11 @@ bool FunctionType::operator!=(FunctionType& b) { return !(*this == b); }
bool SetLocal::isTee() { return type != none; }
void SetLocal::setTee(bool is) {
- if (is)
+ if (is) {
type = value->type;
- else
+ } else {
type = none;
+ }
finalize(); // type may need to be unreachable
}
diff --git a/src/wasm2js.h b/src/wasm2js.h
index 385f8877e..4e5bebb4c 100644
--- a/src/wasm2js.h
+++ b/src/wasm2js.h
@@ -60,12 +60,13 @@ IString EXPRESSION_RESULT("wasm2js$expresult");
// Appends extra to block, flattening out if extra is a block as well
void flattenAppend(Ref ast, Ref extra) {
int index;
- if (ast[0] == BLOCK || ast[0] == TOPLEVEL)
+ if (ast[0] == BLOCK || ast[0] == TOPLEVEL) {
index = 1;
- else if (ast[0] == DEFUN)
+ } else if (ast[0] == DEFUN) {
index = 3;
- else
+ } else {
abort();
+ }
if (extra->isArray() && extra[0] == BLOCK) {
for (size_t i = 0; i < extra[1]->size(); i++) {
ast[index]->push_back(extra[1][i]);
@@ -752,8 +753,9 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m,
bool isBlock(Ref ast) { return !!ast && ast->isArray() && ast[0] == BLOCK; }
Ref blockify(Ref ast) {
- if (isBlock(ast))
+ if (isBlock(ast)) {
return ast;
+ }
Ref ret = ValueBuilder::makeBlock();
ret[1]->push_back(ValueBuilder::makeStatement(ast));
return ret;
@@ -1994,8 +1996,9 @@ void Wasm2JSGlue::emitMemory(
std::string buffer,
std::string segmentWriter,
std::function<std::string(std::string)> accessGlobal) {
- if (wasm.memory.segments.empty())
+ if (wasm.memory.segments.empty()) {
return;
+ }
auto expr = R"(
function(mem) {
@@ -2048,8 +2051,9 @@ void Wasm2JSGlue::emitScratchMemorySupport() {
needScratchMemory = true;
}
});
- if (!needScratchMemory)
+ if (!needScratchMemory) {
return;
+ }
out << R"(
var scratchBuffer = new ArrayBuffer(8);