Skip to content

Commit 8992638

Browse files
authored
Refactor type and function parsing (#2143)
- Refactored & fixed typeuse parsing rules so now the rules more closely follow the spec. There have been multiple parsing rules that were different in subtle ways, which are supposed to be the same according to the spec. - Duplicate types, i.e., types with the same signature, in the type section are allowed as long as they don't have the same given name. If a name is given, we use it; if type name is not given, we generate one in the form of `$FUNCSIG$` + signature string. If the same generated name already exists in the type section, we append `_` at the end. This causes most of the changes in the autogenerated type names in test outputs. - A typeuse has to be in the order of (type) -> (param) -> (result), if more than one of them exist. In case of function definitions, (local) has to be after all of these. Fixed some test cases that violate this rule. - When only (param)/(result) are given, its type will be the type with the smallest existing type index whose parameter and result are the same. If there's no such type, a new type will be created and inserted. - Added a test case `duplicate_types.wast` to test type namings for duplicate types. - Refactored `parseFunction` function. - Add more overrides to helper functions: `getSig` and `ensureFunctionType`.
1 parent dc37d7b commit 8992638

135 files changed

Lines changed: 1740 additions & 1660 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@ full changeset diff at the end of each section.
1515
Current Trunk
1616
-------------
1717

18+
- Wast file parsing rules now don't allow a few invalid formats for typeuses
19+
that were previously allowed. Typeuse entries should follow this format,
20+
meaning they should have (type) -> (param) -> (result) order if more than one
21+
of them exist.
22+
```
23+
typeuse ::= (type index|name)+ |
24+
(type index|name)+ (param ..)* (result ..)* |
25+
(param ..)* (result ..)*
26+
```
27+
Also, all (local) nodes in function definition should be after all typeuse
28+
elements.
1829
- Removed APIs related to deprecated instruction names in Binaryen.js:
1930
- `get_local` / `getLocal`
2031
- `set_local` / `setLocal`

src/asm_v_wasm.h

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,17 @@ AsmType wasmToAsmType(Type type);
2929

3030
char getSig(Type type);
3131

32-
std::string getSig(const FunctionType* type);
32+
template<typename ListType>
33+
std::string getSig(const ListType& params, Type result) {
34+
std::string ret;
35+
ret += getSig(result);
36+
for (auto param : params) {
37+
ret += getSig(param);
38+
}
39+
return ret;
40+
}
3341

42+
std::string getSig(const FunctionType* type);
3443
std::string getSig(Function* func);
3544

3645
template<typename T,
@@ -67,9 +76,18 @@ std::string getSigFromStructs(Type result, const ListType& operands) {
6776

6877
Type sigToType(char sig);
6978

70-
FunctionType sigToFunctionType(std::string sig);
79+
FunctionType sigToFunctionType(const std::string& sig);
80+
81+
FunctionType*
82+
ensureFunctionType(const std::string& sig, Module* wasm, Name name = Name());
7183

72-
FunctionType* ensureFunctionType(std::string sig, Module* wasm);
84+
template<typename ListType>
85+
FunctionType* ensureFunctionType(const ListType& params,
86+
Type result,
87+
Module* wasm,
88+
Name name = Name()) {
89+
return ensureFunctionType(getSig(params, result), wasm, name);
90+
}
7391

7492
// converts an f32 to an f64 if necessary
7593
Expression* ensureDouble(Expression* expr, MixedArena& allocator);

src/asmjs/asm_v_wasm.cpp

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -86,21 +86,11 @@ char getSig(Type type) {
8686
}
8787

8888
std::string getSig(const FunctionType* type) {
89-
std::string ret;
90-
ret += getSig(type->result);
91-
for (auto param : type->params) {
92-
ret += getSig(param);
93-
}
94-
return ret;
89+
return getSig(type->params, type->result);
9590
}
9691

9792
std::string getSig(Function* func) {
98-
std::string ret;
99-
ret += getSig(func->result);
100-
for (auto type : func->params) {
101-
ret += getSig(type);
102-
}
103-
return ret;
93+
return getSig(func->params, func->result);
10494
}
10595

10696
Type sigToType(char sig) {
@@ -124,7 +114,7 @@ Type sigToType(char sig) {
124114
}
125115
}
126116

127-
FunctionType sigToFunctionType(std::string sig) {
117+
FunctionType sigToFunctionType(const std::string& sig) {
128118
FunctionType ret;
129119
ret.result = sigToType(sig[0]);
130120
for (size_t i = 1; i < sig.size(); i++) {
@@ -133,8 +123,11 @@ FunctionType sigToFunctionType(std::string sig) {
133123
return ret;
134124
}
135125

136-
FunctionType* ensureFunctionType(std::string sig, Module* wasm) {
137-
cashew::IString name(("FUNCSIG$" + sig).c_str(), false);
126+
FunctionType*
127+
ensureFunctionType(const std::string& sig, Module* wasm, Name name) {
128+
if (!name.is()) {
129+
name = "FUNCSIG$" + sig;
130+
}
138131
if (wasm->getFunctionTypeOrNull(name)) {
139132
return wasm->getFunctionType(name);
140133
}

src/wasm-s-parser.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ class SExpressionWasmBuilder {
112112
Module& wasm;
113113
MixedArena& allocator;
114114
std::vector<Name> functionNames;
115-
std::vector<Name> functionTypeNames;
116115
std::vector<Name> globalNames;
117116
int functionCounter;
118117
int globalCounter = 0;
@@ -222,9 +221,20 @@ class SExpressionWasmBuilder {
222221
Type parseOptionalResultType(Element& s, Index& i);
223222
Index parseMemoryLimits(Element& s, Index i);
224223
std::vector<Type> parseParamOrLocal(Element& s);
225-
std::vector<NameType> parseNamedParamOrLocal(Element& s, size_t& localIndex);
224+
std::vector<NameType> parseParamOrLocal(Element& s, size_t& localIndex);
226225
Type parseResult(Element& s);
227226
FunctionType* parseTypeRef(Element& s);
227+
size_t parseTypeUse(Element& s,
228+
size_t startPos,
229+
FunctionType*& functionType,
230+
std::vector<NameType>& namedParams,
231+
Type& result);
232+
size_t parseTypeUse(Element& s,
233+
size_t startPos,
234+
FunctionType*& functionType,
235+
std::vector<Type>& params,
236+
Type& result);
237+
size_t parseTypeUse(Element& s, size_t startPos, FunctionType*& functionType);
228238

229239
void stringToBinary(const char* input, size_t size, std::vector<char>& data);
230240
void parseMemory(Element& s, bool preParseImport = false);

src/wasm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,7 @@ class FunctionType {
632632
FunctionType() = default;
633633

634634
bool structuralComparison(FunctionType& b);
635+
bool structuralComparison(const std::vector<Type>& params, Type result);
635636

636637
bool operator==(FunctionType& b);
637638
bool operator!=(FunctionType& b);

0 commit comments

Comments
 (0)