Adds SplitCallStack for use in CallWithStack (#1414)
This adds an internal function `wasm.SplitCallStack` for use in #1407. This is separate because the diff is a lot larger than the destination change ;) Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
@@ -1935,3 +1935,20 @@ var (
|
|||||||
blockType_v_funcref = &FunctionType{Results: []ValueType{ValueTypeFuncref}, ResultNumInUint64: 1}
|
blockType_v_funcref = &FunctionType{Results: []ValueType{ValueTypeFuncref}, ResultNumInUint64: 1}
|
||||||
blockType_v_externref = &FunctionType{Results: []ValueType{ValueTypeExternref}, ResultNumInUint64: 1}
|
blockType_v_externref = &FunctionType{Results: []ValueType{ValueTypeExternref}, ResultNumInUint64: 1}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// SplitCallStack returns the input stack resliced to the count of params and
|
||||||
|
// results, or errors if it isn't long enough for either.
|
||||||
|
func SplitCallStack(ft *FunctionType, stack []uint64) (params []uint64, results []uint64, err error) {
|
||||||
|
stackLen := len(stack)
|
||||||
|
if n := ft.ParamNumInUint64; n > stackLen {
|
||||||
|
return nil, nil, fmt.Errorf("need %d params, but stack size is %d", n, stackLen)
|
||||||
|
} else if n > 0 {
|
||||||
|
params = stack[:n]
|
||||||
|
}
|
||||||
|
if n := ft.ResultNumInUint64; n > stackLen {
|
||||||
|
return nil, nil, fmt.Errorf("need %d results, but stack size is %d", n, stackLen)
|
||||||
|
} else if n > 0 {
|
||||||
|
results = stack[:n]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@@ -673,23 +673,31 @@ func TestModule_ValidateFunction_BulkMemoryOperations(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
f32, f64, i32, i64, externref = ValueTypeF32, ValueTypeF64, ValueTypeI32, ValueTypeI64, ValueTypeExternref
|
f32, f64, i32, i64, v128, externref = ValueTypeF32, ValueTypeF64, ValueTypeI32, ValueTypeI64, ValueTypeV128, ValueTypeExternref
|
||||||
f32i32_v = FunctionType{Params: []ValueType{f32, i32}}
|
f32i32_v = initFt([]ValueType{f32, i32}, nil)
|
||||||
i32_i32 = FunctionType{Params: []ValueType{i32}, Results: []ValueType{i32}}
|
f64f32_i64 = initFt([]ValueType{f64, f32}, []ValueType{i64})
|
||||||
i32f64_v = FunctionType{Params: []ValueType{i32, f64}}
|
f64i32_v128i64 = initFt([]ValueType{f64, i32}, []ValueType{v128, i64})
|
||||||
i32i32_i32 = FunctionType{Params: []ValueType{i32, i32}, Results: []ValueType{i32}}
|
i32_i32 = initFt([]ValueType{i32}, []ValueType{i32})
|
||||||
i32_v = FunctionType{Params: []ValueType{i32}}
|
i32f64_v = initFt([]ValueType{i32, f64}, nil)
|
||||||
v_v = FunctionType{}
|
i32i32_i32 = initFt([]ValueType{i32, i32}, []ValueType{i32})
|
||||||
v_f32 = FunctionType{Results: []ValueType{f32}}
|
i32_v = initFt([]ValueType{i32}, nil)
|
||||||
v_f32f32 = FunctionType{Results: []ValueType{f32, f32}}
|
v_v = FunctionType{}
|
||||||
v_f64i32 = FunctionType{Results: []ValueType{f64, i32}}
|
v_f32 = initFt(nil, []ValueType{f32})
|
||||||
v_f64f64 = FunctionType{Results: []ValueType{f64, f64}}
|
v_f32f32 = initFt(nil, []ValueType{f32, f32})
|
||||||
v_i32 = FunctionType{Results: []ValueType{i32}}
|
v_f64i32 = initFt(nil, []ValueType{f64, i32})
|
||||||
v_i32i32 = FunctionType{Results: []ValueType{i32, i32}}
|
v_f64f64 = initFt(nil, []ValueType{f64, f64})
|
||||||
v_i32i64 = FunctionType{Results: []ValueType{i32, i64}}
|
v_i32 = initFt(nil, []ValueType{i32})
|
||||||
v_i64i64 = FunctionType{Results: []ValueType{i64, i64}}
|
v_i32i32 = initFt(nil, []ValueType{i32, i32})
|
||||||
|
v_i32i64 = initFt(nil, []ValueType{i32, i64})
|
||||||
|
v_i64i64 = initFt(nil, []ValueType{i64, i64})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func initFt(params, results []ValueType) FunctionType {
|
||||||
|
ft := FunctionType{Params: params, Results: results}
|
||||||
|
ft.CacheNumInUint64()
|
||||||
|
return ft
|
||||||
|
}
|
||||||
|
|
||||||
// TestModule_ValidateFunction_MultiValue_TypeMismatch are "type mismatch" tests when "multi-value" was merged.
|
// TestModule_ValidateFunction_MultiValue_TypeMismatch are "type mismatch" tests when "multi-value" was merged.
|
||||||
//
|
//
|
||||||
// See https://github.com/WebAssembly/spec/commit/484180ba3d9d7638ba1cb400b699ffede796927c
|
// See https://github.com/WebAssembly/spec/commit/484180ba3d9d7638ba1cb400b699ffede796927c
|
||||||
@@ -3591,3 +3599,82 @@ func TestFunctionValidation_redundantElse(t *testing.T) {
|
|||||||
0, nil, nil, nil, nil, nil, bytes.NewReader(nil))
|
0, nil, nil, nil, nil, nil, bytes.NewReader(nil))
|
||||||
require.EqualError(t, err, "redundant Else instruction at 0x1")
|
require.EqualError(t, err, "redundant Else instruction at 0x1")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_SplitCallStack(t *testing.T) {
|
||||||
|
oneToEight := []uint64{1, 2, 3, 4, 5, 6, 7, 8}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
ft *FunctionType
|
||||||
|
stack, expectedParams, expectedResults []uint64
|
||||||
|
expectedErr string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "v_v",
|
||||||
|
ft: &v_v,
|
||||||
|
stack: oneToEight,
|
||||||
|
expectedParams: nil,
|
||||||
|
expectedResults: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "v_v - stack nil",
|
||||||
|
ft: &v_v,
|
||||||
|
expectedParams: nil,
|
||||||
|
expectedResults: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "v_i32",
|
||||||
|
ft: &v_i32,
|
||||||
|
stack: oneToEight,
|
||||||
|
expectedParams: nil,
|
||||||
|
expectedResults: []uint64{1},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "f32i32_v",
|
||||||
|
ft: &f32i32_v,
|
||||||
|
stack: oneToEight,
|
||||||
|
expectedParams: []uint64{1, 2},
|
||||||
|
expectedResults: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "f64f32_i64",
|
||||||
|
ft: &f64f32_i64,
|
||||||
|
stack: oneToEight,
|
||||||
|
expectedParams: []uint64{1, 2},
|
||||||
|
expectedResults: []uint64{1},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "f64i32_v128i64",
|
||||||
|
ft: &f64i32_v128i64,
|
||||||
|
stack: oneToEight,
|
||||||
|
expectedParams: []uint64{1, 2},
|
||||||
|
expectedResults: []uint64{1, 2, 3},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "not enough room for params",
|
||||||
|
ft: &f64i32_v128i64,
|
||||||
|
stack: oneToEight[0:1],
|
||||||
|
expectedErr: "need 2 params, but stack size is 1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "not enough room for results",
|
||||||
|
ft: &f64i32_v128i64,
|
||||||
|
stack: oneToEight[0:2],
|
||||||
|
expectedErr: "need 3 results, but stack size is 2",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
tc := tt
|
||||||
|
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
params, results, err := SplitCallStack(tc.ft, tc.stack)
|
||||||
|
if tc.expectedErr != "" {
|
||||||
|
require.EqualError(t, err, tc.expectedErr)
|
||||||
|
} else {
|
||||||
|
require.Equal(t, tc.expectedParams, params)
|
||||||
|
require.Equal(t, tc.expectedResults, results)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -103,8 +103,8 @@ func TestModule_BuildFunctionDefinitions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
TypeSection: []FunctionType{
|
TypeSection: []FunctionType{
|
||||||
v_v,
|
v_v,
|
||||||
{Params: []ValueType{ValueTypeF64, ValueTypeI32}, Results: []ValueType{ValueTypeV128, ValueTypeI64}},
|
f64i32_v128i64,
|
||||||
{Params: []ValueType{ValueTypeF64, ValueTypeF32}, Results: []ValueType{ValueTypeI64}},
|
f64f32_i64,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: []FunctionDefinition{
|
expected: []FunctionDefinition{
|
||||||
@@ -112,13 +112,13 @@ func TestModule_BuildFunctionDefinitions(t *testing.T) {
|
|||||||
index: 0,
|
index: 0,
|
||||||
debugName: ".$0",
|
debugName: ".$0",
|
||||||
exportNames: []string{"function_index=0"},
|
exportNames: []string{"function_index=0"},
|
||||||
funcType: &FunctionType{Params: []ValueType{ValueTypeF64, ValueTypeI32}, Results: []ValueType{ValueTypeV128, ValueTypeI64}},
|
funcType: &f64i32_v128i64,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
index: 1,
|
index: 1,
|
||||||
debugName: ".$1",
|
debugName: ".$1",
|
||||||
exportNames: []string{"function_index=1"},
|
exportNames: []string{"function_index=1"},
|
||||||
funcType: &FunctionType{Params: []ValueType{ValueTypeF64, ValueTypeF32}, Results: []ValueType{ValueTypeI64}},
|
funcType: &f64f32_i64,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
index: 2,
|
index: 2,
|
||||||
@@ -132,13 +132,13 @@ func TestModule_BuildFunctionDefinitions(t *testing.T) {
|
|||||||
index: 0,
|
index: 0,
|
||||||
debugName: ".$0",
|
debugName: ".$0",
|
||||||
exportNames: []string{"function_index=0"},
|
exportNames: []string{"function_index=0"},
|
||||||
funcType: &FunctionType{Params: []ValueType{ValueTypeF64, ValueTypeI32}, Results: []ValueType{ValueTypeV128, ValueTypeI64}},
|
funcType: &f64i32_v128i64,
|
||||||
},
|
},
|
||||||
"function_index=1": &FunctionDefinition{
|
"function_index=1": &FunctionDefinition{
|
||||||
index: 1,
|
index: 1,
|
||||||
exportNames: []string{"function_index=1"},
|
exportNames: []string{"function_index=1"},
|
||||||
debugName: ".$1",
|
debugName: ".$1",
|
||||||
funcType: &FunctionType{Params: []ValueType{ValueTypeF64, ValueTypeF32}, Results: []ValueType{ValueTypeI64}},
|
funcType: &f64f32_i64,
|
||||||
},
|
},
|
||||||
"function_index=2": &FunctionDefinition{
|
"function_index=2": &FunctionDefinition{
|
||||||
index: 2,
|
index: 2,
|
||||||
@@ -162,8 +162,8 @@ func TestModule_BuildFunctionDefinitions(t *testing.T) {
|
|||||||
CodeSection: []Code{{Body: []byte{OpcodeEnd}}, {Body: []byte{OpcodeEnd}}},
|
CodeSection: []Code{{Body: []byte{OpcodeEnd}}, {Body: []byte{OpcodeEnd}}},
|
||||||
TypeSection: []FunctionType{
|
TypeSection: []FunctionType{
|
||||||
v_v,
|
v_v,
|
||||||
{Params: []ValueType{ValueTypeF64, ValueTypeI32}, Results: []ValueType{ValueTypeV128, ValueTypeI64}},
|
f64i32_v128i64,
|
||||||
{Params: []ValueType{ValueTypeF64, ValueTypeF32}, Results: []ValueType{ValueTypeI64}},
|
f64f32_i64,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: []FunctionDefinition{
|
expected: []FunctionDefinition{
|
||||||
@@ -172,13 +172,13 @@ func TestModule_BuildFunctionDefinitions(t *testing.T) {
|
|||||||
debugName: ".$0",
|
debugName: ".$0",
|
||||||
importDesc: imp,
|
importDesc: imp,
|
||||||
exportNames: []string{"imported_function"},
|
exportNames: []string{"imported_function"},
|
||||||
funcType: &FunctionType{Params: []ValueType{ValueTypeF64, ValueTypeF32}, Results: []ValueType{ValueTypeI64}},
|
funcType: &f64f32_i64,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
index: 1,
|
index: 1,
|
||||||
debugName: ".$1",
|
debugName: ".$1",
|
||||||
exportNames: []string{"function_index=1"},
|
exportNames: []string{"function_index=1"},
|
||||||
funcType: &FunctionType{Params: []ValueType{ValueTypeF64, ValueTypeI32}, Results: []ValueType{ValueTypeV128, ValueTypeI64}},
|
funcType: &f64i32_v128i64,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
index: 2,
|
index: 2,
|
||||||
@@ -193,7 +193,7 @@ func TestModule_BuildFunctionDefinitions(t *testing.T) {
|
|||||||
debugName: ".$0",
|
debugName: ".$0",
|
||||||
importDesc: imp,
|
importDesc: imp,
|
||||||
exportNames: []string{"imported_function"},
|
exportNames: []string{"imported_function"},
|
||||||
funcType: &FunctionType{Params: []ValueType{ValueTypeF64, ValueTypeF32}, Results: []ValueType{ValueTypeI64}},
|
funcType: &f64f32_i64,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedExports: map[string]api.FunctionDefinition{
|
expectedExports: map[string]api.FunctionDefinition{
|
||||||
@@ -202,13 +202,13 @@ func TestModule_BuildFunctionDefinitions(t *testing.T) {
|
|||||||
debugName: ".$0",
|
debugName: ".$0",
|
||||||
importDesc: imp,
|
importDesc: imp,
|
||||||
exportNames: []string{"imported_function"},
|
exportNames: []string{"imported_function"},
|
||||||
funcType: &FunctionType{Params: []ValueType{ValueTypeF64, ValueTypeF32}, Results: []ValueType{ValueTypeI64}},
|
funcType: &f64f32_i64,
|
||||||
},
|
},
|
||||||
"function_index=1": &FunctionDefinition{
|
"function_index=1": &FunctionDefinition{
|
||||||
index: 1,
|
index: 1,
|
||||||
debugName: ".$1",
|
debugName: ".$1",
|
||||||
exportNames: []string{"function_index=1"},
|
exportNames: []string{"function_index=1"},
|
||||||
funcType: &FunctionType{Params: []ValueType{ValueTypeF64, ValueTypeI32}, Results: []ValueType{ValueTypeV128, ValueTypeI64}},
|
funcType: &f64i32_v128i64,
|
||||||
},
|
},
|
||||||
"function_index=2": &FunctionDefinition{
|
"function_index=2": &FunctionDefinition{
|
||||||
index: 2,
|
index: 2,
|
||||||
|
|||||||
Reference in New Issue
Block a user