text: plumbs feature flags (#341)

Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
Crypt Keeper
2022-03-07 13:23:22 +08:00
committed by GitHub
parent 0596fd32a7
commit cd52f18323
4 changed files with 28 additions and 17 deletions

View File

@@ -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
}

View File

@@ -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

View File

@@ -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

View File

@@ -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)
})
}