summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/asm2wasm.h12
-rw-r--r--src/passes/Print.cpp6
-rw-r--r--src/wasm-binary.h9
-rw-r--r--src/wasm-s-parser.h3
-rw-r--r--src/wasm-validator.h2
5 files changed, 26 insertions, 6 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h
index bce67a582..1c528d7f3 100644
--- a/src/asm2wasm.h
+++ b/src/asm2wasm.h
@@ -177,6 +177,7 @@ private:
else if (type == f64) value = Literal(double(0));
else WASM_UNREACHABLE();
global->init = wasm.allocator.alloc<Const>()->set(value);
+ global->mutable_ = true;
wasm.addGlobal(global);
}
@@ -502,9 +503,20 @@ void Asm2WasmBuilder::processAsm(Ref ast) {
type = WasmType::f64;
}
if (type != WasmType::none) {
+ // we need imported globals to be mutable, but wasm doesn't support that yet, so we must
+ // import an immutable and create a mutable global initialized to its value
+ import->name = Name(std::string(import->name.str) + "$asm2wasm$import");
import->kind = Import::Global;
import->globalType = type;
mappedGlobals.emplace(name, type);
+ {
+ auto global = new Global();
+ global->name = name;
+ global->type = type;
+ global->init = builder.makeGetGlobal(import->name, type);
+ global->mutable_ = true;
+ wasm.addGlobal(global);
+ }
} else {
import->kind = Import::Function;
}
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 4cb363e66..06a8758c5 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -563,7 +563,11 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
void visitGlobal(Global *curr) {
printOpening(o, "global ");
printName(curr->name) << ' ';
- o << printWasmType(curr->type) << ' ';
+ if (curr->mutable_) {
+ o << "(mut " << printWasmType(curr->type) << ") ";
+ } else {
+ o << printWasmType(curr->type) << ' ';
+ }
visit(curr->init);
o << ')';
}
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 147746c82..1bc18e687 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -1293,8 +1293,13 @@ public:
else if (match(BinaryConsts::Section::FunctionSignatures)) readFunctionSignatures();
else if (match(BinaryConsts::Section::Functions)) readFunctions();
else if (match(BinaryConsts::Section::ExportTable)) readExports();
- else if (match(BinaryConsts::Section::Globals)) readGlobals();
- else if (match(BinaryConsts::Section::DataSegments)) readDataSegments();
+ else if (match(BinaryConsts::Section::Globals)) {
+ readGlobals();
+ // imports can read global imports, so we run getGlobalName and create the mapping
+ // but after we read globals, we need to add the internal globals too, so do that here
+ mappedGlobals.clear(); // wipe the mapping
+ getGlobalName(0); // force rebuild
+ } else if (match(BinaryConsts::Section::DataSegments)) readDataSegments();
else if (match(BinaryConsts::Section::FunctionTable)) readFunctionTable();
else if (match(BinaryConsts::Section::Names)) readNames();
else {
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index b4fcd3466..6280de7d3 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -1517,8 +1517,7 @@ private:
ex->kind = Export::Table;
} else if (inner[0]->str() == GLOBAL) {
ex->kind = Export::Global;
- auto* global = wasm.getGlobal(ex->value);
- if (global->mutable_) throw ParseException("cannot export a mutable global", s.line, s.col);
+ if (wasm.checkGlobal(ex->value) && wasm.getGlobal(ex->value)->mutable_) throw ParseException("cannot export a mutable global", s.line, s.col);
} else {
WASM_UNREACHABLE();
}
diff --git a/src/wasm-validator.h b/src/wasm-validator.h
index 1d3b5c41b..6c6792228 100644
--- a/src/wasm-validator.h
+++ b/src/wasm-validator.h
@@ -335,7 +335,7 @@ public:
}
void visitGlobal(Global* curr) {
- shouldBeTrue(curr->init->is<Const>(), curr->name, "global init must be valid");
+ shouldBeTrue(curr->init->is<Const>() || curr->init->is<GetGlobal>(), curr->name, "global init must be valid");
shouldBeEqual(curr->type, curr->init->type, nullptr, "global init must have correct type");
}