Skip to content

Commit

Permalink
support pre-assigning indexes for functions that are called indirectly
Browse files Browse the repository at this point in the history
  • Loading branch information
ddcc committed Aug 1, 2016
1 parent f99c783 commit 2e5dc9d
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 1 deletion.
7 changes: 7 additions & 0 deletions src/s2wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,13 @@ class S2WasmBuilder {
}
} else if (match(".result")) {
resultType = getType();
} else if (match(".indidx")) {
int64_t indirectIndex = getInt64();
skipWhitespace();
if (indirectIndex < 0) {
abort_on("indidx");
}
linkerObj->addIndirectIndex(name, indirectIndex);
} else if (match(".local")) {
while (1) {
Name name = getNextId();
Expand Down
10 changes: 9 additions & 1 deletion src/wasm-linker.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ class LinkerObject {
return f->second;
}

void addIndirectIndex(Name name, uint64_t index) {
assert(!indirect_indexes.count(name));
indirect_indexes[name] = index;
}

bool isEmpty() {
return wasm.functions.empty();
}
Expand Down Expand Up @@ -192,6 +197,8 @@ class LinkerObject {
std::map<Name, Address> segments; // name => segment index (in wasm module)
std::map<Index, Table *> tables; // index => table index (in wasm module)

std::map<Name, uint64_t> indirect_indexes;

std::vector<Name> initializerFunctions;

LinkerObject(const LinkerObject&) = delete;
Expand Down Expand Up @@ -328,7 +335,8 @@ class Linker {

std::unordered_map<cashew::IString, int32_t> staticAddresses; // name => address
std::unordered_map<Address, Address> segmentsByAddress; // address => segment index
std::unordered_map<cashew::IString, std::pair<Index, Index>> functionIndexes; // name => table, entry indexes
std::unordered_map<cashew::IString, std::pair<Index, uint64_t>> functionIndexes; // name => table, entry indexes
std::map<uint64_t, cashew::IString> functionNames;
};


Expand Down
93 changes: 93 additions & 0 deletions test/dot_s/indidx.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
.text
.file "cfi-wasm.bs.bc"
.type a,@function
a: # @a
.indidx 0
.result i32
# BB#0: # %entry
i32.const $push0=, 0
# fallthrough-return: $pop0
.endfunc
.Lfunc_end0:
.size a, .Lfunc_end0-a

.type b,@function
b: # @b
.indidx 1
.result i32
# BB#0: # %entry
i32.const $push0=, 1
# fallthrough-return: $pop0
.endfunc
.Lfunc_end1:
.size b, .Lfunc_end1-b

.type c,@function
c: # @c
.indidx 2
.result i32
# BB#0: # %entry
i32.const $push0=, 2
# fallthrough-return: $pop0
.endfunc
.Lfunc_end2:
.size c, .Lfunc_end2-c

.type d,@function
d: # @d
.indidx 3
.result i32
# BB#0: # %entry
i32.const $push0=, 3
# fallthrough-return: $pop0
.endfunc
.Lfunc_end3:
.size d, .Lfunc_end3-d

.hidden main
.globl main
.type main,@function
main: # @main
.param i32, i32
.result i32
.local i32
# BB#0: # %entry
block
i32.call $push1=, getchar@FUNCTION
i32.const $push0=, 2
i32.shl $push2=, $pop1, $pop0
i32.const $push3=, .Lmain.fp-192
i32.add $push4=, $pop2, $pop3
i32.load $push9=, 0($pop4)
tee_local $push8=, $2=, $pop9
i32.const $push5=, 4
i32.ge_u $push6=, $pop8, $pop5
br_if 0, $pop6 # 0: down to label0
# BB#1: # %cont
i32.call_indirect $push7=, $2
return $pop7
.LBB4_2: # %trap
end_block # label0:
unreachable
unreachable
.endfunc
.Lfunc_end4:
.size main, .Lfunc_end4-main

.type .Lmain.fp,@object # @main.fp
.section .data.rel.ro,"aw",@progbits
.p2align 4
.Lmain.fp:
.int32 a@FUNCTION
.int32 b@FUNCTION
.int32 c@FUNCTION
.int32 d@FUNCTION
.size .Lmain.fp, 16

.type .L__unnamed_1,@object # @0
.section .rodata,"a",@progbits
.L__unnamed_1:
.size .L__unnamed_1, 0


.ident "clang version 3.9.0 (trunk 271314) (llvm/trunk 271322)"
57 changes: 57 additions & 0 deletions test/dot_s/indidx.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
(module
(memory 1
(segment 16 "\00\00\00\00\01\00\00\00\02\00\00\00\03\00\00\00")
)
(export "memory" memory)
(type $FUNCSIG$i (func (result i32)))
(import $getchar "env" "getchar" (result i32))
(export "main" $main)
(export "dynCall_i" $dynCall_i)
(table $a $b $c $d)
(func $a (type $FUNCSIG$i) (result i32)
(i32.const 0)
)
(func $b (type $FUNCSIG$i) (result i32)
(i32.const 1)
)
(func $c (type $FUNCSIG$i) (result i32)
(i32.const 2)
)
(func $d (type $FUNCSIG$i) (result i32)
(i32.const 3)
)
(func $main (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(block $label$0
(br_if $label$0
(i32.ge_u
(set_local $2
(i32.load
(i32.add
(i32.shl
(call_import $getchar)
(i32.const 2)
)
(i32.const -176)
)
)
)
(i32.const 4)
)
)
(return
(call_indirect $FUNCSIG$i
(get_local $2)
)
)
)
(unreachable)
(unreachable)
)
(func $dynCall_i (param $fptr i32) (result i32)
(call_indirect $FUNCSIG$i
(get_local $fptr)
)
)
)
;; METADATA: { "asmConsts": {},"staticBump": 32, "initializers": [] }

0 comments on commit 2e5dc9d

Please sign in to comment.