text: plumbs feature flags (#341)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
@@ -48,6 +48,9 @@ type moduleParser struct {
|
||||
// source is the entire WebAssembly text format source code being parsed.
|
||||
source []byte
|
||||
|
||||
// enabledFeatures ensure parsing errs at the correct line and column number when a feature is disabled.
|
||||
enabledFeatures wasm.Features
|
||||
|
||||
// module holds the fields incrementally parsed from tokens in the source.
|
||||
module *wasm.Module
|
||||
|
||||
@@ -99,7 +102,7 @@ type moduleParser struct {
|
||||
|
||||
// DecodeModule implements internalwasm.DecodeModule for the WebAssembly 1.0 (20191205) Text Format
|
||||
// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#text-format%E2%91%A0
|
||||
func DecodeModule(source []byte, _ wasm.Features) (result *wasm.Module, err error) {
|
||||
func DecodeModule(source []byte, enabledFeatures wasm.Features) (result *wasm.Module, err error) {
|
||||
// TODO: when globals are supported, err on mutable globals if disabled
|
||||
|
||||
// names are the wasm.Module NameSection
|
||||
@@ -109,7 +112,7 @@ func DecodeModule(source []byte, _ wasm.Features) (result *wasm.Module, err erro
|
||||
// * LocalNames: nil when no imported or module-defined function had named (param) fields.
|
||||
names := &wasm.NameSection{}
|
||||
module := &wasm.Module{NameSection: names}
|
||||
p := newModuleParser(module)
|
||||
p := newModuleParser(module, enabledFeatures)
|
||||
p.source = source
|
||||
|
||||
// A valid source must begin with the token '(', but it could be preceded by whitespace or comments. For this
|
||||
@@ -138,15 +141,15 @@ func DecodeModule(source []byte, _ wasm.Features) (result *wasm.Module, err erro
|
||||
return module, nil
|
||||
}
|
||||
|
||||
func newModuleParser(module *wasm.Module) *moduleParser {
|
||||
p := moduleParser{module: module,
|
||||
func newModuleParser(module *wasm.Module, enabledFeatures wasm.Features) *moduleParser {
|
||||
p := moduleParser{module: module, enabledFeatures: enabledFeatures,
|
||||
typeNamespace: newIndexNamespace(module.SectionElementCount),
|
||||
funcNamespace: newIndexNamespace(module.SectionElementCount),
|
||||
memoryNamespace: newIndexNamespace(module.SectionElementCount),
|
||||
}
|
||||
p.typeParser = newTypeParser(p.typeNamespace, p.onTypeEnd)
|
||||
p.typeUseParser = newTypeUseParser(module, p.typeNamespace)
|
||||
p.funcParser = newFuncParser(p.typeUseParser, p.funcNamespace, p.endFunc)
|
||||
p.funcParser = newFuncParser(enabledFeatures, p.typeUseParser, p.funcNamespace, p.endFunc)
|
||||
p.memoryParser = newMemoryParser(p.memoryNamespace, p.endMemory)
|
||||
return &p
|
||||
}
|
||||
|
||||
@@ -2087,7 +2087,7 @@ func TestParseModule_Errors(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestModuleParser_ErrorContext(t *testing.T) {
|
||||
p := newModuleParser(&wasm.Module{})
|
||||
p := newModuleParser(&wasm.Module{}, 0)
|
||||
tests := []struct {
|
||||
input string
|
||||
pos parserPosition
|
||||
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
wasm "github.com/tetratelabs/wazero/internal/wasm"
|
||||
)
|
||||
|
||||
func newFuncParser(typeUseParser *typeUseParser, funcNamespace *indexNamespace, onFunc onFunc) *funcParser {
|
||||
return &funcParser{typeUseParser: typeUseParser, funcNamespace: funcNamespace, onFunc: onFunc}
|
||||
func newFuncParser(enabledFeatures wasm.Features, typeUseParser *typeUseParser, funcNamespace *indexNamespace, onFunc onFunc) *funcParser {
|
||||
return &funcParser{enabledFeatures: enabledFeatures, typeUseParser: typeUseParser, funcNamespace: funcNamespace, onFunc: onFunc}
|
||||
}
|
||||
|
||||
type onFunc func(typeIdx wasm.Index, code *wasm.Code, name string, localNames wasm.NameMap) (tokenParser, error)
|
||||
@@ -22,6 +22,9 @@ type onFunc func(typeIdx wasm.Index, code *wasm.Code, name string, localNames wa
|
||||
//
|
||||
// Note: funcParser is reusable. The caller resets via begin.
|
||||
type funcParser struct {
|
||||
// enabledFeatures should be set to moduleParser.enabledFeatures
|
||||
enabledFeatures wasm.Features
|
||||
|
||||
// onFunc is called when complete parsing the body. Unless testing, this should be moduleParser.onFuncEnd
|
||||
onFunc onFunc
|
||||
|
||||
|
||||
@@ -11,8 +11,9 @@ import (
|
||||
|
||||
func TestFuncParser(t *testing.T) {
|
||||
tests := []struct {
|
||||
name, source string
|
||||
expected *wasm.Code
|
||||
name, source string
|
||||
enabledFeatures wasm.Features
|
||||
expected *wasm.Code
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
@@ -52,7 +53,7 @@ func TestFuncParser(t *testing.T) {
|
||||
}
|
||||
|
||||
module := &wasm.Module{}
|
||||
fp := newFuncParser(&typeUseParser{module: module}, newIndexNamespace(module.SectionElementCount), setFunc)
|
||||
fp := newFuncParser(tc.enabledFeatures, &typeUseParser{module: module}, newIndexNamespace(module.SectionElementCount), setFunc)
|
||||
require.NoError(t, parseFunc(fp, tc.source))
|
||||
require.Equal(t, tc.expected, parsedCode)
|
||||
})
|
||||
@@ -62,6 +63,7 @@ func TestFuncParser(t *testing.T) {
|
||||
func TestFuncParser_Call_Unresolved(t *testing.T) {
|
||||
tests := []struct {
|
||||
name, source string
|
||||
enabledFeatures wasm.Features
|
||||
expectedCode *wasm.Code
|
||||
expectedUnresolvedIndex *unresolvedIndex
|
||||
}{
|
||||
@@ -110,7 +112,7 @@ func TestFuncParser_Call_Unresolved(t *testing.T) {
|
||||
}
|
||||
|
||||
module := &wasm.Module{}
|
||||
fp := newFuncParser(&typeUseParser{module: module}, newIndexNamespace(module.SectionElementCount), setFunc)
|
||||
fp := newFuncParser(tc.enabledFeatures, &typeUseParser{module: module}, newIndexNamespace(module.SectionElementCount), setFunc)
|
||||
require.NoError(t, parseFunc(fp, tc.source))
|
||||
require.Equal(t, tc.expectedCode, parsedCode)
|
||||
require.Equal(t, []*unresolvedIndex{tc.expectedUnresolvedIndex}, fp.funcNamespace.unresolvedIndices)
|
||||
@@ -120,8 +122,9 @@ func TestFuncParser_Call_Unresolved(t *testing.T) {
|
||||
|
||||
func TestFuncParser_Call_Resolved(t *testing.T) {
|
||||
tests := []struct {
|
||||
name, source string
|
||||
expected *wasm.Code
|
||||
name, source string
|
||||
enabledFeatures wasm.Features
|
||||
expected *wasm.Code
|
||||
}{
|
||||
{
|
||||
name: "index zero",
|
||||
@@ -170,7 +173,7 @@ func TestFuncParser_Call_Resolved(t *testing.T) {
|
||||
return parseErr, nil
|
||||
}
|
||||
|
||||
fp := newFuncParser(&typeUseParser{module: &wasm.Module{}}, funcNamespace, setFunc)
|
||||
fp := newFuncParser(tc.enabledFeatures, &typeUseParser{module: &wasm.Module{}}, funcNamespace, setFunc)
|
||||
require.NoError(t, parseFunc(fp, tc.source))
|
||||
require.Equal(t, tc.expected, parsedCode)
|
||||
})
|
||||
@@ -179,7 +182,9 @@ func TestFuncParser_Call_Resolved(t *testing.T) {
|
||||
|
||||
func TestFuncParser_Errors(t *testing.T) {
|
||||
tests := []struct {
|
||||
name, source, expectedErr string
|
||||
name, source string
|
||||
enabledFeatures wasm.Features
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "not field",
|
||||
@@ -228,7 +233,7 @@ func TestFuncParser_Errors(t *testing.T) {
|
||||
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
module := &wasm.Module{}
|
||||
fp := newFuncParser(&typeUseParser{module: module}, newIndexNamespace(module.SectionElementCount), failOnFunc)
|
||||
fp := newFuncParser(tc.enabledFeatures, &typeUseParser{module: module}, newIndexNamespace(module.SectionElementCount), failOnFunc)
|
||||
require.EqualError(t, parseFunc(fp, tc.source), tc.expectedErr)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user