Skip to content

Commit 444d7f6

Browse files
committed
call_import changes: no more call_import, shared index space with functions
1 parent 7292ef9 commit 444d7f6

59 files changed

Lines changed: 2060 additions & 2033 deletions

Some content is hidden

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

src/passes/Print.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
224224
printCallBody(curr);
225225
}
226226
void visitCallImport(CallImport *curr) {
227-
printOpening(o, "call_import ");
227+
printOpening(o, "call ");
228228
printCallBody(curr);
229229
}
230230
void visitCallIndirect(CallIndirect *curr) {

src/wasm-binary.h

Lines changed: 69 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,6 @@ enum ASTNodes {
411411
SetLocal = 0x15,
412412
CallFunction = 0x16,
413413
CallIndirect = 0x17,
414-
CallImport = 0x18,
415414
TeeLocal = 0x19,
416415
GetGlobal = 0x1a,
417416
SetGlobal = 0x1b,
@@ -727,27 +726,21 @@ class WasmBinaryWriter : public Visitor<WasmBinaryWriter, void> {
727726
}
728727
finishSection(start);
729728
}
730-
731-
std::map<Name, uint32_t> mappedImports; // name of the Import => index
732-
uint32_t getImportIndex(Name name) {
733-
if (!mappedImports.size()) {
734-
// Create name => index mapping.
735-
for (size_t i = 0; i < wasm->imports.size(); i++) {
736-
assert(mappedImports.count(wasm->imports[i]->name) == 0);
737-
mappedImports[wasm->imports[i]->name] = i;
738-
}
739-
}
740-
assert(mappedImports.count(name));
741-
return mappedImports[name];
742-
}
743729

744-
std::map<Name, uint32_t> mappedFunctions; // name of the Function => index
730+
std::map<Name, Index> mappedFunctions; // name of the Function => index. first imports, then internals
745731
uint32_t getFunctionIndex(Name name) {
746732
if (!mappedFunctions.size()) {
747733
// Create name => index mapping.
734+
for (auto& import : wasm->imports) {
735+
if (import->kind != Import::Function) continue;
736+
assert(mappedFunctions.count(import->name) == 0);
737+
auto index = mappedFunctions.size();
738+
mappedFunctions[import->name] = index;
739+
}
748740
for (size_t i = 0; i < wasm->functions.size(); i++) {
749741
assert(mappedFunctions.count(wasm->functions[i]->name) == 0);
750-
mappedFunctions[wasm->functions[i]->name] = i;
742+
auto index = mappedFunctions.size();
743+
mappedFunctions[wasm->functions[i]->name] = index;
751744
}
752745
}
753746
assert(mappedFunctions.count(name));
@@ -957,7 +950,7 @@ class WasmBinaryWriter : public Visitor<WasmBinaryWriter, void> {
957950
for (auto* operand : curr->operands) {
958951
recurse(operand);
959952
}
960-
o << int8_t(BinaryConsts::CallImport) << U32LEB(curr->operands.size()) << U32LEB(getImportIndex(curr->target));
953+
o << int8_t(BinaryConsts::CallFunction) << U32LEB(curr->operands.size()) << U32LEB(getFunctionIndex(curr->target));
961954
}
962955
void visitCallIndirect(CallIndirect *curr) {
963956
if (debug) std::cerr << "zz node: CallIndirect" << std::endl;
@@ -1501,6 +1494,20 @@ class WasmBinaryBuilder {
15011494
}
15021495
}
15031496

1497+
std::vector<Name> functionImportIndexes; // index in function index space => name of function import
1498+
1499+
// gets a name in the combined function import+defined function space
1500+
Name getFunctionIndexName(Index i) {
1501+
if (i < functionImportIndexes.size()) {
1502+
auto* import = wasm.getImport(functionImportIndexes[i]);
1503+
assert(import->kind == Import::Function);
1504+
return import->name;
1505+
} else {
1506+
i -= functionImportIndexes.size();
1507+
return wasm.functions.at(i)->name;
1508+
}
1509+
}
1510+
15041511
void readImports() {
15051512
if (debug) std::cerr << "== readImports" << std::endl;
15061513
size_t num = getU32LEB();
@@ -1511,16 +1518,17 @@ class WasmBinaryBuilder {
15111518
curr->name = Name(std::string("import$") + std::to_string(i));
15121519
curr->kind = (Import::Kind)getU32LEB();
15131520
switch (curr->kind) {
1514-
case Export::Function: {
1521+
case Import::Function: {
15151522
auto index = getU32LEB();
15161523
assert(index < wasm.functionTypes.size());
15171524
curr->functionType = wasm.getFunctionType(index);
15181525
assert(curr->functionType->name.is());
1526+
functionImportIndexes.push_back(curr->name);
15191527
break;
15201528
}
1521-
case Export::Table: break;
1522-
case Export::Memory: break;
1523-
case Export::Global: curr->globalType = getWasmType(); break;
1529+
case Import::Table: break;
1530+
case Import::Memory: break;
1531+
case Import::Global: curr->globalType = getWasmType(); break;
15241532
default: WASM_UNREACHABLE();
15251533
}
15261534
curr->module = getInlineString();
@@ -1529,7 +1537,7 @@ class WasmBinaryBuilder {
15291537
}
15301538
}
15311539

1532-
std::vector<FunctionType*> functionTypes;
1540+
std::vector<FunctionType*> functionTypes; // types of defined functions
15331541

15341542
void readFunctionSignatures() {
15351543
if (debug) std::cerr << "== readFunctionSignatures" << std::endl;
@@ -1551,7 +1559,7 @@ class WasmBinaryBuilder {
15511559
// We read functions before we know their names, so we need to backpatch the names later
15521560

15531561
std::vector<Function*> functions; // we store functions here before wasm.addFunction after we know their names
1554-
std::map<size_t, std::vector<Call*>> functionCalls; // at index i we have all calls to i
1562+
std::map<Index, std::vector<Call*>> functionCalls; // at index i we have all calls to the defined function i
15551563
Function* currFunction = nullptr;
15561564
size_t endOfFunction;
15571565

@@ -1611,7 +1619,7 @@ class WasmBinaryBuilder {
16111619
}
16121620
}
16131621

1614-
std::map<Export*, size_t> exportIndexes;
1622+
std::map<Export*, Index> exportIndexes;
16151623

16161624
void readExports() {
16171625
if (debug) std::cerr << "== readExports" << std::endl;
@@ -1705,7 +1713,10 @@ class WasmBinaryBuilder {
17051713
for (auto& iter : exportIndexes) {
17061714
Export* curr = iter.first;
17071715
switch (curr->kind) {
1708-
case Export::Function: curr->value = wasm.functions[iter.second]->name; break;
1716+
case Export::Function: {
1717+
curr->value = getFunctionIndexName(iter.second);
1718+
break;
1719+
}
17091720
case Export::Table: curr->value = Name::fromInt(0); break;
17101721
case Export::Memory: curr->value = Name::fromInt(0); break;
17111722
case Export::Global: curr->value = getGlobalName(iter.second); break;
@@ -1726,7 +1737,7 @@ class WasmBinaryBuilder {
17261737
auto i = pair.first;
17271738
auto& indexes = pair.second;
17281739
for (auto j : indexes) {
1729-
wasm.table.segments[i].data.push_back(wasm.functions[j]->name);
1740+
wasm.table.segments[i].data.push_back(getFunctionIndexName(j));
17301741
}
17311742
}
17321743
}
@@ -1795,8 +1806,7 @@ class WasmBinaryBuilder {
17951806
case BinaryConsts::Br:
17961807
case BinaryConsts::BrIf: visitBreak((curr = allocator.alloc<Break>())->cast<Break>(), code); break; // code distinguishes br from br_if
17971808
case BinaryConsts::TableSwitch: visitSwitch((curr = allocator.alloc<Switch>())->cast<Switch>()); break;
1798-
case BinaryConsts::CallFunction: visitCall((curr = allocator.alloc<Call>())->cast<Call>()); break;
1799-
case BinaryConsts::CallImport: visitCallImport((curr = allocator.alloc<CallImport>())->cast<CallImport>()); break;
1809+
case BinaryConsts::CallFunction: curr = visitCall(); break; // we don't know if it's a call or call_import yet
18001810
case BinaryConsts::CallIndirect: visitCallIndirect((curr = allocator.alloc<CallIndirect>())->cast<CallIndirect>()); break;
18011811
case BinaryConsts::GetLocal: visitGetLocal((curr = allocator.alloc<GetLocal>())->cast<GetLocal>()); break;
18021812
case BinaryConsts::TeeLocal:
@@ -1938,38 +1948,45 @@ class WasmBinaryBuilder {
19381948
}
19391949
curr->default_ = getBreakName(getInt32());
19401950
}
1941-
void visitCall(Call *curr) {
1942-
if (debug) std::cerr << "zz node: Call" << std::endl;
1943-
auto arity = getU32LEB();
1944-
WASM_UNUSED(arity);
1945-
auto index = getU32LEB();
1946-
assert(index < functionTypes.size());
1947-
auto type = functionTypes[index];
1951+
1952+
template<typename T>
1953+
void fillCall(T* call, FunctionType* type, Index arity) {
1954+
assert(type);
19481955
auto num = type->params.size();
19491956
assert(num == arity);
1950-
curr->operands.resize(num);
1957+
call->operands.resize(num);
19511958
for (size_t i = 0; i < num; i++) {
1952-
curr->operands[num - i - 1] = popExpression();
1959+
call->operands[num - i - 1] = popExpression();
19531960
}
1954-
curr->type = type->result;
1955-
functionCalls[index].push_back(curr);
1961+
call->type = type->result;
19561962
}
1957-
void visitCallImport(CallImport *curr) {
1958-
if (debug) std::cerr << "zz node: CallImport" << std::endl;
1963+
1964+
Expression* visitCall() {
1965+
if (debug) std::cerr << "zz node: Call" << std::endl;
19591966
auto arity = getU32LEB();
19601967
WASM_UNUSED(arity);
1961-
auto import = wasm.getImport(getU32LEB());
1962-
curr->target = import->name;
1963-
auto type = import->functionType;
1964-
assert(type);
1965-
auto num = type->params.size();
1966-
assert(num == arity);
1967-
if (debug) std::cerr << "zz node: CallImport " << curr->target << " with type " << type->name << " and " << num << " params\n";
1968-
curr->operands.resize(num);
1969-
for (size_t i = 0; i < num; i++) {
1970-
curr->operands[num - i - 1] = popExpression();
1968+
auto index = getU32LEB();
1969+
FunctionType* type;
1970+
Expression* ret;
1971+
if (index < functionImportIndexes.size()) {
1972+
// this is a call of an imported function
1973+
auto* call = allocator.alloc<CallImport>();
1974+
auto* import = wasm.getImport(functionImportIndexes[index]);
1975+
call->target = import->name;
1976+
type = import->functionType;
1977+
fillCall(call, type, arity);
1978+
ret = call;
1979+
} else {
1980+
// this is a call of a defined function
1981+
auto* call = allocator.alloc<Call>();
1982+
auto adjustedIndex = index - functionImportIndexes.size();
1983+
assert(adjustedIndex < functionTypes.size());
1984+
type = functionTypes[adjustedIndex];
1985+
fillCall(call, type, arity);
1986+
functionCalls[adjustedIndex].push_back(call); // we don't know function names yet
1987+
ret = call;
19711988
}
1972-
curr->type = type->result;
1989+
return ret;
19731990
}
19741991
void visitCallIndirect(CallIndirect *curr) {
19751992
if (debug) std::cerr << "zz node: CallIndirect" << std::endl;

src/wasm-s-parser.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1207,8 +1207,18 @@ class SExpressionWasmBuilder {
12071207
}
12081208

12091209
Expression* makeCall(Element& s) {
1210+
auto target = s[1]->str();
1211+
auto* import = wasm.checkImport(target);
1212+
if (import && import->kind == Import::Function) {
1213+
auto ret = allocator.alloc<CallImport>();
1214+
ret->target = target;
1215+
Import* import = wasm.getImport(ret->target);
1216+
ret->type = import->functionType->result;
1217+
parseCallOperands(s, 2, s.size(), ret);
1218+
return ret;
1219+
}
12101220
auto ret = allocator.alloc<Call>();
1211-
ret->target = s[1]->str();
1221+
ret->target = target;
12121222
ret->type = functionTypes[ret->target];
12131223
parseCallOperands(s, 2, s.size(), ret);
12141224
return ret;

test/dot_s/asm_const.wast

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
(export "main" (func $main))
88
(func $main (result i32)
99
(drop
10-
(call_import $emscripten_asm_const_vi
10+
(call $emscripten_asm_const_vi
1111
(i32.const 0)
1212
)
1313
)

test/dot_s/basics.wast

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
(elem (i32.const 0) $__wasm_nullptr $main)
1515
(func $main (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
1616
(drop
17-
(call_import $puts
17+
(call $puts
1818
(i32.const 16)
1919
)
2020
)

test/dot_s/bcp-1.wast

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -288,34 +288,34 @@
288288
)
289289
)
290290
(drop
291-
(call_import $exit
291+
(call $exit
292292
(get_local $0)
293293
)
294294
)
295295
(unreachable)
296296
)
297297
(drop
298-
(call_import $abort)
298+
(call $abort)
299299
)
300300
(unreachable)
301301
)
302302
(drop
303-
(call_import $abort)
303+
(call $abort)
304304
)
305305
(unreachable)
306306
)
307307
(drop
308-
(call_import $abort)
308+
(call $abort)
309309
)
310310
(unreachable)
311311
)
312312
(drop
313-
(call_import $abort)
313+
(call $abort)
314314
)
315315
(unreachable)
316316
)
317317
(drop
318-
(call_import $abort)
318+
(call $abort)
319319
)
320320
(unreachable)
321321
)

test/dot_s/exit.wast

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
(func $main (result i32)
88
(local $0 i32)
99
(drop
10-
(call_import $exit
10+
(call $exit
1111
(i32.const 0)
1212
)
1313
)

test/dot_s/fix_em_ehsjlj_names.wast

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,27 +38,27 @@
3838
(local $2 i32)
3939
(local $3 i32)
4040
(drop
41-
(call_import $invoke_v
41+
(call $invoke_v
4242
(i32.const 1)
4343
)
4444
)
4545
(drop
46-
(call_import $invoke_iiii
46+
(call $invoke_iiii
4747
(i32.const 2)
4848
(i32.const 1)
4949
(i32.const 2)
5050
(i32.const 3)
5151
)
5252
)
5353
(drop
54-
(call_import $invoke_ffd
54+
(call $invoke_ffd
5555
(i32.const 3)
5656
(f32.const 1.5)
5757
(f64.const 3.4)
5858
)
5959
)
6060
(drop
61-
(call_import $invoke_iii
61+
(call $invoke_iii
6262
(i32.const 4)
6363
(i32.add
6464
(get_local $1)
@@ -71,7 +71,7 @@
7171
)
7272
)
7373
(drop
74-
(call_import $emscripten_longjmp
74+
(call $emscripten_longjmp
7575
(i32.const 5)
7676
(i32.const 6)
7777
)

test/dot_s/indidx.wast

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
(i32.load
3131
(i32.add
3232
(i32.shl
33-
(call_import $getchar)
33+
(call $getchar)
3434
(i32.const 2)
3535
)
3636
(i32.const -176)

0 commit comments

Comments
 (0)