diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/wasm-ctor-eval.cpp | 29 | ||||
-rw-r--r-- | src/wasm-builder.h | 4 |
2 files changed, 29 insertions, 4 deletions
diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index 00bceac8f..195a5350f 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -572,13 +572,28 @@ public: // If |possibleDefiningGlobal| is provided, it is the name of a global that we // are in the init expression of, and which can be reused as defining global, // if the other conditions are suitable. - Expression* getSerialization(const Literal& value, + Expression* getSerialization(Literal value, Name possibleDefiningGlobal = Name()) { Builder builder(*wasm); + // If this is externalized then we want to inspect the inner data, handle + // that, and emit a ref.externalize around it as needed. To simplify the + // logic here, we save the original (possible externalized) value, and then + // look at the internals from here on out. + Literal original = value; + if (value.type.isRef() && value.type.getHeapType() == HeapType::ext) { + value = value.internalize(); + + // We cannot serialize truly external things, only data and i31s. + assert(value.isData() || value.type.getHeapType() == HeapType::i31); + } + + // GC data (structs and arrays) must be handled with the special global- + // creating logic later down. But MVP types as well as i31s (even + // externalized i31s) can be handled by the general makeConstantExpression + // logic (which knows how to handle externalization, for i31s). if (!value.isData()) { - // This can be handled normally. - return builder.makeConstantExpression(value); + return builder.makeConstantExpression(original); } // This is GC data, which we must handle in a more careful way. @@ -637,7 +652,13 @@ public: // Refer to this GC allocation by reading from the global that is // designated to contain it. - return builder.makeGlobalGet(definingGlobal, value.type); + Expression* ret = builder.makeGlobalGet(definingGlobal, value.type); + if (original != value) { + // The original is externalized. + assert(original.type.getHeapType() == HeapType::ext); + ret = builder.makeRefAs(ExternExternalize, ret); + } + return ret; } Expression* getSerialization(const Literals& values, diff --git a/src/wasm-builder.h b/src/wasm-builder.h index cbdd7abf7..8b34d6933 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -1155,6 +1155,10 @@ public: } return makeStringConst(string); } + if (type.isRef() && type.getHeapType() == HeapType::ext) { + return makeRefAs(ExternExternalize, + makeConstantExpression(value.internalize())); + } TODO_SINGLE_COMPOUND(type); WASM_UNREACHABLE("unsupported constant expression"); } |