Consistently uses LEB128 signed encoding for global constants (#443)

Global constants can be defined in wasm or in ModuleBuilder. In either
case, they end up being decoded and interpreted during instantiation.
This chooses signed encoding to avoid surprises. A more comprehensive
explanation was added to RATIONALE.md, but the motivation was a global
100 coming out negative.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
Crypt Keeper
2022-04-06 09:50:47 +08:00
committed by GitHub
parent f5598c9a8e
commit fb0b311844
22 changed files with 188 additions and 68 deletions

View File

@@ -107,7 +107,7 @@ type ModuleBuilder interface {
//
// Note: If a global is already exported with the same name, this overwrites it.
// Note: The maximum value of v is math.MaxInt32 to match constraints of initialization in binary format.
// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#value-types%E2%91%A2
// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#value-types%E2%91%A0
// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#syntax-globaltype
ExportGlobalI32(name string, v int32) ModuleBuilder
@@ -119,7 +119,7 @@ type ModuleBuilder interface {
//
// Note: If a global is already exported with the same name, this overwrites it.
// Note: The maximum value of v is math.MaxInt64 to match constraints of initialization in binary format.
// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#value-types%E2%91%A2
// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#value-types%E2%91%A0
// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#syntax-globaltype
ExportGlobalI64(name string, v int64) ModuleBuilder
@@ -202,8 +202,8 @@ func (b *moduleBuilder) ExportMemoryWithMax(name string, minPages, maxPages uint
func (b *moduleBuilder) ExportGlobalI32(name string, v int32) ModuleBuilder {
b.nameToGlobal[name] = &wasm.Global{
Type: &wasm.GlobalType{ValType: wasm.ValueTypeI32},
// Signed per https://www.w3.org/TR/wasm-core-1/#value-types%E2%91%A2
Init: &wasm.ConstantExpression{Opcode: wasm.OpcodeI32Const, Data: leb128.EncodeUint32(uint32(v))},
// Treat constants as signed as their interpretation is not yet known per /RATIONALE.md
Init: &wasm.ConstantExpression{Opcode: wasm.OpcodeI32Const, Data: leb128.EncodeInt32(v)},
}
return b
}
@@ -212,8 +212,8 @@ func (b *moduleBuilder) ExportGlobalI32(name string, v int32) ModuleBuilder {
func (b *moduleBuilder) ExportGlobalI64(name string, v int64) ModuleBuilder {
b.nameToGlobal[name] = &wasm.Global{
Type: &wasm.GlobalType{ValType: wasm.ValueTypeI64},
// Signed per https://www.w3.org/TR/wasm-core-1/#value-types%E2%91%A2
Init: &wasm.ConstantExpression{Opcode: wasm.OpcodeI64Const, Data: leb128.EncodeUint64(uint64(v))},
// Treat constants as signed as their interpretation is not yet known per /RATIONALE.md
Init: &wasm.ConstantExpression{Opcode: wasm.OpcodeI64Const, Data: leb128.EncodeInt64(v)},
}
return b
}