Skip to content

Commit 816ec66

Browse files
committed
additional parsing support for new spec things
1 parent b0fcaaa commit 816ec66

File tree

1 file changed

+74
-22
lines changed

1 file changed

+74
-22
lines changed

src/wasm-s-parser.h

+74-22
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ class Element {
6767

6868
bool isList() { return isList_; }
6969
bool isStr() { return !isList_; }
70-
bool dollared() { return dollared_; }
71-
bool quoted() { return quoted_; }
70+
bool dollared() { return isStr() && dollared_; }
71+
bool quoted() { return isStr() && quoted_; }
7272

7373
size_t line, col;
7474

@@ -428,6 +428,13 @@ class SExpressionWasmBuilder {
428428
break;
429429
}
430430
}
431+
if (i < s.size() && s[i]->isList()) {
432+
auto& inner = *s[i];
433+
if (inner.size() > 0 && inner[0]->str() == EXPORT) {
434+
exportName = inner[1]->str();
435+
i++;
436+
}
437+
}
431438
return i;
432439
}
433440

@@ -1341,16 +1348,29 @@ class SExpressionWasmBuilder {
13411348

13421349
void parseMemory(Element& s) {
13431350
hasMemory = true;
1344-
1345-
if (s[1]->isList()) {
1346-
// (memory (data ..)) format
1347-
parseData(*s[1]);
1348-
wasm.memory.initial = wasm.memory.segments[0].data.size();
1349-
return;
1351+
Index i = 1;
1352+
if (s[i]->dollared()) {
1353+
wasm.memory.name = s[i++]->str();
1354+
}
1355+
if (s[i]->isList()) {
1356+
auto& inner = *s[i];
1357+
if (inner[0]->str() == EXPORT) {
1358+
auto ex = make_unique<Export>();
1359+
ex->name = inner[1]->str();
1360+
ex->value = wasm.memory.name;
1361+
ex->kind = Export::Memory;
1362+
wasm.addExport(ex.release());
1363+
i++;
1364+
} else {
1365+
assert(inner.size() > 0 ? inner[0]->str() != IMPORT : true);
1366+
// (memory (data ..)) format
1367+
parseData(*s[i]);
1368+
wasm.memory.initial = wasm.memory.segments[0].data.size();
1369+
return;
1370+
}
13501371
}
1351-
wasm.memory.initial = atoi(s[1]->c_str());
1352-
if (s.size() == 2) return;
1353-
size_t i = 2;
1372+
wasm.memory.initial = atoi(s[i++]->c_str());
1373+
if (i == s.size()) return;
13541374
if (s[i]->isStr()) {
13551375
uint64_t max = atoll(s[i]->c_str());
13561376
if (max > Memory::kMaxSize) throw ParseException("total memory must be <= 4GB");
@@ -1522,12 +1542,25 @@ class SExpressionWasmBuilder {
15221542
void parseGlobal(Element& s) {
15231543
std::unique_ptr<Global> global = make_unique<Global>();
15241544
size_t i = 1;
1525-
if (s.size() == 4) {
1545+
if (s[i]->dollared()) {
15261546
global->name = s[i++]->str();
15271547
} else {
15281548
global->name = Name::fromInt(globalCounter);
15291549
}
15301550
globalCounter++;
1551+
if (s[i]->isList()) {
1552+
auto& inner = *s[i];
1553+
if (inner[0]->str() == EXPORT) {
1554+
auto ex = make_unique<Export>();
1555+
ex->name = inner[1]->str();
1556+
ex->value = global->name;
1557+
ex->kind = Export::Global;
1558+
wasm.addExport(ex.release());
1559+
i++;
1560+
} else {
1561+
WASM_UNREACHABLE();
1562+
}
1563+
}
15311564
global->type = stringToWasmType(s[i++]->str());
15321565
global->init = parseExpression(s[i++]);
15331566
assert(i == s.size());
@@ -1538,31 +1571,50 @@ class SExpressionWasmBuilder {
15381571

15391572
void parseTable(Element& s) {
15401573
seenTable = true;
1541-
1542-
if (s.size() == 1) return; // empty table in old notation
1543-
if (!s[1]->dollared()) {
1544-
if (s[1]->str() == ANYFUNC) {
1574+
Index i = 1;
1575+
if (i == s.size()) return; // empty table in old notation
1576+
#if 0 // TODO: new table notation
1577+
if (s[i]->dollared()) {
1578+
wasm.table.name = s[i++]->str();
1579+
}
1580+
#endif
1581+
if (i == s.size()) return;
1582+
if (s[i]->isList()) {
1583+
auto& inner = *s[i];
1584+
if (inner[0]->str() == EXPORT) {
1585+
auto ex = make_unique<Export>();
1586+
ex->name = inner[1]->str();
1587+
ex->value = wasm.table.name;
1588+
ex->kind = Export::Table;
1589+
wasm.addExport(ex.release());
1590+
i++;
1591+
} else {
1592+
WASM_UNREACHABLE();
1593+
}
1594+
}
1595+
if (i == s.size()) return;
1596+
if (!s[i]->dollared()) {
1597+
if (s[i]->str() == ANYFUNC) {
15451598
// (table type (elem ..))
1546-
parseElem(*s[2]);
1599+
parseElem(*s[i + 1]);
15471600
wasm.table.initial = wasm.table.max = wasm.table.segments[0].data.size();
15481601
return;
15491602
}
15501603
// first element isn't dollared, and isn't anyfunc. this could be old syntax for (table 0 1) which means function 0 and 1, or it could be (table initial max? type), look for type
15511604
if (s[s.size() - 1]->str() == ANYFUNC) {
15521605
// (table initial max? type)
1553-
wasm.table.initial = atoi(s[1]->c_str());
1554-
wasm.table.max = atoi(s[2]->c_str());
1606+
wasm.table.initial = atoi(s[i]->c_str());
1607+
wasm.table.max = atoi(s[i + 1]->c_str());
15551608
return;
15561609
}
15571610
}
15581611
// old notation (table func1 func2 ..)
1559-
parseElem(s);
1612+
parseElem(s, i);
15601613
wasm.table.initial = wasm.table.max = wasm.table.segments[0].data.size();
15611614
}
15621615

1563-
void parseElem(Element& s) {
1616+
void parseElem(Element& s, Index i = 1) {
15641617
if (!seenTable) throw ParseException("elem without table", s.line, s.col);
1565-
Index i = 1;
15661618
Expression* offset;
15671619
if (s[i]->isList()) {
15681620
// there is an init expression

0 commit comments

Comments
 (0)