@@ -67,8 +67,8 @@ class Element {
67
67
68
68
bool isList () { return isList_; }
69
69
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_; }
72
72
73
73
size_t line, col;
74
74
@@ -428,6 +428,13 @@ class SExpressionWasmBuilder {
428
428
break ;
429
429
}
430
430
}
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
+ }
431
438
return i;
432
439
}
433
440
@@ -1341,16 +1348,29 @@ class SExpressionWasmBuilder {
1341
1348
1342
1349
void parseMemory (Element& s) {
1343
1350
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
+ }
1350
1371
}
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 ;
1354
1374
if (s[i]->isStr ()) {
1355
1375
uint64_t max = atoll (s[i]->c_str ());
1356
1376
if (max > Memory::kMaxSize ) throw ParseException (" total memory must be <= 4GB" );
@@ -1522,12 +1542,25 @@ class SExpressionWasmBuilder {
1522
1542
void parseGlobal (Element& s) {
1523
1543
std::unique_ptr<Global> global = make_unique<Global>();
1524
1544
size_t i = 1 ;
1525
- if (s. size () == 4 ) {
1545
+ if (s[i]-> dollared () ) {
1526
1546
global->name = s[i++]->str ();
1527
1547
} else {
1528
1548
global->name = Name::fromInt (globalCounter);
1529
1549
}
1530
1550
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
+ }
1531
1564
global->type = stringToWasmType (s[i++]->str ());
1532
1565
global->init = parseExpression (s[i++]);
1533
1566
assert (i == s.size ());
@@ -1538,31 +1571,50 @@ class SExpressionWasmBuilder {
1538
1571
1539
1572
void parseTable (Element& s) {
1540
1573
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) {
1545
1598
// (table type (elem ..))
1546
- parseElem (*s[2 ]);
1599
+ parseElem (*s[i + 1 ]);
1547
1600
wasm.table .initial = wasm.table .max = wasm.table .segments [0 ].data .size ();
1548
1601
return ;
1549
1602
}
1550
1603
// 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
1551
1604
if (s[s.size () - 1 ]->str () == ANYFUNC) {
1552
1605
// (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 ());
1555
1608
return ;
1556
1609
}
1557
1610
}
1558
1611
// old notation (table func1 func2 ..)
1559
- parseElem (s);
1612
+ parseElem (s, i );
1560
1613
wasm.table .initial = wasm.table .max = wasm.table .segments [0 ].data .size ();
1561
1614
}
1562
1615
1563
- void parseElem (Element& s) {
1616
+ void parseElem (Element& s, Index i = 1 ) {
1564
1617
if (!seenTable) throw ParseException (" elem without table" , s.line , s.col );
1565
- Index i = 1 ;
1566
1618
Expression* offset;
1567
1619
if (s[i]->isList ()) {
1568
1620
// there is an init expression
0 commit comments