diff options
-rw-r--r-- | src/binary-writer.cc | 16 | ||||
-rw-r--r-- | src/leb128.cc | 14 | ||||
-rw-r--r-- | src/leb128.h | 1 | ||||
-rw-r--r-- | src/type.h | 2 | ||||
-rw-r--r-- | test/roundtrip/multi-value-block-type.txt | 149 | ||||
-rwxr-xr-x | test/run-roundtrip.py | 2 |
6 files changed, 182 insertions, 2 deletions
diff --git a/src/binary-writer.cc b/src/binary-writer.cc index 5d75fca4..61b61b3b 100644 --- a/src/binary-writer.cc +++ b/src/binary-writer.cc @@ -134,6 +134,9 @@ class BinaryWriter { void WriteU32Leb128WithReloc(Index index, const char* desc, RelocType reloc_type); + void WriteS32Leb128WithReloc(int32_t value, + const char* desc, + RelocType reloc_type); template <typename T> void WriteLoadStoreExpr(const Func* func, const Expr* expr, const char* desc); void WriteExpr(const Func* func, const Expr* expr); @@ -245,7 +248,7 @@ void BinaryWriter::WriteBlockDecl(const BlockDeclaration& decl) { Index index = decl.has_func_type ? module_->GetFuncTypeIndex(decl.type_var) : module_->GetFuncTypeIndex(decl.sig); assert(index != kInvalidIndex); - WriteU32Leb128WithReloc(index, "block type function index", RelocType::TypeIndexLEB); + WriteS32Leb128WithReloc(index, "block type function index", RelocType::TypeIndexLEB); } void BinaryWriter::WriteSectionHeader(const char* desc, @@ -368,6 +371,17 @@ void BinaryWriter::WriteU32Leb128WithReloc(Index index, } } +void BinaryWriter::WriteS32Leb128WithReloc(int32_t value, + const char* desc, + RelocType reloc_type) { + if (options_.relocatable) { + AddReloc(reloc_type, value); + WriteFixedS32Leb128(stream_, value, desc); + } else { + WriteS32Leb128(stream_, value, desc); + } +} + Index BinaryWriter::GetLocalIndex(const Func* func, const Var& var) { // func can be nullptr when using local.get/local.set/local.tee in an // init_expr. diff --git a/src/leb128.cc b/src/leb128.cc index c3decac5..044aaf02 100644 --- a/src/leb128.cc +++ b/src/leb128.cc @@ -138,6 +138,20 @@ void WriteS64Leb128(Stream* stream, uint64_t value, const char* desc) { WriteS64Leb128(stream, Bitcast<int64_t>(value), desc); } +void WriteFixedS32Leb128(Stream* stream, uint32_t value, const char* desc) { + uint8_t data[MAX_U32_LEB128_BYTES]; + data[0] = (value & 0x7f) | 0x80; + data[1] = ((value >> 7) & 0x7f) | 0x80; + data[2] = ((value >> 14) & 0x7f) | 0x80; + data[3] = ((value >> 21) & 0x7f) | 0x80; + // The last byte needs to be sign-extended. + data[4] = ((value >> 28) & 0x0f); + if (static_cast<int32_t>(value) < 0) { + data[4] |= 0x70; + } + stream->WriteData(data, MAX_U32_LEB128_BYTES, desc); +} + #undef LEB128_LOOP_UNTIL #define BYTE_AT(type, i, shift) ((static_cast<type>(p[i]) & 0x7f) << (shift)) diff --git a/src/leb128.h b/src/leb128.h index 4ec74774..5bf4e463 100644 --- a/src/leb128.h +++ b/src/leb128.h @@ -31,6 +31,7 @@ Offset U32Leb128Length(uint32_t value); void WriteU32Leb128(Stream* stream, uint32_t value, const char* desc); void WriteS32Leb128(Stream* stream, uint32_t value, const char* desc); void WriteS64Leb128(Stream* stream, uint64_t value, const char* desc); +void WriteFixedS32Leb128(Stream* stream, uint32_t value, const char* desc); void WriteFixedU32Leb128(Stream* stream, uint32_t value, const char* desc); Offset WriteU32Leb128At(Stream* stream, @@ -33,7 +33,7 @@ using TypeVector = std::vector<Type>; class Type { public: // Matches binary format, do not change. - enum Enum { + enum Enum : int32_t { I32 = -0x01, // 0x7f I64 = -0x02, // 0x7e F32 = -0x03, // 0x7d diff --git a/test/roundtrip/multi-value-block-type.txt b/test/roundtrip/multi-value-block-type.txt new file mode 100644 index 00000000..385a24c5 --- /dev/null +++ b/test/roundtrip/multi-value-block-type.txt @@ -0,0 +1,149 @@ +;;; TOOL: run-roundtrip +;;; ARGS: --stdout --reloc +(module + ;; 64 random types to force the block type below to get encoded as sleb + (type (func (param f32 f32 f32 f32 f32 f32))) + (type (func (param i32 f32 f32 f32 f32 f32))) + (type (func (param f32 i32 f32 f32 f32 f32))) + (type (func (param i32 i32 f32 f32 f32 f32))) + (type (func (param f32 f32 i32 f32 f32 f32))) + (type (func (param i32 f32 i32 f32 f32 f32))) + (type (func (param f32 i32 i32 f32 f32 f32))) + (type (func (param i32 i32 i32 f32 f32 f32))) + (type (func (param f32 f32 f32 i32 f32 f32))) + (type (func (param i32 f32 f32 i32 f32 f32))) + (type (func (param f32 i32 f32 i32 f32 f32))) + (type (func (param i32 i32 f32 i32 f32 f32))) + (type (func (param f32 f32 i32 i32 f32 f32))) + (type (func (param i32 f32 i32 i32 f32 f32))) + (type (func (param f32 i32 i32 i32 f32 f32))) + (type (func (param i32 i32 i32 i32 f32 f32))) + (type (func (param f32 f32 f32 f32 i32 f32))) + (type (func (param i32 f32 f32 f32 i32 f32))) + (type (func (param f32 i32 f32 f32 i32 f32))) + (type (func (param i32 i32 f32 f32 i32 f32))) + (type (func (param f32 f32 i32 f32 i32 f32))) + (type (func (param i32 f32 i32 f32 i32 f32))) + (type (func (param f32 i32 i32 f32 i32 f32))) + (type (func (param i32 i32 i32 f32 i32 f32))) + (type (func (param f32 f32 f32 i32 i32 f32))) + (type (func (param i32 f32 f32 i32 i32 f32))) + (type (func (param f32 i32 f32 i32 i32 f32))) + (type (func (param i32 i32 f32 i32 i32 f32))) + (type (func (param f32 f32 i32 i32 i32 f32))) + (type (func (param i32 f32 i32 i32 i32 f32))) + (type (func (param f32 i32 i32 i32 i32 f32))) + (type (func (param i32 i32 i32 i32 i32 f32))) + (type (func (param f32 f32 f32 f32 f32 i32))) + (type (func (param i32 f32 f32 f32 f32 i32))) + (type (func (param f32 i32 f32 f32 f32 i32))) + (type (func (param i32 i32 f32 f32 f32 i32))) + (type (func (param f32 f32 i32 f32 f32 i32))) + (type (func (param i32 f32 i32 f32 f32 i32))) + (type (func (param f32 i32 i32 f32 f32 i32))) + (type (func (param i32 i32 i32 f32 f32 i32))) + (type (func (param f32 f32 f32 i32 f32 i32))) + (type (func (param i32 f32 f32 i32 f32 i32))) + (type (func (param f32 i32 f32 i32 f32 i32))) + (type (func (param i32 i32 f32 i32 f32 i32))) + (type (func (param f32 f32 i32 i32 f32 i32))) + (type (func (param i32 f32 i32 i32 f32 i32))) + (type (func (param f32 i32 i32 i32 f32 i32))) + (type (func (param i32 i32 i32 i32 f32 i32))) + (type (func (param f32 f32 f32 f32 i32 i32))) + (type (func (param i32 f32 f32 f32 i32 i32))) + (type (func (param f32 i32 f32 f32 i32 i32))) + (type (func (param i32 i32 f32 f32 i32 i32))) + (type (func (param f32 f32 i32 f32 i32 i32))) + (type (func (param i32 f32 i32 f32 i32 i32))) + (type (func (param f32 i32 i32 f32 i32 i32))) + (type (func (param i32 i32 i32 f32 i32 i32))) + (type (func (param f32 f32 f32 i32 i32 i32))) + (type (func (param i32 f32 f32 i32 i32 i32))) + (type (func (param f32 i32 f32 i32 i32 i32))) + (type (func (param i32 i32 f32 i32 i32 i32))) + (type (func (param f32 f32 i32 i32 i32 i32))) + (type (func (param i32 f32 i32 i32 i32 i32))) + (type (func (param f32 i32 i32 i32 i32 i32))) + (type (func (param i32 i32 i32 i32 i32 i32))) + + (func (result i32) + (i32.add + (block (result i32 i32) + (i32.const 32) + (i32.const 10))))) +(;; STDOUT ;;; +(module + (type (;0;) (func (param f32 f32 f32 f32 f32 f32))) + (type (;1;) (func (param i32 f32 f32 f32 f32 f32))) + (type (;2;) (func (param f32 i32 f32 f32 f32 f32))) + (type (;3;) (func (param i32 i32 f32 f32 f32 f32))) + (type (;4;) (func (param f32 f32 i32 f32 f32 f32))) + (type (;5;) (func (param i32 f32 i32 f32 f32 f32))) + (type (;6;) (func (param f32 i32 i32 f32 f32 f32))) + (type (;7;) (func (param i32 i32 i32 f32 f32 f32))) + (type (;8;) (func (param f32 f32 f32 i32 f32 f32))) + (type (;9;) (func (param i32 f32 f32 i32 f32 f32))) + (type (;10;) (func (param f32 i32 f32 i32 f32 f32))) + (type (;11;) (func (param i32 i32 f32 i32 f32 f32))) + (type (;12;) (func (param f32 f32 i32 i32 f32 f32))) + (type (;13;) (func (param i32 f32 i32 i32 f32 f32))) + (type (;14;) (func (param f32 i32 i32 i32 f32 f32))) + (type (;15;) (func (param i32 i32 i32 i32 f32 f32))) + (type (;16;) (func (param f32 f32 f32 f32 i32 f32))) + (type (;17;) (func (param i32 f32 f32 f32 i32 f32))) + (type (;18;) (func (param f32 i32 f32 f32 i32 f32))) + (type (;19;) (func (param i32 i32 f32 f32 i32 f32))) + (type (;20;) (func (param f32 f32 i32 f32 i32 f32))) + (type (;21;) (func (param i32 f32 i32 f32 i32 f32))) + (type (;22;) (func (param f32 i32 i32 f32 i32 f32))) + (type (;23;) (func (param i32 i32 i32 f32 i32 f32))) + (type (;24;) (func (param f32 f32 f32 i32 i32 f32))) + (type (;25;) (func (param i32 f32 f32 i32 i32 f32))) + (type (;26;) (func (param f32 i32 f32 i32 i32 f32))) + (type (;27;) (func (param i32 i32 f32 i32 i32 f32))) + (type (;28;) (func (param f32 f32 i32 i32 i32 f32))) + (type (;29;) (func (param i32 f32 i32 i32 i32 f32))) + (type (;30;) (func (param f32 i32 i32 i32 i32 f32))) + (type (;31;) (func (param i32 i32 i32 i32 i32 f32))) + (type (;32;) (func (param f32 f32 f32 f32 f32 i32))) + (type (;33;) (func (param i32 f32 f32 f32 f32 i32))) + (type (;34;) (func (param f32 i32 f32 f32 f32 i32))) + (type (;35;) (func (param i32 i32 f32 f32 f32 i32))) + (type (;36;) (func (param f32 f32 i32 f32 f32 i32))) + (type (;37;) (func (param i32 f32 i32 f32 f32 i32))) + (type (;38;) (func (param f32 i32 i32 f32 f32 i32))) + (type (;39;) (func (param i32 i32 i32 f32 f32 i32))) + (type (;40;) (func (param f32 f32 f32 i32 f32 i32))) + (type (;41;) (func (param i32 f32 f32 i32 f32 i32))) + (type (;42;) (func (param f32 i32 f32 i32 f32 i32))) + (type (;43;) (func (param i32 i32 f32 i32 f32 i32))) + (type (;44;) (func (param f32 f32 i32 i32 f32 i32))) + (type (;45;) (func (param i32 f32 i32 i32 f32 i32))) + (type (;46;) (func (param f32 i32 i32 i32 f32 i32))) + (type (;47;) (func (param i32 i32 i32 i32 f32 i32))) + (type (;48;) (func (param f32 f32 f32 f32 i32 i32))) + (type (;49;) (func (param i32 f32 f32 f32 i32 i32))) + (type (;50;) (func (param f32 i32 f32 f32 i32 i32))) + (type (;51;) (func (param i32 i32 f32 f32 i32 i32))) + (type (;52;) (func (param f32 f32 i32 f32 i32 i32))) + (type (;53;) (func (param i32 f32 i32 f32 i32 i32))) + (type (;54;) (func (param f32 i32 i32 f32 i32 i32))) + (type (;55;) (func (param i32 i32 i32 f32 i32 i32))) + (type (;56;) (func (param f32 f32 f32 i32 i32 i32))) + (type (;57;) (func (param i32 f32 f32 i32 i32 i32))) + (type (;58;) (func (param f32 i32 f32 i32 i32 i32))) + (type (;59;) (func (param i32 i32 f32 i32 i32 i32))) + (type (;60;) (func (param f32 f32 i32 i32 i32 i32))) + (type (;61;) (func (param i32 f32 i32 i32 i32 i32))) + (type (;62;) (func (param f32 i32 i32 i32 i32 i32))) + (type (;63;) (func (param i32 i32 i32 i32 i32 i32))) + (type (;64;) (func (result i32))) + (type (;65;) (func (result i32 i32))) + (func (;0;) (type 64) (result i32) + block (result i32 i32) ;; label = @1 + i32.const 32 + i32.const 10 + end + i32.add)) +;;; STDOUT ;;) diff --git a/test/run-roundtrip.py b/test/run-roundtrip.py index 46e96430..8aef6f55 100755 --- a/test/run-roundtrip.py +++ b/test/run-roundtrip.py @@ -126,6 +126,7 @@ def main(args): parser.add_argument('--enable-memory64', action='store_true') parser.add_argument('--inline-exports', action='store_true') parser.add_argument('--inline-imports', action='store_true') + parser.add_argument('--reloc', action='store_true') parser.add_argument('file', help='test file.') options = parser.parse_args(args) @@ -145,6 +146,7 @@ def main(args): '--enable-tail-call': options.enable_tail_call, '--enable-reference-types': options.enable_reference_types, '--enable-memory64': options.enable_memory64, + '--reloc': options.reloc, '--no-check': options.no_check, }) |