summaryrefslogtreecommitdiffstats
path: root/js/src/wasm/WasmBinary.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/wasm/WasmBinary.h')
-rw-r--r--js/src/wasm/WasmBinary.h47
1 files changed, 36 insertions, 11 deletions
diff --git a/js/src/wasm/WasmBinary.h b/js/src/wasm/WasmBinary.h
index 2d41528157..da17a0a864 100644
--- a/js/src/wasm/WasmBinary.h
+++ b/js/src/wasm/WasmBinary.h
@@ -72,12 +72,18 @@ class Opcode {
static_assert(size_t(SimdOp::Limit) <= 0xFFFFFF, "fits");
MOZ_ASSERT(size_t(op) < size_t(SimdOp::Limit));
}
+ MOZ_IMPLICIT Opcode(GcOp op)
+ : bits_((uint32_t(op) << 8) | uint32_t(Op::GcPrefix)) {
+ static_assert(size_t(SimdOp::Limit) <= 0xFFFFFF, "fits");
+ MOZ_ASSERT(size_t(op) < size_t(SimdOp::Limit));
+ }
bool isOp() const { return bits_ < uint32_t(Op::FirstPrefix); }
bool isMisc() const { return (bits_ & 255) == uint32_t(Op::MiscPrefix); }
bool isThread() const { return (bits_ & 255) == uint32_t(Op::ThreadPrefix); }
bool isMoz() const { return (bits_ & 255) == uint32_t(Op::MozPrefix); }
bool isSimd() const { return (bits_ & 255) == uint32_t(Op::SimdPrefix); }
+ bool isGc() const { return (bits_ & 255) == uint32_t(Op::GcPrefix); }
Op asOp() const {
MOZ_ASSERT(isOp());
@@ -99,6 +105,10 @@ class Opcode {
MOZ_ASSERT(isSimd());
return SimdOp(bits_ >> 8);
}
+ GcOp asGc() const {
+ MOZ_ASSERT(isGc());
+ return GcOp(bits_ >> 8);
+ }
uint32_t bits() const { return bits_; }
@@ -127,6 +137,7 @@ using MaybeSectionRange = Maybe<SectionRange>;
class Encoder {
Bytes& bytes_;
+ const TypeContext* types_;
template <class T>
[[nodiscard]] bool write(const T& v) {
@@ -201,7 +212,13 @@ class Encoder {
}
public:
- explicit Encoder(Bytes& bytes) : bytes_(bytes) { MOZ_ASSERT(empty()); }
+ explicit Encoder(Bytes& bytes) : bytes_(bytes), types_(nullptr) {
+ MOZ_ASSERT(empty());
+ }
+ explicit Encoder(Bytes& bytes, const TypeContext& types)
+ : bytes_(bytes), types_(&types) {
+ MOZ_ASSERT(empty());
+ }
size_t currentOffset() const { return bytes_.length(); }
bool empty() const { return currentOffset() == 0; }
@@ -226,9 +243,17 @@ class Encoder {
[[nodiscard]] bool writeVarS64(int64_t i) { return writeVarS<int64_t>(i); }
[[nodiscard]] bool writeValType(ValType type) {
static_assert(size_t(TypeCode::Limit) <= UINT8_MAX, "fits");
- // writeValType is only used by asm.js, which doesn't use type
- // references
- MOZ_RELEASE_ASSERT(!type.isTypeRef(), "NYI");
+ if (type.isTypeRef()) {
+ MOZ_RELEASE_ASSERT(types_,
+ "writeValType is used, but types were not specified.");
+ if (!writeFixedU8(uint8_t(type.isNullable() ? TypeCode::NullableRef
+ : TypeCode::Ref))) {
+ return false;
+ }
+ uint32_t typeIndex = types_->indexOf(*type.typeDef());
+ // Encode positive LEB S33 as S64.
+ return writeVarS64(typeIndex);
+ }
TypeCode tc = type.packed().typeCode();
MOZ_ASSERT(size_t(tc) < size_t(TypeCode::Limit));
return writeFixedU8(uint8_t(tc));
@@ -693,9 +718,9 @@ inline bool Decoder::readPackedType(const TypeContext& types,
}
case uint8_t(TypeCode::Ref):
case uint8_t(TypeCode::NullableRef): {
-#ifdef ENABLE_WASM_FUNCTION_REFERENCES
- if (!features.functionReferences) {
- return fail("(ref T) types not enabled");
+#ifdef ENABLE_WASM_GC
+ if (!features.gc) {
+ return fail("gc not enabled");
}
bool nullable = code == uint8_t(TypeCode::NullableRef);
RefType refType;
@@ -718,7 +743,7 @@ inline bool Decoder::readPackedType(const TypeContext& types,
case uint8_t(TypeCode::NullAnyRef): {
#ifdef ENABLE_WASM_GC
if (!features.gc) {
- return fail("gc types not enabled");
+ return fail("gc not enabled");
}
*type = RefType::fromTypeCode(TypeCode(code), true);
return true;
@@ -784,7 +809,7 @@ inline bool Decoder::readHeapType(const TypeContext& types,
case uint8_t(TypeCode::NullExternRef):
case uint8_t(TypeCode::NullAnyRef):
if (!features.gc) {
- return fail("gc types not enabled");
+ return fail("gc not enabled");
}
*type = RefType::fromTypeCode(TypeCode(code), nullable);
return true;
@@ -794,8 +819,8 @@ inline bool Decoder::readHeapType(const TypeContext& types,
}
}
-#ifdef ENABLE_WASM_FUNCTION_REFERENCES
- if (features.functionReferences) {
+#ifdef ENABLE_WASM_GC
+ if (features.gc) {
int32_t x;
if (!readVarS32(&x) || x < 0 || uint32_t(x) >= types.length()) {
return fail("invalid heap type index");