summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-binary.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r--src/wasm/wasm-binary.cpp91
1 files changed, 59 insertions, 32 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 54e417b8c..3aace6721 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -226,6 +226,16 @@ void WasmBinaryWriter::writeTypes() {
writeType(type);
}
}
+ } else if (type.isStruct()) {
+ o << S32LEB(BinaryConsts::EncodedType::Struct);
+ auto fields = type.getStruct().fields;
+ o << U32LEB(fields.size());
+ for (const auto& field : fields) {
+ writeField(field);
+ }
+ } else if (type.isArray()) {
+ o << S32LEB(BinaryConsts::EncodedType::Array);
+ writeField(type.getArray().element);
} else {
WASM_UNREACHABLE("TODO GC type writing");
}
@@ -495,11 +505,11 @@ uint32_t WasmBinaryWriter::getEventIndex(Name name) const {
return it->second;
}
-uint32_t WasmBinaryWriter::getTypeIndex(Signature sig) const {
- auto it = typeIndices.find(sig);
+uint32_t WasmBinaryWriter::getTypeIndex(HeapType type) const {
+ auto it = typeIndices.find(type);
#ifndef NDEBUG
if (it == typeIndices.end()) {
- std::cout << "Missing signature: " << sig << '\n';
+ std::cout << "Missing type: " << type << '\n';
assert(0);
}
#endif
@@ -963,18 +973,14 @@ void WasmBinaryWriter::finishUp() {
}
void WasmBinaryWriter::writeType(Type type) {
- if (type.isRef()) {
- auto heapType = type.getHeapType();
- // TODO: fully handle non-signature reference types (GC), and in reading
- if (heapType.isSignature()) {
- if (type.isNullable()) {
- o << S32LEB(BinaryConsts::EncodedType::nullable);
- } else {
- o << S32LEB(BinaryConsts::EncodedType::nonnullable);
- }
- writeHeapType(heapType);
- return;
+ if (type.isRef() && !type.isBasic()) {
+ if (type.isNullable()) {
+ o << S32LEB(BinaryConsts::EncodedType::nullable);
+ } else {
+ o << S32LEB(BinaryConsts::EncodedType::nonnullable);
}
+ writeHeapType(type.getHeapType());
+ return;
}
int ret = 0;
TODO_SINGLE_COMPOUND(type);
@@ -1023,9 +1029,8 @@ void WasmBinaryWriter::writeType(Type type) {
}
void WasmBinaryWriter::writeHeapType(HeapType type) {
- if (type.isSignature()) {
- auto sig = type.getSignature();
- o << S32LEB(getTypeIndex(sig));
+ if (type.isSignature() || type.isStruct() || type.isArray()) {
+ o << S32LEB(getTypeIndex(type));
return;
}
int ret = 0;
@@ -1056,6 +1061,11 @@ void WasmBinaryWriter::writeHeapType(HeapType type) {
o << S32LEB(ret); // TODO: Actually encoded as s33
}
+void WasmBinaryWriter::writeField(const Field& field) {
+ writeType(field.type);
+ o << U32LEB(field.mutable_);
+}
+
// reader
bool WasmBinaryBuilder::hasDWARFSections() {
@@ -1397,6 +1407,12 @@ HeapType WasmBinaryBuilder::getHeapType() {
WASM_UNREACHABLE("unexpected type");
}
+Field WasmBinaryBuilder::getField() {
+ auto type = getConcreteType();
+ auto mutable_ = getU32LEB();
+ return Field(type, mutable_);
+}
+
Type WasmBinaryBuilder::getConcreteType() {
auto type = getType();
if (!type.isConcrete()) {
@@ -1493,23 +1509,34 @@ void WasmBinaryBuilder::readTypes() {
BYN_TRACE("num: " << numTypes << std::endl);
for (size_t i = 0; i < numTypes; i++) {
BYN_TRACE("read one\n");
- std::vector<Type> params;
- std::vector<Type> results;
auto form = getS32LEB();
- if (form != BinaryConsts::EncodedType::Func) {
- throwError("bad signature form " + std::to_string(form));
- }
- size_t numParams = getU32LEB();
- BYN_TRACE("num params: " << numParams << std::endl);
- for (size_t j = 0; j < numParams; j++) {
- params.push_back(getConcreteType());
- }
- auto numResults = getU32LEB();
- BYN_TRACE("num results: " << numResults << std::endl);
- for (size_t j = 0; j < numResults; j++) {
- results.push_back(getConcreteType());
+ if (form == BinaryConsts::EncodedType::Func) {
+ std::vector<Type> params;
+ std::vector<Type> results;
+ size_t numParams = getU32LEB();
+ BYN_TRACE("num params: " << numParams << std::endl);
+ for (size_t j = 0; j < numParams; j++) {
+ params.push_back(getConcreteType());
+ }
+ auto numResults = getU32LEB();
+ BYN_TRACE("num results: " << numResults << std::endl);
+ for (size_t j = 0; j < numResults; j++) {
+ results.push_back(getConcreteType());
+ }
+ types.emplace_back(Signature(Type(params), Type(results)));
+ } else if (form == BinaryConsts::EncodedType::Struct) {
+ FieldList fields;
+ size_t numFields = getU32LEB();
+ BYN_TRACE("num fields: " << numFields << std::endl);
+ for (size_t j = 0; j < numFields; j++) {
+ fields.push_back(getField());
+ }
+ types.emplace_back(Struct(fields));
+ } else if (form == BinaryConsts::EncodedType::Array) {
+ types.emplace_back(Array(getField()));
+ } else {
+ throwError("bad type form " + std::to_string(form));
}
- types.emplace_back(Signature(Type(params), Type(results)));
}
}