Commit a338912f819bd6fa4333e0c982768e58f6f2219f
fix bug in custom type encoder
wanderer committed on 2/20/2018, 10:30:00 PMParent: b9cefb81b38fc031f3179fbfff55dfd7fa8596a6
Files changed
customTypes.js | changed |
tests/wasm/caller.wasm | changed |
tests/wasm/funcRef_caller.wasm | changed |
tests/wasm/funcRef_reciever.wasm | changed |
tests/wasmContainer.js | changed |
tests/wast/caller.json | changed |
tests/wast/funcRef_caller.json | changed |
tests/wast/funcRef_reciever.json | changed |
tests/wast2wasm.js | changed |
wasmContainer.js | changed |
customTypes.js | ||
---|---|---|
@@ -25,28 +25,50 @@ | ||
25 | 25 | } |
26 | 26 | |
27 | 27 | function encodeJSON (json) { |
28 | 28 | const stream = new Stream() |
29 | - encodeCustomSection('type', json, stream, encodeType) | |
29 | + encodeCustomSection('types', json, stream, encodeType) | |
30 | 30 | encodeCustomSection('typeMap', json, stream, encodeTypeMap) |
31 | + encodeCustomSection('globals', json, stream, encodeGlobals) | |
31 | 32 | |
32 | 33 | return stream.buffer |
33 | 34 | } |
34 | 35 | |
35 | 36 | function encodeCustomSection (name, json, stream, encodingFunc) { |
36 | - stream.write([0]) | |
37 | 37 | let payload = new Stream() |
38 | + json = json[name] | |
38 | 39 | |
39 | - // encode type | |
40 | - leb.unsigned.write(name.length, payload) | |
41 | - payload.write(name) | |
42 | - encodingFunc(json[name], payload) | |
43 | - // write the size of the payload | |
44 | - leb.unsigned.write(payload.bytesWrote, stream) | |
45 | - stream.write(payload.buffer) | |
40 | + if (json) { | |
41 | + stream.write([0]) | |
42 | + // encode type | |
43 | + leb.unsigned.write(name.length, payload) | |
44 | + payload.write(name) | |
45 | + encodingFunc(json, payload) | |
46 | + // write the size of the payload | |
47 | + leb.unsigned.write(payload.bytesWrote, stream) | |
48 | + stream.write(payload.buffer) | |
49 | + } | |
46 | 50 | return stream |
47 | 51 | } |
48 | 52 | |
53 | +function encodeGlobals (json, stream) { | |
54 | + leb.unsigned.write(json.length, stream) | |
55 | + for (const entry of json) { | |
56 | + leb.unsigned.write(entry, stream) | |
57 | + } | |
58 | + return stream | |
59 | +} | |
60 | + | |
61 | +function decodeGlobals (buf) { | |
62 | + const stream = new Stream(Buffer.from(buf)) | |
63 | + let numOfEntries = leb.unsigned.read(stream) | |
64 | + const json = [] | |
65 | + while (numOfEntries--) { | |
66 | + json.push(leb.unsigned.readBn(stream).toNumber()) | |
67 | + } | |
68 | + return json | |
69 | +} | |
70 | + | |
49 | 71 | function encodeTypeMap (json, stream) { |
50 | 72 | leb.unsigned.write(json.length, stream) |
51 | 73 | for (let entry of json) { |
52 | 74 | leb.unsigned.write(entry.func, stream) |
@@ -139,25 +161,25 @@ | ||
139 | 161 | indexes: {}, |
140 | 162 | exports: {} |
141 | 163 | } |
142 | 164 | |
143 | - const wantedSections = ['custom', 'custom', 'type', 'import', 'function', 'export'] | |
165 | + const wantedSections = ['types', 'typeMap', 'type', 'import', 'function', 'export'] | |
144 | 166 | const iterator = findSections(json, wantedSections) |
145 | 167 | const mappedFuncs = new Map() |
146 | 168 | const mappedTypes = new Map() |
147 | - const {value: customType} = iterator.next('custom') | |
169 | + const {value: customType} = iterator.next() | |
148 | 170 | if (customType) { |
149 | 171 | const type = decodeType(customType.payload) |
150 | 172 | result.types = type |
151 | 173 | } |
152 | - let {value: typeMap} = iterator.next('custom') | |
174 | + let {value: typeMap} = iterator.next() | |
153 | 175 | if (typeMap) { |
154 | 176 | decodeTypeMap(typeMap.payload).forEach(map => mappedFuncs.set(map.func, map.type)) |
155 | 177 | } |
156 | 178 | |
157 | - const {value: type} = iterator.next('type') | |
158 | - const {value: imports = {entries: []}} = iterator.next('import') | |
159 | - const {value: functions} = iterator.next('function') | |
179 | + const {value: type} = iterator.next() | |
180 | + const {value: imports = {entries: []}} = iterator.next() | |
181 | + const {value: functions} = iterator.next() | |
160 | 182 | functions.entries.forEach((typeIndex, funcIndex) => { |
161 | 183 | let customIndex = mappedFuncs.get(funcIndex) |
162 | 184 | if (customIndex === undefined) { |
163 | 185 | customIndex = mappedTypes.get(typeIndex) |
@@ -168,9 +190,9 @@ | ||
168 | 190 | } |
169 | 191 | result.indexes[funcIndex + imports.entries.length] = customIndex |
170 | 192 | }) |
171 | 193 | |
172 | - const {value: exports = {entries: []}} = iterator.next('export') | |
194 | + const {value: exports = {entries: []}} = iterator.next() | |
173 | 195 | exports.entries.forEach(entry => { |
174 | 196 | if (entry.kind === 'function') { |
175 | 197 | result.exports[entry.field_str] = entry.index |
176 | 198 | } |
@@ -182,8 +204,9 @@ | ||
182 | 204 | injectCustomSection, |
183 | 205 | inject, |
184 | 206 | decodeType, |
185 | 207 | decodeTypeMap, |
208 | + decodeGlobals, | |
186 | 209 | encodeType, |
187 | 210 | encodeTypeMap, |
188 | 211 | encodeJSON, |
189 | 212 | mergeTypeSections |
tests/wasm/caller.wasm | ||
---|---|---|
@@ -1,4 +1,3 @@ | ||
1 | - asm | |
2 | -type`` typeMap | |
1 | + asm types`` typeMap | |
3 | 2 | ` ` funcinternalize ptable call |
4 | 3 | A A A |
tests/wasm/funcRef_caller.wasm | ||
---|---|---|
@@ -1,3 +1,2 @@ | ||
1 | - asm | |
2 | -type`` typeMap ` ` `` @funcinternalize testcheck moduleself moduleexports p $memory table call callback | |
1 | + asm types`` typeMap ` ` `` @funcinternalize testcheck moduleself moduleexports p $memory table call callback | |
3 | 2 | A AA A A A callback |
tests/wasm/funcRef_reciever.wasm | ||
---|---|---|
@@ -1,4 +1,3 @@ | ||
1 | - asm | |
2 | -type`` typeMap | |
1 | + asm types`` typeMap | |
3 | 2 | ` ` funcinternalize ptable receive |
4 | 3 | A AA |
tests/wasmContainer.js | ||
---|---|---|
@@ -65,9 +65,9 @@ | ||
65 | 65 | tape('two communicating actors', async t => { |
66 | 66 | t.plan(2) |
67 | 67 | tester = t |
68 | 68 | const expectedState = { |
69 | - '/': Buffer.from('123bcbf52421f0ebf0c9a28d6546a3b374f5d56d', 'hex') | |
69 | + '/': Buffer.from('8c230b5f0f680199b24ecd1800c2970dfca7cfdc', 'hex') | |
70 | 70 | } |
71 | 71 | |
72 | 72 | const tree = new RadixTree({db}) |
73 | 73 | |
@@ -89,12 +89,12 @@ | ||
89 | 89 | t.deepEquals(stateRoot, expectedState, 'expected root!') |
90 | 90 | }) |
91 | 91 | |
92 | 92 | tape('two communicating actors with callback', async t => { |
93 | - // t.plan(2) | |
93 | + t.plan(2) | |
94 | 94 | tester = t |
95 | 95 | const expectedState = { |
96 | - '/': Buffer.from('51ded6c294314defc886b70f7f593434c8d53c95', 'hex') | |
96 | + '/': Buffer.from('9bf27cf07b75a90e0af530e2df73e3102482b24a', 'hex') | |
97 | 97 | } |
98 | 98 | |
99 | 99 | const tree = new RadixTree({ |
100 | 100 | db |
@@ -116,8 +116,39 @@ | ||
116 | 116 | |
117 | 117 | hypervisor.send(message) |
118 | 118 | const stateRoot = await hypervisor.createStateRoot() |
119 | 119 | t.deepEquals(stateRoot, expectedState, 'expected root!') |
120 | + // t.end() | |
121 | +}) | |
122 | + | |
123 | +tape.skip('two communicating actors with callback', async t => { | |
124 | + t.plan(2) | |
125 | + tester = t | |
126 | + const expectedState = { | |
127 | + '/': Buffer.from('9bf27cf07b75a90e0af530e2df73e3102482b24a', 'hex') | |
128 | + } | |
129 | + | |
130 | + const tree = new RadixTree({ | |
131 | + db | |
132 | + }) | |
133 | + | |
134 | + const recieverWasm = fs.readFileSync('./wasm/funcRef_reciever.wasm') | |
135 | + const callerWasm = fs.readFileSync('./wasm/funcRef_caller.wasm') | |
136 | + | |
137 | + const hypervisor = new Hypervisor(tree) | |
138 | + hypervisor.registerContainer(TestWasmContainer) | |
139 | + | |
140 | + const {module: receiverMod} = await hypervisor.createActor(TestWasmContainer.typeId, recieverWasm) | |
141 | + const {module: callerMod} = await hypervisor.createActor(TestWasmContainer.typeId, callerWasm) | |
142 | + | |
143 | + const message = new Message({ | |
144 | + funcRef: callerMod.getFuncRef('call'), | |
145 | + funcArguments: [receiverMod.getFuncRef('receive')] | |
146 | + }) | |
147 | + | |
148 | + hypervisor.send(message) | |
149 | + const stateRoot = await hypervisor.createStateRoot() | |
150 | + t.deepEquals(stateRoot, expectedState, 'expected root!') | |
120 | 151 | t.end() |
121 | 152 | }) |
122 | 153 | |
123 | 154 | // Increment a counter. |
tests/wast/caller.json | ||
---|---|---|
@@ -1,6 +1,6 @@ | ||
1 | 1 | { |
2 | - "type": [{ | |
2 | + "types": [{ | |
3 | 3 | "form": "func", |
4 | 4 | "params": [ |
5 | 5 | "func" |
6 | 6 | ] |
tests/wast/funcRef_caller.json | ||
---|---|---|
@@ -1,6 +1,6 @@ | ||
1 | 1 | { |
2 | - "type": [{ | |
2 | + "types": [{ | |
3 | 3 | "form": "func", |
4 | 4 | "params": [ |
5 | 5 | "func" |
6 | 6 | ] |
tests/wast/funcRef_reciever.json | ||
---|---|---|
@@ -1,6 +1,6 @@ | ||
1 | 1 | { |
2 | - "type": [{ | |
2 | + "types": [{ | |
3 | 3 | "form": "func", |
4 | 4 | "params": [ |
5 | 5 | "func" |
6 | 6 | ] |
tests/wast2wasm.js | ||
---|---|---|
@@ -20,8 +20,9 @@ | ||
20 | 20 | const mod = wabt.parseWat('module.wast', wat) |
21 | 21 | const r = mod.toBinary({log: true}) |
22 | 22 | let binary = Buffer.from(r.buffer) |
23 | 23 | if (json) { |
24 | + console.log(json) | |
24 | 25 | const buf = types.encodeJSON(json) |
25 | 26 | binary = types.injectCustomSection(buf, binary) |
26 | 27 | } |
27 | 28 | fs.writeFileSync(`${__dirname}/wasm/${file}.wasm`, binary) |
wasmContainer.js | ||
---|---|---|
@@ -171,9 +171,9 @@ | ||
171 | 171 | getInterface (funcRef) { |
172 | 172 | const self = this |
173 | 173 | return { |
174 | 174 | func: { |
175 | - externalize: (index) => { | |
175 | + externalize: index => { | |
176 | 176 | const func = this.instance.exports.table.get(index) |
177 | 177 | const object = func.object |
178 | 178 | if (object) { |
179 | 179 | return self.refs.add(object) |
@@ -195,9 +195,9 @@ | ||
195 | 195 | getGasAmount: (funcRef) => {}, |
196 | 196 | setGasAmount: (funcRef) => {} |
197 | 197 | }, |
198 | 198 | link: { |
199 | - wrap: (ref) => { | |
199 | + wrap: ref => { | |
200 | 200 | const obj = this.refs.get(ref) |
201 | 201 | const link = new LinkRef(obj.serialize()) |
202 | 202 | return this.refs.add(link, 'link') |
203 | 203 | }, |
@@ -255,9 +255,9 @@ | ||
255 | 255 | mem.set(buf) |
256 | 256 | } |
257 | 257 | }, |
258 | 258 | metering: { |
259 | - usegas: (amount) => { | |
259 | + usegas: amount => { | |
260 | 260 | funcRef.gas -= amount |
261 | 261 | if (funcRef.gas < 0) { |
262 | 262 | throw new Error('out of gas! :(') |
263 | 263 | } |
Built with git-ssb-web