git ssb

0+

wanderer🌟 / js-primea-hypervisor



Commit ff617aaaa70d98abc58ed432aac680e76748c148

added custom type encoding

Signed-off-by: wanderer <mjbecze@gmail.com>
wanderer committed on 1/23/2018, 12:13:47 AM
Parent: 7feb7c9fd152c9b122c6ee9ec57387c444a89541

Files changed

customTypes.jsadded
typeEncoding.mddeleted
tools/injectTypesadded
tools/testTypeInfo.jsonadded
customTypes.jsView
@@ -1,0 +1,137 @@
1+const Stream = require('buffer-pipe')
2+const leb = require('leb128')
3+
4+const LANGUAGE_TYPES = {
5+ 'actor': 0x0,
6+ 'buf': 0x1,
7+ 'i32': 0x7f,
8+ 'i64': 0x7e,
9+ 'f32': 0x7d,
10+ 'f64': 0x7c,
11+ 'anyFunc': 0x70,
12+ 'func': 0x60,
13+ 'block_type': 0x40,
14+
15+ 0x0: 'actor',
16+ 0x1: 'buf',
17+ 0x7f: 'i32',
18+ 0x7e: 'i64',
19+ 0x7d: 'f32',
20+ 0x7c: 'f64',
21+ 0x70: 'anyFunc',
22+ 0x60: 'func',
23+ 0x40: 'block_type'
24+}
25+
26+function encodeJSON (json) {
27+ const stream = new Stream()
28+ encodeCustomSection('type', json, stream, encodeType)
29+ encodeCustomSection('typeMap', json, stream, encodeTypeMap)
30+
31+ return stream.buffer
32+}
33+
34+function encodeCustomSection (name, json, stream, encodingFunc) {
35+ stream.write([0])
36+ let payload = new Stream()
37+
38+ // encode type
39+ leb.unsigned.write(name.length, payload)
40+ payload.write(name)
41+ encodingFunc(json[name], payload)
42+ // write the size of the payload
43+ leb.unsigned.write(payload.bytesWrote, stream)
44+ stream.write(payload.buffer)
45+ return stream
46+}
47+
48+function encodeTypeMap (json, stream) {
49+ leb.unsigned.write(json.length, stream)
50+ for (let entry of json) {
51+ leb.unsigned.write(entry.func, stream)
52+ leb.unsigned.write(entry.type, stream)
53+ }
54+ return stream
55+}
56+
57+function decodeTypeMap (buf) {
58+ const stream = new Stream(Buffer.from(buf))
59+ let numOfEntries = leb.unsigned.read(stream)
60+ const json = []
61+ while (numOfEntries--) {
62+ json.push({
63+ func: leb.unsigned.read(stream),
64+ type: leb.unsigned.read(stream)
65+ })
66+ }
67+ return json
68+}
69+
70+function encodeType (json, stream = new Stream()) {
71+ let binEntries = new Stream()
72+
73+ leb.unsigned.write(json.length, binEntries)
74+ for (let entry of json) {
75+ // a single type entry binary encoded
76+ binEntries.write([LANGUAGE_TYPES[entry.form]]) // the form
77+
78+ const len = entry.params.length // number of parameters
79+ leb.unsigned.write(len, binEntries)
80+ if (len !== 0) {
81+ binEntries.write(entry.params.map(type => LANGUAGE_TYPES[type])) // the paramter types
82+ }
83+
84+ binEntries.write([entry.return_type ? 1 : 0]) // number of return types
85+
86+ if (entry.return_type) {
87+ binEntries.write([LANGUAGE_TYPES[entry.return_type]])
88+ }
89+ }
90+
91+ stream.write(binEntries.buffer)
92+ return stream
93+}
94+
95+function decodeType (buf) {
96+ const stream = new Stream(Buffer.from(buf))
97+ const numberOfEntries = leb.unsigned.readBn(stream).toNumber()
98+ const json = []
99+ for (let i = 0; i < numberOfEntries; i++) {
100+ let type = stream.read(1)[0]
101+ const entry = {
102+ form: LANGUAGE_TYPES[type],
103+ params: []
104+ }
105+
106+ let paramCount = leb.unsigned.readBn(stream).toNumber()
107+
108+ // parse the entries
109+ while (paramCount--) {
110+ const type = stream.read(1)[0]
111+ entry.params.push(LANGUAGE_TYPES[type])
112+ }
113+ const numOfReturns = leb.unsigned.readBn(stream).toNumber()
114+ if (numOfReturns) {
115+ type = stream.read(1)[0]
116+ entry.return_type = LANGUAGE_TYPES[type]
117+ }
118+
119+ json.push(entry)
120+ }
121+ return json
122+}
123+
124+function injectCustomSection (custom, wasm) {
125+ const preramble = wasm.subarray(0, 8)
126+ const body = wasm.subarray(8)
127+ return Buffer.concat([preramble, custom, body])
128+}
129+
130+module.exports = {
131+ injectCustomSection,
132+ decodeType,
133+ decodeTypeMap,
134+ encodeType,
135+ encodeTypeMap,
136+ encodeJSON
137+}
typeEncoding.mdView
@@ -1,5 +1,0 @@
1-func = 0
2-buf = 1
3-actor = 1
4-
5-customTypeToFunc = count: i32, [funcIndex, CustomtypeIndex]
tools/injectTypesView
@@ -1,0 +1,15 @@
1+#!/usr/bin/env node
2+const fs = require('fs')
3+const types = require('../customTypes')
4+
5+const typeinfoFile = process.argv[2]
6+const inputWasmFile = process.argv[3]
7+const outputWasmFile = process.argv[4]
8+
9+const typeinfo = JSON.parse(fs.readFileSync(typeinfoFile))
10+const inputWasm = fs.readFileSync(inputWasmFile)
11+
12+const buf = types.encodeJSON(typeinfo)
13+const outputWasm = types.injectCustomSection(buf, inputWasm)
14+
15+fs.writeFileSync(outputWasmFile, outputWasm)
tools/testTypeInfo.jsonView
@@ -1,0 +1,16 @@
1+{
2+ "type": [{
3+ "form": "func",
4+ "params": [
5+ "i32",
6+ "func",
7+ "i64",
8+ "actor",
9+ "buf"
10+ ]
11+ }],
12+ "typeMap": [{
13+ "func": 0,
14+ "type": 0
15+ }]
16+}

Built with git-ssb-web