├── .gitmodules
├── .travis.yml
├── README.md
├── bin
└── wasm-meter
├── defaultCostTable.json
├── demo
├── index.js
├── package-lock.json
└── package.json
├── example
├── fac.wasm
├── fac.wast
└── index.js
├── index.js
├── package-lock.json
├── package.json
└── test
├── buildTests.js
├── defaultCostTable.json
├── expected-out
├── initCosts.json
├── json
│ ├── basic+import.wast.json
│ ├── basic.wast.json
│ ├── element.wast.json
│ ├── fac.wast.json
│ ├── memory0.wast.json
│ ├── memory1.wast.json
│ ├── memory2.wast.json
│ ├── mixedImports.wast.json
│ ├── start.wast.json
│ ├── stuff.wast.json
│ └── zeroCostOps.wast.json
└── wast
│ ├── basic+import.wast
│ ├── basic.wast
│ ├── element.wast
│ ├── fac.wast
│ ├── memory0.wast
│ ├── memory1.wast
│ ├── memory2.wast
│ ├── mixedImports.wast
│ ├── start.wast
│ ├── stuff.wast
│ └── zeroCostOps.wast
├── in
├── costTables
│ ├── memory0.wast.json.js
│ ├── memory1.wast.json.js
│ ├── memory2.wast.json.js
│ └── zeroCostOps.wast.json.js
├── json
│ ├── basic+import.wast.json
│ ├── basic.wast.json
│ ├── element.wast.json
│ ├── fac.wast.json
│ ├── memory0.wast.json
│ ├── memory1.wast.json
│ ├── memory2.wast.json
│ ├── mixedImports.wast.json
│ ├── start.wast.json
│ ├── stuff.wast.json
│ └── zeroCostOps.wast.json
└── wast
│ ├── basic+import.wast
│ ├── basic.wast
│ ├── element.wast
│ ├── fac.wast
│ ├── memory0.wast
│ ├── memory1.wast
│ ├── memory2.wast
│ ├── mixedImports.wast
│ ├── start.wast
│ ├── stuff.wast
│ └── zeroCostOps.wast
└── index.js
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "test/wabt"]
2 | path = test/wabt
3 | url = https://github.com/WebAssembly/wabt.git
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "9"
4 | env:
5 | matrix:
6 | - TEST_SUITE=test
7 | matrix:
8 | fast_finish: true
9 | include:
10 | - os: linux
11 | node_js: "9"
12 | env: TEST_SUITE=coveralls
13 | - os: linux
14 | node_js: "9"
15 | env: TEST_SUITE=lint
16 | script: npm run $TEST_SUITE
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SYNOPSIS
2 |
3 | [](https://www.npmjs.org/package/wasm-metering)
4 | [](https://travis-ci.org/ewasm/wasm-metering)
5 | [](https://coveralls.io/r/ewasm/wasm-metering)
6 |
7 | [](https://github.com/feross/standard)
8 |
9 | Injects metering into webassembly binaries. The metering counts computation
10 | time for a given program in units of `gas`. The metered wasm binary expects an
11 | import that functions as the gas counter. This works for binary version 0x1.
12 | For a more detailed description of how this works see [metering.md](https://github.com/ewasm/design/blob/master/metering.md)
13 |
14 | # INSTALL
15 | `npm install wasm-metering`
16 |
17 | # USAGE
18 | ```javascript
19 | const fs = require('fs')
20 | const metering = require('wasm-metering')
21 |
22 | const wasm = fs.readFileSync('fac.wasm')
23 | const meteredWasm = metering.meterWASM(wasm, {
24 | meterType: 'i32'
25 | })
26 |
27 | const limit = 90000000
28 | let gasUsed = 0
29 |
30 | const mod = WebAssembly.Module(meteredWasm.module)
31 | const instance = WebAssembly.Instance(mod, {
32 | 'metering': {
33 | 'usegas': (gas) => {
34 | gasUsed += gas
35 | if (gasUsed > limit) {
36 | throw new Error('out of gas!')
37 | }
38 | }
39 | }
40 | })
41 |
42 | const result = instance.exports.fac(6)
43 | console.log(`result:${result}, gas used ${gasUsed * 1e-4}`) // result:720, gas used 0.4177
44 | ```
45 | [Source](./example/index.js)
46 |
47 | # API
48 | ## meterJSON
49 |
50 | [./index.js:104-224](https://github.com/ewasm/wasm-metering/blob/5ab76de89bc07d0abfaa6d0c776c204a752a0d9d/./index.js#L104-L224 "Source code on GitHub")
51 |
52 | Injects metering into a JSON output of [wasm2json](https://github.com/ewasm/wasm-json-toolkit#wasm2json)
53 |
54 | **Parameters**
55 |
56 | - `json` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** the json tobe metered
57 | - `opts` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
58 | - `opts.costTable` **\[[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)]** the cost table to meter with. See these notes about the default. (optional, default `defaultTable`)
59 | - `opts.moduleStr` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** the import string for the metering function (optional, default `'metering'`)
60 | - `opts.fieldStr` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** the field string for the metering function (optional, default `'usegas'`)
61 | - `opts.meterType` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** the register type that is used to meter. Can be `i64`, `i32`, `f64`, `f32` (optional, default `'i64'`)
62 |
63 | Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** the metered json
64 |
65 | ## meterWASM
66 |
67 | [./index.js:236-240](https://github.com/ewasm/wasm-metering/blob/5ab76de89bc07d0abfaa6d0c776c204a752a0d9d/./index.js#L236-L240 "Source code on GitHub")
68 |
69 | Injects metering into a webassembly binary
70 |
71 | **Parameters**
72 |
73 | - `json` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** the json tobe metered
74 | - `opts` **\[[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)](default {})**
75 | - `opts.costTable` **\[[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)]** the cost table to meter with. See these notes about the default. (optional, default `defaultTable`)
76 | - `opts.moduleStr` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** the import string for the metering function (optional, default `'metering'`)
77 | - `opts.fieldStr` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** the field string for the metering function (optional, default `'usegas'`)
78 | - `opts.meterType` **\[[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** the register type that is used to meter. Can be `i64`, `i32`, `f64`, `f32` (optional, default `'i64'`)
79 | - `wasm`
80 |
81 | Returns **[Buffer](https://nodejs.org/api/buffer.html)**
82 |
83 | ## costTable
84 |
85 | The costTable option defines the cost of each of the operations.
86 | Cost Tables consist of an object whose keys are sections in a wasm binary.
87 | For example
88 | ```
89 | module.exports = {
90 | 'start': 1,
91 | 'type': {
92 | 'params': {
93 | 'DEFAULT': 1
94 | },
95 | 'return_type': {
96 | 'DEFAULT': 1
97 | }
98 | },
99 | 'import': 1,
100 | 'code': {
101 | 'locals': {
102 | 'DEFAULT': 1
103 | },
104 | 'code': {
105 | 'DEFAULT': 1
106 | }
107 | },
108 | 'memory': (entry) => {
109 | return entry.maximum * 10
110 | },
111 | 'data': 5
112 | }
113 |
114 | ```
115 |
116 | Keys can either map to a function which will be given that section's entries or
117 | an integer which will be used as the cost for each entry or an object whose
118 | keys are matched against the [JSON representation](https://github.com/ewasm/wasm-json-toolkit) of the code.
119 | The default cost table used is from [here](https://github.com/ewasm/design/blob/master/determining_wasm_gas_costs.md)
120 |
121 | The cost table can use a special key 'DEFAULT' that will be used as the cost value for any fields in a section that are not defined.
122 |
123 | ## Initial Cost
124 | The Initial cost for instantation for the module is calculated from all the
125 | sections other than the code section (which is metered at runtime). This information is
126 | stored as a [custom section](https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#name-section)
127 | that is inserted directly after the preamble. It uses the the name `initCost` and
128 | its payload contains the initial cost encoded as an unsigned leb128 interger.
129 |
130 | # LICENSE
131 | [MPL-2.0](https://tldrlegal.com/license/mozilla-public-license-2.0-(mpl-2))
132 |
--------------------------------------------------------------------------------
/bin/wasm-meter:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const fs = require('fs')
3 | const meter = require('../')
4 |
5 | const file = process.argv[2]
6 | const out = process.argv[3]
7 |
8 | if (file) {
9 | const wasm = fs.readFileSync(file)
10 | const meteredWasm = meter.meterWASM(wasm)
11 |
12 | fs.writeFileSync(out, meteredWasm)
13 | } else {
14 | const helpMessage = 'Usage: meter-meter [FILE]'
15 | process.stdout.write(helpMessage)
16 | }
17 |
--------------------------------------------------------------------------------
/defaultCostTable.json:
--------------------------------------------------------------------------------
1 | {
2 | "start": 0,
3 | "type": {
4 | "params": {
5 | "DEFAULT": 0
6 | },
7 | "return_type": {
8 | "DEFAULT": 0
9 | }
10 | },
11 | "import": 0,
12 | "code": {
13 | "locals": {
14 | "DEFAULT": 1
15 | },
16 | "code": {
17 | "get_local": 120,
18 | "set_local": 120,
19 | "tee_local": 120,
20 | "get_global": 120,
21 | "set_global": 120,
22 |
23 | "load8_s": 120,
24 | "load8_u": 120,
25 | "load16_s": 120,
26 | "load16_u": 120,
27 | "load32_s": 120,
28 | "load32_u": 120,
29 | "load": 120,
30 |
31 | "store8": 120,
32 | "store16": 120,
33 | "store32": 120,
34 | "store": 120,
35 |
36 | "grow_memory": 10000,
37 | "current_memory": 100,
38 |
39 | "nop": 1,
40 | "block": 1,
41 | "loop": 1,
42 | "if": 1,
43 | "then": 90,
44 | "else": 90,
45 | "br": 90,
46 | "br_if": 90,
47 | "br_table": 120,
48 | "return": 90,
49 |
50 | "call": 90,
51 | "call_indirect": 10000,
52 |
53 | "const": 1,
54 |
55 | "add": 45,
56 | "sub": 45,
57 | "mul": 45,
58 | "div_s": 36000,
59 | "div_u": 36000,
60 | "rem_s": 36000,
61 | "rem_u": 36000,
62 | "and": 45,
63 | "or": 45,
64 | "xor": 45,
65 | "shl": 67,
66 | "shr_u": 67,
67 | "shr_s": 67,
68 | "rotl": 90,
69 | "rotr": 90,
70 | "eq": 45,
71 | "eqz": 45,
72 | "ne": 45,
73 | "lt_s": 45,
74 | "lt_u": 45,
75 | "le_s": 45,
76 | "le_u": 45,
77 | "gt_s": 45,
78 | "gt_u": 45,
79 | "ge_s": 45,
80 | "ge_u": 45,
81 | "clz": 45,
82 | "ctz": 45,
83 | "popcnt": 45,
84 |
85 | "drop": 120,
86 | "select": 120,
87 |
88 | "unreachable": 1
89 | }
90 | },
91 | "data": 0
92 | }
93 |
--------------------------------------------------------------------------------
/demo/index.js:
--------------------------------------------------------------------------------
1 | const html = require('nanohtml')
2 | const wabt = require('wabt')
3 | const metering = require('../')
4 |
5 | function inject (wat) {
6 | const mod = wabt.parseWat('module.wast', wat)
7 | const binary = mod.toBinary({log: true})
8 | console.log('here', binary)
9 | const meteredCode = metering.meterWASM(Buffer.from(binary.buffer))
10 | const textMod = wabt.readWasm(meteredCode, { readDebugNames: true })
11 | textMod.generateNames()
12 | textMod.applyNames()
13 | const text = textMod.toText({ foldExprs: true, inlineExport: false })
14 | document.getElementById('result').innerHTML = text
15 | }
16 |
17 | const textarea = html`
18 |
19 |
23 |
24 |
25 |
`
26 |
27 | document.body.appendChild(textarea)
28 |
--------------------------------------------------------------------------------
/demo/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "JSONStream": {
8 | "version": "1.3.2",
9 | "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz",
10 | "integrity": "sha1-wQI3G27Dp887hHygDCC7D85Mbeo=",
11 | "requires": {
12 | "jsonparse": "1.3.1",
13 | "through": "2.3.8"
14 | }
15 | },
16 | "acorn": {
17 | "version": "5.5.3",
18 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz",
19 | "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ=="
20 | },
21 | "acorn-node": {
22 | "version": "1.3.0",
23 | "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.3.0.tgz",
24 | "integrity": "sha512-efP54n3d1aLfjL2UMdaXa6DsswwzJeI5rqhbFvXMrKiJ6eJFpf+7R0zN7t8IC+XKn2YOAFAv6xbBNgHUkoHWLw==",
25 | "requires": {
26 | "acorn": "5.5.3",
27 | "xtend": "4.0.1"
28 | }
29 | },
30 | "ansi-regex": {
31 | "version": "2.1.1",
32 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
33 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
34 | },
35 | "ansi-styles": {
36 | "version": "2.2.1",
37 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
38 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
39 | },
40 | "array-filter": {
41 | "version": "0.0.1",
42 | "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz",
43 | "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw="
44 | },
45 | "array-map": {
46 | "version": "0.0.0",
47 | "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz",
48 | "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI="
49 | },
50 | "array-reduce": {
51 | "version": "0.0.0",
52 | "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz",
53 | "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys="
54 | },
55 | "asn1.js": {
56 | "version": "4.10.1",
57 | "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
58 | "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
59 | "requires": {
60 | "bn.js": "4.11.8",
61 | "inherits": "2.0.3",
62 | "minimalistic-assert": "1.0.0"
63 | }
64 | },
65 | "assert": {
66 | "version": "1.4.1",
67 | "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
68 | "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
69 | "requires": {
70 | "util": "0.10.3"
71 | }
72 | },
73 | "astw": {
74 | "version": "2.2.0",
75 | "resolved": "https://registry.npmjs.org/astw/-/astw-2.2.0.tgz",
76 | "integrity": "sha1-e9QXhNMkk5h66yOba04cV6hzuRc=",
77 | "requires": {
78 | "acorn": "4.0.13"
79 | },
80 | "dependencies": {
81 | "acorn": {
82 | "version": "4.0.13",
83 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
84 | "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c="
85 | }
86 | }
87 | },
88 | "balanced-match": {
89 | "version": "1.0.0",
90 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
91 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
92 | },
93 | "base64-js": {
94 | "version": "1.2.3",
95 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.3.tgz",
96 | "integrity": "sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w=="
97 | },
98 | "bel": {
99 | "version": "6.0.0",
100 | "resolved": "https://registry.npmjs.org/bel/-/bel-6.0.0.tgz",
101 | "integrity": "sha512-KXYw+v9f7szrr0750pJ2vJbM40TLCKVd7kZv7tR/Cw8vShvR3+ouZZfZqU4nSkDuWBru7JhRPExq33bGsnCINg==",
102 | "requires": {
103 | "hyperx": "2.4.0",
104 | "is-electron": "2.1.0",
105 | "pelo": "0.1.0"
106 | }
107 | },
108 | "bn.js": {
109 | "version": "4.11.8",
110 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
111 | "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
112 | },
113 | "brace-expansion": {
114 | "version": "1.1.11",
115 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
116 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
117 | "requires": {
118 | "balanced-match": "1.0.0",
119 | "concat-map": "0.0.1"
120 | }
121 | },
122 | "brorand": {
123 | "version": "1.1.0",
124 | "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
125 | "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
126 | },
127 | "browser-pack": {
128 | "version": "6.1.0",
129 | "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz",
130 | "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==",
131 | "requires": {
132 | "JSONStream": "1.3.2",
133 | "combine-source-map": "0.8.0",
134 | "defined": "1.0.0",
135 | "safe-buffer": "5.1.1",
136 | "through2": "2.0.3",
137 | "umd": "3.0.3"
138 | }
139 | },
140 | "browser-process-hrtime": {
141 | "version": "0.1.2",
142 | "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz",
143 | "integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44="
144 | },
145 | "browser-resolve": {
146 | "version": "1.11.2",
147 | "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz",
148 | "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=",
149 | "requires": {
150 | "resolve": "1.1.7"
151 | },
152 | "dependencies": {
153 | "resolve": {
154 | "version": "1.1.7",
155 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
156 | "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs="
157 | }
158 | }
159 | },
160 | "browserify": {
161 | "version": "16.1.1",
162 | "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.1.1.tgz",
163 | "integrity": "sha512-iSH21jK0+IApV8YHOfmGt1qsGd74oflQ1Ko/28JOkWLFNBngAQfKb6WYIJ9CufH8vycqKX1sYU3y7ZrVhwevAg==",
164 | "requires": {
165 | "JSONStream": "1.3.2",
166 | "assert": "1.4.1",
167 | "browser-pack": "6.1.0",
168 | "browser-resolve": "1.11.2",
169 | "browserify-zlib": "0.2.0",
170 | "buffer": "5.1.0",
171 | "cached-path-relative": "1.0.1",
172 | "concat-stream": "1.6.2",
173 | "console-browserify": "1.1.0",
174 | "constants-browserify": "1.0.0",
175 | "crypto-browserify": "3.12.0",
176 | "defined": "1.0.0",
177 | "deps-sort": "2.0.0",
178 | "domain-browser": "1.2.0",
179 | "duplexer2": "0.1.4",
180 | "events": "2.0.0",
181 | "glob": "7.1.2",
182 | "has": "1.0.1",
183 | "htmlescape": "1.1.1",
184 | "https-browserify": "1.0.0",
185 | "inherits": "2.0.3",
186 | "insert-module-globals": "7.0.5",
187 | "labeled-stream-splicer": "2.0.1",
188 | "mkdirp": "0.5.1",
189 | "module-deps": "6.0.2",
190 | "os-browserify": "0.3.0",
191 | "parents": "1.0.1",
192 | "path-browserify": "0.0.0",
193 | "process": "0.11.10",
194 | "punycode": "1.4.1",
195 | "querystring-es3": "0.2.1",
196 | "read-only-stream": "2.0.0",
197 | "readable-stream": "2.3.6",
198 | "resolve": "1.6.0",
199 | "shasum": "1.0.2",
200 | "shell-quote": "1.6.1",
201 | "stream-browserify": "2.0.1",
202 | "stream-http": "2.8.1",
203 | "string_decoder": "1.0.3",
204 | "subarg": "1.0.0",
205 | "syntax-error": "1.4.0",
206 | "through2": "2.0.3",
207 | "timers-browserify": "1.4.2",
208 | "tty-browserify": "0.0.1",
209 | "url": "0.11.0",
210 | "util": "0.10.3",
211 | "vm-browserify": "0.0.4",
212 | "xtend": "4.0.1"
213 | },
214 | "dependencies": {
215 | "string_decoder": {
216 | "version": "1.0.3",
217 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
218 | "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
219 | "requires": {
220 | "safe-buffer": "5.1.1"
221 | }
222 | }
223 | }
224 | },
225 | "browserify-aes": {
226 | "version": "1.2.0",
227 | "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
228 | "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
229 | "requires": {
230 | "buffer-xor": "1.0.3",
231 | "cipher-base": "1.0.4",
232 | "create-hash": "1.1.3",
233 | "evp_bytestokey": "1.0.3",
234 | "inherits": "2.0.3",
235 | "safe-buffer": "5.1.1"
236 | }
237 | },
238 | "browserify-cipher": {
239 | "version": "1.0.0",
240 | "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz",
241 | "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=",
242 | "requires": {
243 | "browserify-aes": "1.2.0",
244 | "browserify-des": "1.0.0",
245 | "evp_bytestokey": "1.0.3"
246 | }
247 | },
248 | "browserify-des": {
249 | "version": "1.0.0",
250 | "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz",
251 | "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=",
252 | "requires": {
253 | "cipher-base": "1.0.4",
254 | "des.js": "1.0.0",
255 | "inherits": "2.0.3"
256 | }
257 | },
258 | "browserify-rsa": {
259 | "version": "4.0.1",
260 | "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
261 | "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
262 | "requires": {
263 | "bn.js": "4.11.8",
264 | "randombytes": "2.0.6"
265 | }
266 | },
267 | "browserify-sign": {
268 | "version": "4.0.4",
269 | "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
270 | "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
271 | "requires": {
272 | "bn.js": "4.11.8",
273 | "browserify-rsa": "4.0.1",
274 | "create-hash": "1.1.3",
275 | "create-hmac": "1.1.6",
276 | "elliptic": "6.4.0",
277 | "inherits": "2.0.3",
278 | "parse-asn1": "5.1.0"
279 | }
280 | },
281 | "browserify-zlib": {
282 | "version": "0.2.0",
283 | "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
284 | "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
285 | "requires": {
286 | "pako": "1.0.6"
287 | }
288 | },
289 | "buffer": {
290 | "version": "5.1.0",
291 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.1.0.tgz",
292 | "integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==",
293 | "requires": {
294 | "base64-js": "1.2.3",
295 | "ieee754": "1.1.11"
296 | }
297 | },
298 | "buffer-from": {
299 | "version": "1.0.0",
300 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz",
301 | "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA=="
302 | },
303 | "buffer-xor": {
304 | "version": "1.0.3",
305 | "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
306 | "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk="
307 | },
308 | "builtin-status-codes": {
309 | "version": "3.0.0",
310 | "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
311 | "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug="
312 | },
313 | "cached-path-relative": {
314 | "version": "1.0.1",
315 | "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.1.tgz",
316 | "integrity": "sha1-0JxLUoAKpMB44t2BqGmqyQ0uVOc="
317 | },
318 | "camel-case": {
319 | "version": "3.0.0",
320 | "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz",
321 | "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=",
322 | "requires": {
323 | "no-case": "2.3.2",
324 | "upper-case": "1.1.3"
325 | }
326 | },
327 | "chalk": {
328 | "version": "1.1.3",
329 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
330 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
331 | "requires": {
332 | "ansi-styles": "2.2.1",
333 | "escape-string-regexp": "1.0.5",
334 | "has-ansi": "2.0.0",
335 | "strip-ansi": "3.0.1",
336 | "supports-color": "2.0.0"
337 | }
338 | },
339 | "cipher-base": {
340 | "version": "1.0.4",
341 | "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
342 | "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
343 | "requires": {
344 | "inherits": "2.0.3",
345 | "safe-buffer": "5.1.1"
346 | }
347 | },
348 | "combine-source-map": {
349 | "version": "0.8.0",
350 | "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz",
351 | "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=",
352 | "requires": {
353 | "convert-source-map": "1.1.3",
354 | "inline-source-map": "0.6.2",
355 | "lodash.memoize": "3.0.4",
356 | "source-map": "0.5.7"
357 | },
358 | "dependencies": {
359 | "convert-source-map": {
360 | "version": "1.1.3",
361 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz",
362 | "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA="
363 | }
364 | }
365 | },
366 | "concat-map": {
367 | "version": "0.0.1",
368 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
369 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
370 | },
371 | "concat-stream": {
372 | "version": "1.6.2",
373 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
374 | "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
375 | "requires": {
376 | "buffer-from": "1.0.0",
377 | "inherits": "2.0.3",
378 | "readable-stream": "2.3.6",
379 | "typedarray": "0.0.6"
380 | }
381 | },
382 | "console-browserify": {
383 | "version": "1.1.0",
384 | "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
385 | "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
386 | "requires": {
387 | "date-now": "0.1.4"
388 | }
389 | },
390 | "constants-browserify": {
391 | "version": "1.0.0",
392 | "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
393 | "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U="
394 | },
395 | "convert-source-map": {
396 | "version": "1.5.1",
397 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz",
398 | "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU="
399 | },
400 | "core-util-is": {
401 | "version": "1.0.2",
402 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
403 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
404 | },
405 | "create-ecdh": {
406 | "version": "4.0.0",
407 | "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz",
408 | "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=",
409 | "requires": {
410 | "bn.js": "4.11.8",
411 | "elliptic": "6.4.0"
412 | }
413 | },
414 | "create-hash": {
415 | "version": "1.1.3",
416 | "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz",
417 | "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=",
418 | "requires": {
419 | "cipher-base": "1.0.4",
420 | "inherits": "2.0.3",
421 | "ripemd160": "2.0.1",
422 | "sha.js": "2.4.11"
423 | }
424 | },
425 | "create-hmac": {
426 | "version": "1.1.6",
427 | "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz",
428 | "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=",
429 | "requires": {
430 | "cipher-base": "1.0.4",
431 | "create-hash": "1.1.3",
432 | "inherits": "2.0.3",
433 | "ripemd160": "2.0.1",
434 | "safe-buffer": "5.1.1",
435 | "sha.js": "2.4.11"
436 | }
437 | },
438 | "crypto-browserify": {
439 | "version": "3.12.0",
440 | "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
441 | "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
442 | "requires": {
443 | "browserify-cipher": "1.0.0",
444 | "browserify-sign": "4.0.4",
445 | "create-ecdh": "4.0.0",
446 | "create-hash": "1.1.3",
447 | "create-hmac": "1.1.6",
448 | "diffie-hellman": "5.0.2",
449 | "inherits": "2.0.3",
450 | "pbkdf2": "3.0.14",
451 | "public-encrypt": "4.0.0",
452 | "randombytes": "2.0.6",
453 | "randomfill": "1.0.4"
454 | }
455 | },
456 | "date-now": {
457 | "version": "0.1.4",
458 | "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
459 | "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs="
460 | },
461 | "defined": {
462 | "version": "1.0.0",
463 | "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
464 | "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM="
465 | },
466 | "deps-sort": {
467 | "version": "2.0.0",
468 | "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz",
469 | "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=",
470 | "requires": {
471 | "JSONStream": "1.3.2",
472 | "shasum": "1.0.2",
473 | "subarg": "1.0.0",
474 | "through2": "2.0.3"
475 | }
476 | },
477 | "des.js": {
478 | "version": "1.0.0",
479 | "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
480 | "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
481 | "requires": {
482 | "inherits": "2.0.3",
483 | "minimalistic-assert": "1.0.0"
484 | }
485 | },
486 | "detective": {
487 | "version": "5.1.0",
488 | "resolved": "https://registry.npmjs.org/detective/-/detective-5.1.0.tgz",
489 | "integrity": "sha512-TFHMqfOvxlgrfVzTEkNBSh9SvSNX/HfF4OFI2QFGCyPm02EsyILqnUeb5P6q7JZ3SFNTBL5t2sePRgrN4epUWQ==",
490 | "requires": {
491 | "acorn-node": "1.3.0",
492 | "defined": "1.0.0",
493 | "minimist": "1.2.0"
494 | }
495 | },
496 | "diffie-hellman": {
497 | "version": "5.0.2",
498 | "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz",
499 | "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=",
500 | "requires": {
501 | "bn.js": "4.11.8",
502 | "miller-rabin": "4.0.1",
503 | "randombytes": "2.0.6"
504 | }
505 | },
506 | "domain-browser": {
507 | "version": "1.2.0",
508 | "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
509 | "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA=="
510 | },
511 | "duplexer2": {
512 | "version": "0.1.4",
513 | "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
514 | "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
515 | "requires": {
516 | "readable-stream": "2.3.6"
517 | }
518 | },
519 | "elliptic": {
520 | "version": "6.4.0",
521 | "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz",
522 | "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=",
523 | "requires": {
524 | "bn.js": "4.11.8",
525 | "brorand": "1.1.0",
526 | "hash.js": "1.1.3",
527 | "hmac-drbg": "1.0.1",
528 | "inherits": "2.0.3",
529 | "minimalistic-assert": "1.0.0",
530 | "minimalistic-crypto-utils": "1.0.1"
531 | }
532 | },
533 | "escape-string-regexp": {
534 | "version": "1.0.5",
535 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
536 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
537 | },
538 | "events": {
539 | "version": "2.0.0",
540 | "resolved": "https://registry.npmjs.org/events/-/events-2.0.0.tgz",
541 | "integrity": "sha512-r/M5YkNg9zwI8QbSf7tsDWWJvO3PGwZXyG7GpFAxtMASnHL2eblFd7iHiGPtyGKKFPZ59S63NeX10Ws6WqGDcg=="
542 | },
543 | "evp_bytestokey": {
544 | "version": "1.0.3",
545 | "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
546 | "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
547 | "requires": {
548 | "md5.js": "1.3.4",
549 | "safe-buffer": "5.1.1"
550 | }
551 | },
552 | "fs.realpath": {
553 | "version": "1.0.0",
554 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
555 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
556 | },
557 | "function-bind": {
558 | "version": "1.1.1",
559 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
560 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
561 | },
562 | "glob": {
563 | "version": "7.1.2",
564 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
565 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
566 | "requires": {
567 | "fs.realpath": "1.0.0",
568 | "inflight": "1.0.6",
569 | "inherits": "2.0.3",
570 | "minimatch": "3.0.4",
571 | "once": "1.4.0",
572 | "path-is-absolute": "1.0.1"
573 | }
574 | },
575 | "has": {
576 | "version": "1.0.1",
577 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
578 | "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=",
579 | "requires": {
580 | "function-bind": "1.1.1"
581 | }
582 | },
583 | "has-ansi": {
584 | "version": "2.0.0",
585 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
586 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
587 | "requires": {
588 | "ansi-regex": "2.1.1"
589 | }
590 | },
591 | "hash-base": {
592 | "version": "2.0.2",
593 | "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
594 | "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=",
595 | "requires": {
596 | "inherits": "2.0.3"
597 | }
598 | },
599 | "hash.js": {
600 | "version": "1.1.3",
601 | "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
602 | "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
603 | "requires": {
604 | "inherits": "2.0.3",
605 | "minimalistic-assert": "1.0.0"
606 | }
607 | },
608 | "hmac-drbg": {
609 | "version": "1.0.1",
610 | "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
611 | "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
612 | "requires": {
613 | "hash.js": "1.1.3",
614 | "minimalistic-assert": "1.0.0",
615 | "minimalistic-crypto-utils": "1.0.1"
616 | }
617 | },
618 | "htmlescape": {
619 | "version": "1.1.1",
620 | "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz",
621 | "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E="
622 | },
623 | "https-browserify": {
624 | "version": "1.0.0",
625 | "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
626 | "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM="
627 | },
628 | "hyperscript-attribute-to-property": {
629 | "version": "1.0.0",
630 | "resolved": "https://registry.npmjs.org/hyperscript-attribute-to-property/-/hyperscript-attribute-to-property-1.0.0.tgz",
631 | "integrity": "sha1-glMI1Ju44pV5I/cxmBvMgRytev8="
632 | },
633 | "hyperx": {
634 | "version": "2.4.0",
635 | "resolved": "https://registry.npmjs.org/hyperx/-/hyperx-2.4.0.tgz",
636 | "integrity": "sha512-43jbOQfVkm9U0oAyBZ4Vt2eB0hZWS5EyrOhR3ZbgUrcprutGu9s/C476OVFL3QU1iynKO5s9kZsWrZm19gJKjg==",
637 | "requires": {
638 | "hyperscript-attribute-to-property": "1.0.0"
639 | }
640 | },
641 | "ieee754": {
642 | "version": "1.1.11",
643 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.11.tgz",
644 | "integrity": "sha512-VhDzCKN7K8ufStx/CLj5/PDTMgph+qwN5Pkd5i0sGnVwk56zJ0lkT8Qzi1xqWLS0Wp29DgDtNeS7v8/wMoZeHg=="
645 | },
646 | "indexof": {
647 | "version": "0.0.1",
648 | "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
649 | "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
650 | },
651 | "inflight": {
652 | "version": "1.0.6",
653 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
654 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
655 | "requires": {
656 | "once": "1.4.0",
657 | "wrappy": "1.0.2"
658 | }
659 | },
660 | "inherits": {
661 | "version": "2.0.3",
662 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
663 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
664 | },
665 | "inline-source-map": {
666 | "version": "0.6.2",
667 | "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz",
668 | "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=",
669 | "requires": {
670 | "source-map": "0.5.7"
671 | }
672 | },
673 | "insert-module-globals": {
674 | "version": "7.0.5",
675 | "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.5.tgz",
676 | "integrity": "sha512-wgRtrCpMm0ruH2hgLUIx+9YfJsgJQmU1KkPUzTuatW9dbH19yPRqAQhFX1HJU6zbmg2IMmt80BgSE5MWuksw3Q==",
677 | "requires": {
678 | "JSONStream": "1.3.2",
679 | "combine-source-map": "0.8.0",
680 | "concat-stream": "1.6.2",
681 | "is-buffer": "1.1.6",
682 | "lexical-scope": "1.2.0",
683 | "process": "0.11.10",
684 | "through2": "2.0.3",
685 | "xtend": "4.0.1"
686 | },
687 | "dependencies": {
688 | "is-buffer": {
689 | "version": "1.1.6",
690 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
691 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
692 | }
693 | }
694 | },
695 | "is-boolean-attribute": {
696 | "version": "0.0.1",
697 | "resolved": "https://registry.npmjs.org/is-boolean-attribute/-/is-boolean-attribute-0.0.1.tgz",
698 | "integrity": "sha1-JKtZt9y52jYSx3PmDGVlZeWgmAw="
699 | },
700 | "is-buffer": {
701 | "version": "2.0.2",
702 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.2.tgz",
703 | "integrity": "sha512-imvkm8cOGKeZ/NwkAd+FAURi0hsL9gr3kvdi0r3MnqChcOdPaQRIOQiOU+sD40XzUIe6nFmSHYtQjbkDvaQbEg=="
704 | },
705 | "is-electron": {
706 | "version": "2.1.0",
707 | "resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.1.0.tgz",
708 | "integrity": "sha512-dkg5xT383+M6zIbbXW/z7n2nz4SFUi2OSyhntnFYkRdtV+HVEfdjEK+5AWisfYgkpe3WYjTIuh7toaKmSfFVWw=="
709 | },
710 | "isarray": {
711 | "version": "1.0.0",
712 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
713 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
714 | },
715 | "json-stable-stringify": {
716 | "version": "0.0.1",
717 | "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz",
718 | "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=",
719 | "requires": {
720 | "jsonify": "0.0.0"
721 | }
722 | },
723 | "jsonify": {
724 | "version": "0.0.0",
725 | "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
726 | "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM="
727 | },
728 | "jsonparse": {
729 | "version": "1.3.1",
730 | "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
731 | "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA="
732 | },
733 | "labeled-stream-splicer": {
734 | "version": "2.0.1",
735 | "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz",
736 | "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==",
737 | "requires": {
738 | "inherits": "2.0.3",
739 | "isarray": "2.0.4",
740 | "stream-splicer": "2.0.0"
741 | },
742 | "dependencies": {
743 | "isarray": {
744 | "version": "2.0.4",
745 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz",
746 | "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA=="
747 | }
748 | }
749 | },
750 | "lexical-scope": {
751 | "version": "1.2.0",
752 | "resolved": "https://registry.npmjs.org/lexical-scope/-/lexical-scope-1.2.0.tgz",
753 | "integrity": "sha1-/Ope3HBKSzqHls3KQZw6CvryLfQ=",
754 | "requires": {
755 | "astw": "2.2.0"
756 | }
757 | },
758 | "lodash.memoize": {
759 | "version": "3.0.4",
760 | "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz",
761 | "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8="
762 | },
763 | "lower-case": {
764 | "version": "1.1.4",
765 | "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz",
766 | "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw="
767 | },
768 | "magic-string": {
769 | "version": "0.23.2",
770 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.23.2.tgz",
771 | "integrity": "sha512-oIUZaAxbcxYIp4AyLafV6OVKoB3YouZs0UTCJ8mOKBHNyJgGDaMJ4TgA+VylJh6fx7EQCC52XkbURxxG9IoJXA==",
772 | "requires": {
773 | "sourcemap-codec": "1.4.1"
774 | }
775 | },
776 | "md5.js": {
777 | "version": "1.3.4",
778 | "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
779 | "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=",
780 | "requires": {
781 | "hash-base": "3.0.4",
782 | "inherits": "2.0.3"
783 | },
784 | "dependencies": {
785 | "hash-base": {
786 | "version": "3.0.4",
787 | "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
788 | "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
789 | "requires": {
790 | "inherits": "2.0.3",
791 | "safe-buffer": "5.1.1"
792 | }
793 | }
794 | }
795 | },
796 | "merge-source-map": {
797 | "version": "1.0.4",
798 | "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz",
799 | "integrity": "sha1-pd5GU42uhNQRTMXqArR3KmNGcB8=",
800 | "requires": {
801 | "source-map": "0.5.7"
802 | }
803 | },
804 | "miller-rabin": {
805 | "version": "4.0.1",
806 | "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
807 | "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
808 | "requires": {
809 | "bn.js": "4.11.8",
810 | "brorand": "1.1.0"
811 | }
812 | },
813 | "minimalistic-assert": {
814 | "version": "1.0.0",
815 | "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz",
816 | "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M="
817 | },
818 | "minimalistic-crypto-utils": {
819 | "version": "1.0.1",
820 | "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
821 | "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
822 | },
823 | "minimatch": {
824 | "version": "3.0.4",
825 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
826 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
827 | "requires": {
828 | "brace-expansion": "1.1.11"
829 | }
830 | },
831 | "minimist": {
832 | "version": "1.2.0",
833 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
834 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
835 | },
836 | "mkdirp": {
837 | "version": "0.5.1",
838 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
839 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
840 | "requires": {
841 | "minimist": "0.0.8"
842 | },
843 | "dependencies": {
844 | "minimist": {
845 | "version": "0.0.8",
846 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
847 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
848 | }
849 | }
850 | },
851 | "module-deps": {
852 | "version": "6.0.2",
853 | "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.0.2.tgz",
854 | "integrity": "sha512-KWBI3009iRnHjRlxRhe8nJ6kdeBTg4sMi5N6AZgg5f1/v5S7EBCRBOY854I4P5Anl4kx6AJH+4bBBC2Gi3nkvg==",
855 | "requires": {
856 | "JSONStream": "1.3.2",
857 | "browser-resolve": "1.11.2",
858 | "cached-path-relative": "1.0.1",
859 | "concat-stream": "1.6.2",
860 | "defined": "1.0.0",
861 | "detective": "5.1.0",
862 | "duplexer2": "0.1.4",
863 | "inherits": "2.0.3",
864 | "parents": "1.0.1",
865 | "readable-stream": "2.3.6",
866 | "resolve": "1.6.0",
867 | "stream-combiner2": "1.1.1",
868 | "subarg": "1.0.0",
869 | "through2": "2.0.3",
870 | "xtend": "4.0.1"
871 | }
872 | },
873 | "mutexify": {
874 | "version": "1.2.0",
875 | "resolved": "https://registry.npmjs.org/mutexify/-/mutexify-1.2.0.tgz",
876 | "integrity": "sha512-oprzxd2zhfrJqEuB98qc1dRMMonClBQ57UPDjnbcrah4orEMTq1jq3+AcdFe5ePzdbJXI7zmdhfftIdMnhYFoQ=="
877 | },
878 | "nanoassert": {
879 | "version": "1.1.0",
880 | "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-1.1.0.tgz",
881 | "integrity": "sha1-TzFS4JVA/eKMdvRLGbvNHVpCR40="
882 | },
883 | "nanobench": {
884 | "version": "2.1.1",
885 | "resolved": "https://registry.npmjs.org/nanobench/-/nanobench-2.1.1.tgz",
886 | "integrity": "sha512-z+Vv7zElcjN+OpzAxAquUayFLGK3JI/ubCl0Oh64YQqsTGG09CGqieJVQw4ui8huDnnAgrvTv93qi5UaOoNj8A==",
887 | "requires": {
888 | "browser-process-hrtime": "0.1.2",
889 | "chalk": "1.1.3",
890 | "mutexify": "1.2.0",
891 | "pretty-hrtime": "1.0.3"
892 | }
893 | },
894 | "nanohtml": {
895 | "version": "1.2.2",
896 | "resolved": "https://registry.npmjs.org/nanohtml/-/nanohtml-1.2.2.tgz",
897 | "integrity": "sha512-C2Ddjr6ItgOuTOXX/BQv/lSAgPm/Zojz+9+wDDw/AqcfwAJCpC9g0njiprJM0f6Ykd7C/mAVSyMHDhaZDDzgbQ==",
898 | "requires": {
899 | "acorn": "5.5.3",
900 | "camel-case": "3.0.0",
901 | "convert-source-map": "1.5.1",
902 | "hyperx": "2.4.0",
903 | "is-boolean-attribute": "0.0.1",
904 | "nanoassert": "1.1.0",
905 | "nanobench": "2.1.1",
906 | "normalize-html-whitespace": "0.2.0",
907 | "through2": "2.0.3",
908 | "transform-ast": "2.4.3"
909 | }
910 | },
911 | "no-case": {
912 | "version": "2.3.2",
913 | "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
914 | "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==",
915 | "requires": {
916 | "lower-case": "1.1.4"
917 | }
918 | },
919 | "normalize-html-whitespace": {
920 | "version": "0.2.0",
921 | "resolved": "https://registry.npmjs.org/normalize-html-whitespace/-/normalize-html-whitespace-0.2.0.tgz",
922 | "integrity": "sha1-EBci9kI1Ucdc24+dEE/4UNrx4Q4="
923 | },
924 | "once": {
925 | "version": "1.4.0",
926 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
927 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
928 | "requires": {
929 | "wrappy": "1.0.2"
930 | }
931 | },
932 | "os-browserify": {
933 | "version": "0.3.0",
934 | "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
935 | "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc="
936 | },
937 | "pako": {
938 | "version": "1.0.6",
939 | "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
940 | "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg=="
941 | },
942 | "parents": {
943 | "version": "1.0.1",
944 | "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz",
945 | "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=",
946 | "requires": {
947 | "path-platform": "0.11.15"
948 | }
949 | },
950 | "parse-asn1": {
951 | "version": "5.1.0",
952 | "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz",
953 | "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=",
954 | "requires": {
955 | "asn1.js": "4.10.1",
956 | "browserify-aes": "1.2.0",
957 | "create-hash": "1.1.3",
958 | "evp_bytestokey": "1.0.3",
959 | "pbkdf2": "3.0.14"
960 | }
961 | },
962 | "path-browserify": {
963 | "version": "0.0.0",
964 | "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
965 | "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo="
966 | },
967 | "path-is-absolute": {
968 | "version": "1.0.1",
969 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
970 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
971 | },
972 | "path-parse": {
973 | "version": "1.0.5",
974 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
975 | "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME="
976 | },
977 | "path-platform": {
978 | "version": "0.11.15",
979 | "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz",
980 | "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I="
981 | },
982 | "pbkdf2": {
983 | "version": "3.0.14",
984 | "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz",
985 | "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==",
986 | "requires": {
987 | "create-hash": "1.1.3",
988 | "create-hmac": "1.1.6",
989 | "ripemd160": "2.0.1",
990 | "safe-buffer": "5.1.1",
991 | "sha.js": "2.4.11"
992 | }
993 | },
994 | "pelo": {
995 | "version": "0.1.0",
996 | "resolved": "https://registry.npmjs.org/pelo/-/pelo-0.1.0.tgz",
997 | "integrity": "sha512-+oVixa69fxS/X+3s1DaSJVQLG/ukHfjK2pHCmpIgjRChp73lnAfbqOYZ0MEo5C5yVkYeUJSoWAcRK0lx0hvOjQ=="
998 | },
999 | "pretty-hrtime": {
1000 | "version": "1.0.3",
1001 | "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
1002 | "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE="
1003 | },
1004 | "process": {
1005 | "version": "0.11.10",
1006 | "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
1007 | "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI="
1008 | },
1009 | "process-nextick-args": {
1010 | "version": "2.0.0",
1011 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
1012 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
1013 | },
1014 | "public-encrypt": {
1015 | "version": "4.0.0",
1016 | "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz",
1017 | "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=",
1018 | "requires": {
1019 | "bn.js": "4.11.8",
1020 | "browserify-rsa": "4.0.1",
1021 | "create-hash": "1.1.3",
1022 | "parse-asn1": "5.1.0",
1023 | "randombytes": "2.0.6"
1024 | }
1025 | },
1026 | "punycode": {
1027 | "version": "1.4.1",
1028 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
1029 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
1030 | },
1031 | "querystring": {
1032 | "version": "0.2.0",
1033 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
1034 | "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
1035 | },
1036 | "querystring-es3": {
1037 | "version": "0.2.1",
1038 | "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
1039 | "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM="
1040 | },
1041 | "randombytes": {
1042 | "version": "2.0.6",
1043 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz",
1044 | "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==",
1045 | "requires": {
1046 | "safe-buffer": "5.1.1"
1047 | }
1048 | },
1049 | "randomfill": {
1050 | "version": "1.0.4",
1051 | "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
1052 | "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
1053 | "requires": {
1054 | "randombytes": "2.0.6",
1055 | "safe-buffer": "5.1.1"
1056 | }
1057 | },
1058 | "read-only-stream": {
1059 | "version": "2.0.0",
1060 | "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz",
1061 | "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=",
1062 | "requires": {
1063 | "readable-stream": "2.3.6"
1064 | }
1065 | },
1066 | "readable-stream": {
1067 | "version": "2.3.6",
1068 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
1069 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
1070 | "requires": {
1071 | "core-util-is": "1.0.2",
1072 | "inherits": "2.0.3",
1073 | "isarray": "1.0.0",
1074 | "process-nextick-args": "2.0.0",
1075 | "safe-buffer": "5.1.1",
1076 | "string_decoder": "1.1.1",
1077 | "util-deprecate": "1.0.2"
1078 | }
1079 | },
1080 | "resolve": {
1081 | "version": "1.6.0",
1082 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.6.0.tgz",
1083 | "integrity": "sha512-mw7JQNu5ExIkcw4LPih0owX/TZXjD/ZUF/ZQ/pDnkw3ZKhDcZZw5klmBlj6gVMwjQ3Pz5Jgu7F3d0jcDVuEWdw==",
1084 | "requires": {
1085 | "path-parse": "1.0.5"
1086 | }
1087 | },
1088 | "ripemd160": {
1089 | "version": "2.0.1",
1090 | "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
1091 | "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=",
1092 | "requires": {
1093 | "hash-base": "2.0.2",
1094 | "inherits": "2.0.3"
1095 | }
1096 | },
1097 | "safe-buffer": {
1098 | "version": "5.1.1",
1099 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
1100 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
1101 | },
1102 | "sha.js": {
1103 | "version": "2.4.11",
1104 | "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
1105 | "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
1106 | "requires": {
1107 | "inherits": "2.0.3",
1108 | "safe-buffer": "5.1.1"
1109 | }
1110 | },
1111 | "shasum": {
1112 | "version": "1.0.2",
1113 | "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz",
1114 | "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=",
1115 | "requires": {
1116 | "json-stable-stringify": "0.0.1",
1117 | "sha.js": "2.4.11"
1118 | }
1119 | },
1120 | "shell-quote": {
1121 | "version": "1.6.1",
1122 | "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz",
1123 | "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=",
1124 | "requires": {
1125 | "array-filter": "0.0.1",
1126 | "array-map": "0.0.0",
1127 | "array-reduce": "0.0.0",
1128 | "jsonify": "0.0.0"
1129 | }
1130 | },
1131 | "source-map": {
1132 | "version": "0.5.7",
1133 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
1134 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
1135 | },
1136 | "sourcemap-codec": {
1137 | "version": "1.4.1",
1138 | "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.1.tgz",
1139 | "integrity": "sha512-hX1eNBNuilj8yfFnECh0DzLgwKpBLMIvmhgEhixXNui8lMLBInTI8Kyxt++RwJnMNu7cAUo635L2+N1TxMJCzA=="
1140 | },
1141 | "stream-browserify": {
1142 | "version": "2.0.1",
1143 | "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
1144 | "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
1145 | "requires": {
1146 | "inherits": "2.0.3",
1147 | "readable-stream": "2.3.6"
1148 | }
1149 | },
1150 | "stream-combiner2": {
1151 | "version": "1.1.1",
1152 | "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz",
1153 | "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=",
1154 | "requires": {
1155 | "duplexer2": "0.1.4",
1156 | "readable-stream": "2.3.6"
1157 | }
1158 | },
1159 | "stream-http": {
1160 | "version": "2.8.1",
1161 | "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.1.tgz",
1162 | "integrity": "sha512-cQ0jo17BLca2r0GfRdZKYAGLU6JRoIWxqSOakUMuKOT6MOK7AAlE856L33QuDmAy/eeOrhLee3dZKX0Uadu93A==",
1163 | "requires": {
1164 | "builtin-status-codes": "3.0.0",
1165 | "inherits": "2.0.3",
1166 | "readable-stream": "2.3.6",
1167 | "to-arraybuffer": "1.0.1",
1168 | "xtend": "4.0.1"
1169 | }
1170 | },
1171 | "stream-splicer": {
1172 | "version": "2.0.0",
1173 | "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz",
1174 | "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=",
1175 | "requires": {
1176 | "inherits": "2.0.3",
1177 | "readable-stream": "2.3.6"
1178 | }
1179 | },
1180 | "string_decoder": {
1181 | "version": "1.1.1",
1182 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
1183 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
1184 | "requires": {
1185 | "safe-buffer": "5.1.1"
1186 | }
1187 | },
1188 | "strip-ansi": {
1189 | "version": "3.0.1",
1190 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
1191 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
1192 | "requires": {
1193 | "ansi-regex": "2.1.1"
1194 | }
1195 | },
1196 | "subarg": {
1197 | "version": "1.0.0",
1198 | "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz",
1199 | "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=",
1200 | "requires": {
1201 | "minimist": "1.2.0"
1202 | }
1203 | },
1204 | "supports-color": {
1205 | "version": "2.0.0",
1206 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
1207 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
1208 | },
1209 | "syntax-error": {
1210 | "version": "1.4.0",
1211 | "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz",
1212 | "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==",
1213 | "requires": {
1214 | "acorn-node": "1.3.0"
1215 | }
1216 | },
1217 | "tachyons": {
1218 | "version": "4.9.1",
1219 | "resolved": "https://registry.npmjs.org/tachyons/-/tachyons-4.9.1.tgz",
1220 | "integrity": "sha512-trJFXhzDZeHRcd9Bqn6ub3e0VqGWKMsGdP7RJoT+8Ihoak41o1qCwqcFx8hsFlfFWa6a4jsb464TNXnTt+MPnw=="
1221 | },
1222 | "through": {
1223 | "version": "2.3.8",
1224 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
1225 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
1226 | },
1227 | "through2": {
1228 | "version": "2.0.3",
1229 | "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
1230 | "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
1231 | "requires": {
1232 | "readable-stream": "2.3.6",
1233 | "xtend": "4.0.1"
1234 | }
1235 | },
1236 | "timers-browserify": {
1237 | "version": "1.4.2",
1238 | "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz",
1239 | "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=",
1240 | "requires": {
1241 | "process": "0.11.10"
1242 | }
1243 | },
1244 | "to-arraybuffer": {
1245 | "version": "1.0.1",
1246 | "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
1247 | "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M="
1248 | },
1249 | "transform-ast": {
1250 | "version": "2.4.3",
1251 | "resolved": "https://registry.npmjs.org/transform-ast/-/transform-ast-2.4.3.tgz",
1252 | "integrity": "sha512-H/agTb5MRPp7FwN/uFOOvqm10pTWCcWksXL2H90BqS+bKeNPCYQsWza8Unx0+3+uBn0mHJxs/FI0BVu0gJ5e4Q==",
1253 | "requires": {
1254 | "acorn-node": "1.3.0",
1255 | "convert-source-map": "1.5.1",
1256 | "is-buffer": "2.0.2",
1257 | "magic-string": "0.23.2",
1258 | "merge-source-map": "1.0.4",
1259 | "nanobench": "2.1.1"
1260 | }
1261 | },
1262 | "tty-browserify": {
1263 | "version": "0.0.1",
1264 | "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz",
1265 | "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw=="
1266 | },
1267 | "typedarray": {
1268 | "version": "0.0.6",
1269 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
1270 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
1271 | },
1272 | "umd": {
1273 | "version": "3.0.3",
1274 | "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz",
1275 | "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow=="
1276 | },
1277 | "upper-case": {
1278 | "version": "1.1.3",
1279 | "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
1280 | "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg="
1281 | },
1282 | "url": {
1283 | "version": "0.11.0",
1284 | "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
1285 | "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
1286 | "requires": {
1287 | "punycode": "1.3.2",
1288 | "querystring": "0.2.0"
1289 | },
1290 | "dependencies": {
1291 | "punycode": {
1292 | "version": "1.3.2",
1293 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
1294 | "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
1295 | }
1296 | }
1297 | },
1298 | "util": {
1299 | "version": "0.10.3",
1300 | "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
1301 | "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
1302 | "requires": {
1303 | "inherits": "2.0.1"
1304 | },
1305 | "dependencies": {
1306 | "inherits": {
1307 | "version": "2.0.1",
1308 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
1309 | "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE="
1310 | }
1311 | }
1312 | },
1313 | "util-deprecate": {
1314 | "version": "1.0.2",
1315 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
1316 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
1317 | },
1318 | "vm-browserify": {
1319 | "version": "0.0.4",
1320 | "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
1321 | "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=",
1322 | "requires": {
1323 | "indexof": "0.0.1"
1324 | }
1325 | },
1326 | "wabt": {
1327 | "version": "1.0.0",
1328 | "resolved": "https://registry.npmjs.org/wabt/-/wabt-1.0.0.tgz",
1329 | "integrity": "sha512-Apt7rylKNS2VWMMYgY43aYStopVpc9wCJ16y0CznaWcJC2vs7BLVGAV6pffBqn28BfWYeYVA92zRwBstaq1zaA=="
1330 | },
1331 | "wrappy": {
1332 | "version": "1.0.2",
1333 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1334 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
1335 | },
1336 | "xtend": {
1337 | "version": "4.0.1",
1338 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
1339 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
1340 | }
1341 | }
1342 | }
1343 |
--------------------------------------------------------------------------------
/demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "bel": "^6.0.0",
13 | "browserify": "^16.1.1",
14 | "nanohtml": "^1.2.2",
15 | "tachyons": "^4.9.1",
16 | "wabt": "1.0.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/example/fac.wasm:
--------------------------------------------------------------------------------
1 | asm ` fac
2 | AHA Ak l
--------------------------------------------------------------------------------
/example/fac.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (func $fac (param i32) (result i32)
3 | (if (result i32) (i32.lt_s (get_local 0) (i32.const 1))
4 | (then (i32.const 1))
5 | (else
6 | (i32.mul (get_local 0) (call $fac (i32.sub (get_local 0) (i32.const 1))))
7 | )
8 | )
9 | )
10 | (export "fac" (func $fac))
11 | )
12 |
--------------------------------------------------------------------------------
/example/index.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const metering = require('../')
3 |
4 | const wasm = fs.readFileSync(`${__dirname}/fac.wasm`)
5 | const meteredWasm = metering.meterWASM(wasm, {
6 | meterType: 'i32'
7 | })
8 |
9 | const limit = 90000000
10 | let gasUsed = 0
11 |
12 | const mod = new WebAssembly.Module(meteredWasm)
13 | const instance = new WebAssembly.Instance(mod, {
14 | 'metering': {
15 | 'usegas': (gas) => {
16 | gasUsed += gas
17 | if (gasUsed > limit) {
18 | throw new Error('out of gas!')
19 | }
20 | }
21 | }
22 | })
23 |
24 | const result = instance.exports.fac(6)
25 | console.log(`result:${result}, gas used ${gasUsed * 1e-4}`) // result:720, gas used 0.4177
26 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const toolkit = require('wasm-json-toolkit')
2 | const text2json = toolkit.text2json
3 | const SECTION_IDS = require('wasm-json-toolkit/json2wasm').SECTION_IDS
4 | const defaultCostTable = require('./defaultCostTable.json')
5 |
6 | // gets the cost of an operation for entry in a section from the cost table
7 | function getCost (json, costTable = {}, defaultCost = 0) {
8 | let cost = 0
9 | // finds the default cost
10 | defaultCost = costTable['DEFAULT'] !== undefined ? costTable['DEFAULT'] : 0
11 |
12 | if (Array.isArray(json)) {
13 | json.forEach(el => {
14 | cost += getCost(el, costTable)
15 | })
16 | } else if (typeof json === 'object') {
17 | for (const propName in json) {
18 | const propCost = costTable[propName]
19 | if (propCost) {
20 | cost += getCost(json[propName], propCost, defaultCost)
21 | }
22 | }
23 | } else if (costTable[json] === undefined) {
24 | cost = defaultCost
25 | } else {
26 | cost = costTable[json]
27 | }
28 | return cost
29 | }
30 |
31 | // meters a single code entrie
32 | function meterCodeEntry (entry, costTable, meterFuncIndex, meterType, cost) {
33 | function meteringStatement (cost, meteringImportIndex) {
34 | return text2json(`${meterType}.const ${cost} call ${meteringImportIndex}`)
35 | }
36 | function remapOp (op, funcIndex) {
37 | if (op.name === 'call' && op.immediates >= funcIndex) {
38 | op.immediates = (++op.immediates).toString()
39 | }
40 | }
41 | function meterTheMeteringStatement () {
42 | const code = meteringStatement(0, 0)
43 | // sum the operations cost
44 | return code.reduce(
45 | (sum, op) => sum + getCost(op.name, costTable.code)
46 | , 0)
47 | }
48 |
49 | // operations that can possible cause a branch
50 | const branchingOps = new Set(['grow_memory', 'end', 'br', 'br_table', 'br_if', 'if', 'else', 'return', 'loop'])
51 | const meteringOverHead = meterTheMeteringStatement()
52 | let code = entry.code.slice()
53 | let meteredCode = []
54 |
55 | cost += getCost(entry.locals, costTable.local)
56 |
57 | while (code.length) {
58 | let i = 0
59 |
60 | // meters a segment of wasm code
61 | while (true) {
62 | const op = code[i++]
63 | remapOp(op, meterFuncIndex)
64 |
65 | cost += getCost(op.name, costTable.code)
66 | if (branchingOps.has(op.name)) {
67 | break
68 | }
69 | }
70 |
71 | // add the metering statement
72 | if (cost !== 0) {
73 | // add the cost of metering
74 | cost += meteringOverHead
75 | meteredCode = meteredCode
76 | .concat(meteringStatement(cost, meterFuncIndex))
77 | }
78 |
79 | // start a new segment
80 | meteredCode = meteredCode
81 | .concat(code.slice(0, i))
82 | code = code.slice(i)
83 | cost = 0
84 | }
85 |
86 | entry.code = meteredCode
87 | return entry
88 | }
89 |
90 | /**
91 | * Injects metering into a JSON output of [wasm2json](https://github.com/ewasm/wasm-json-toolkit#wasm2json)
92 | * @param {Object} json the json tobe metered
93 | * @param {Object} opts
94 | * @param {Object} [opts.costTable=defaultTable] the cost table to meter with. See these notes about the default.
95 | * @param {String} [opts.moduleStr='metering'] the import string for the metering function
96 | * @param {String} [opts.fieldStr='usegas'] the field string for the metering function
97 | * @param {String} [opts.meterType='i64'] the register type that is used to meter. Can be `i64`, `i32`, `f64`, `f32`
98 | * @return {Object} the metered json
99 | */
100 | exports.meterJSON = (json, opts) => {
101 | function findSection (module, sectionName) {
102 | return module.find(section => section.name === sectionName)
103 | }
104 |
105 | function createSection (module, name) {
106 | const newSectionId = SECTION_IDS[name]
107 | for (let index in module) {
108 | const section = module[index]
109 | const sectionId = SECTION_IDS[section.name]
110 | if (sectionId) {
111 | if (newSectionId < sectionId) {
112 | // inject a new section
113 | module.splice(index, 0, {
114 | name,
115 | entries: []
116 | })
117 | return
118 | }
119 | }
120 | }
121 | }
122 |
123 | let funcIndex = 0
124 | let functionModule, typeModule
125 |
126 | let {costTable, moduleStr, fieldStr, meterType} = opts
127 |
128 | // set defaults
129 | if (!costTable) costTable = defaultCostTable
130 | if (!moduleStr) moduleStr = 'metering'
131 | if (!fieldStr) fieldStr = 'usegas'
132 | if (!meterType) meterType = 'i32'
133 |
134 | // add nessicarry sections iff they don't exist
135 | if (!findSection(json, 'type')) createSection(json, 'type')
136 | if (!findSection(json, 'import')) createSection(json, 'import')
137 |
138 | const importJson = {
139 | 'moduleStr': moduleStr,
140 | 'fieldStr': fieldStr,
141 | 'kind': 'function'
142 | }
143 | const importType = {
144 | 'form': 'func',
145 | 'params': [meterType]
146 | }
147 |
148 | json = json.slice(0)
149 |
150 | for (let section of json) {
151 | section = Object.assign(section)
152 | switch (section.name) {
153 | case 'type':
154 | // mark the import index
155 | importJson.type = section.entries.push(importType) - 1
156 | // save for use for the code section
157 | typeModule = section
158 | break
159 | case 'function':
160 | // save for use for the code section
161 | functionModule = section
162 | break
163 | case 'import':
164 | for (const entry of section.entries) {
165 | if (entry.moduleStr === moduleStr && entry.fieldStr === fieldStr) {
166 | throw new Error('importing metering function is not allowed')
167 | }
168 | if (entry.kind === 'function') {
169 | funcIndex++
170 | }
171 | }
172 | // append the metering import
173 | section.entries.push(importJson)
174 | break
175 | case 'export':
176 | for (const entry of section.entries) {
177 | if (entry.kind === 'function' && entry.index >= funcIndex) {
178 | entry.index++
179 | }
180 | }
181 | break
182 | case 'element':
183 | for (const entry of section.entries) {
184 | // remap elements indices
185 | entry.elements = entry.elements.map(el => el >= funcIndex ? ++el : el)
186 | }
187 | break
188 | case 'start':
189 | // remap start index
190 | if (section.index >= funcIndex) section.index++
191 | break
192 | case 'code':
193 | for (const i in section.entries) {
194 | const entry = section.entries[i]
195 | const typeIndex = functionModule.entries[i]
196 | const type = typeModule.entries[typeIndex]
197 | const cost = getCost(type, costTable.type)
198 |
199 | meterCodeEntry(entry, costTable.code, funcIndex, meterType, cost)
200 | }
201 | break
202 | }
203 | }
204 |
205 | return json
206 | }
207 |
208 | /**
209 | * Injects metering into a webassembly binary
210 | * @param {Object} json the json tobe metered
211 | * @param {Object} opts
212 | * @param {Object} [opts.costTable=defaultTable] the cost table to meter with. See these notes about the default.
213 | * @param {String} [opts.moduleStr='metering'] the import string for the metering function
214 | * @param {String} [opts.fieldStr='usegas'] the field string for the metering function
215 | * @param {String} [opts.meterType='i64'] the register type that is used to meter. Can be `i64`, `i32`, `f64`, `f32`
216 | * @return {Buffer}
217 | */
218 | exports.meterWASM = (wasm, opts = {}) => {
219 | let json = toolkit.wasm2json(wasm)
220 | json = exports.meterJSON(json, opts)
221 | return toolkit.json2wasm(json)
222 | }
223 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wasm-metering",
3 | "version": "0.2.1",
4 | "description": "injects metering into webassembly binaries",
5 | "main": "index.js",
6 | "scripts": {
7 | "coveralls": "npm run coverage && nyc report --reporter=text-lcov | coveralls",
8 | "coverage": "nyc npm test",
9 | "lint": "standard",
10 | "test": "node --harmony ./test/index.js"
11 | },
12 | "bin": {
13 | "wasm-meter": "./bin/wasm-meter"
14 | },
15 | "author": "mjbecze ",
16 | "contributors": [
17 | "Alex Beregszaszi "
18 | ],
19 | "license": "MPL-2.0",
20 | "dependencies": {
21 | "leb128": "^0.0.4",
22 | "wasm-json-toolkit": "0.3.0"
23 | },
24 | "devDependencies": {
25 | "coveralls": "^3.0.0",
26 | "nyc": "^11.6.0",
27 | "standard": "^11.0.0",
28 | "tape": "^4.9.0"
29 | },
30 | "keywords": [
31 | "wasm",
32 | "metering",
33 | "webassembly"
34 | ],
35 | "repository": {
36 | "type": "git",
37 | "url": "https://github.com/ewasm/wasm-metering.git"
38 | },
39 | "bugs": {
40 | "url": "https://github.com/ewasm/wasm-metering/issues"
41 | },
42 | "homepage": "https://github.com/ewasm/wasm-metering",
43 | "standard": {
44 | "ignore": [
45 | "test/wabt"
46 | ],
47 | "globals": [
48 | "WebAssembly"
49 | ]
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/test/buildTests.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const cp = require('child_process')
3 | const path = require('path')
4 | const wasm2json = require('wasm-json-toolkit/wasm2json')
5 |
6 | function processFiles (path, out) {
7 | const binPath = `${__dirname}/wabt/out/wast2wasm`
8 | const files = fs.readdirSync(path)
9 |
10 | for (let file of files) {
11 | console.log(file)
12 | if (file.split('.')[1] === 'wast') {
13 | // compile to wasm
14 | const str = `${binPath} ${path}/${file} -o /tmp/temp.wasm`
15 | cp.execSync(str)
16 | const wasm = fs.readFileSync('/tmp/temp.wasm')
17 | // compile to json
18 | const json = wasm2json(wasm)
19 | fs.writeFileSync(`${out}/${file}.json`, JSON.stringify(json, null, 2))
20 | }
21 | }
22 | }
23 |
24 | processFiles(path.join(__dirname, './in/wast'), path.join(__dirname, './in/json'))
25 | processFiles(path.join(__dirname, './expected-out/wast'), path.join(__dirname, './expected-out/json'))
26 |
--------------------------------------------------------------------------------
/test/defaultCostTable.json:
--------------------------------------------------------------------------------
1 | {
2 | "start": 1,
3 | "type": {
4 | "params": {
5 | "DEFAULT": 1
6 | },
7 | "return_type": {
8 | "DEFAULT": 1
9 | }
10 | },
11 | "import": 1,
12 | "code": {
13 | "locals": {
14 | "DEFAULT": 1
15 | },
16 | "code": {
17 | "DEFAULT": 1
18 | }
19 | },
20 | "data": 1
21 | }
22 |
--------------------------------------------------------------------------------
/test/expected-out/initCosts.json:
--------------------------------------------------------------------------------
1 | {
2 | "basic+import.wast.json": 1,
3 | "basic.wast.json": 0,
4 | "element.wast.json": 2,
5 | "fac.wast.json": 0,
6 | "memory0.wast.json": 20,
7 | "memory1.wast.json": 30,
8 | "memory2.wast.json": 26,
9 | "mixedImports.wast.json": 2,
10 | "start.wast.json": 4,
11 | "zeroCostOps.wast.json": 0,
12 | "stuff.wast.json": 3
13 | }
14 |
--------------------------------------------------------------------------------
/test/expected-out/json/basic+import.wast.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "preramble",
4 | "magic": [
5 | 0,
6 | 97,
7 | 115,
8 | 109
9 | ],
10 | "version": [
11 | 13,
12 | 0,
13 | 0,
14 | 0
15 | ]
16 | },
17 | {
18 | "name": "type",
19 | "entries": [
20 | {
21 | "form": "func",
22 | "params": [
23 | "i32",
24 | "i32"
25 | ],
26 | "return_type": "i32"
27 | },
28 | {
29 | "form": "func",
30 | "params": [
31 | "i64"
32 | ]
33 | },
34 | {
35 | "form": "func",
36 | "params": [
37 | "i64"
38 | ]
39 | }
40 | ]
41 | },
42 | {
43 | "name": "import",
44 | "entries": [
45 | {
46 | "moduleStr": "metering",
47 | "fieldStr": "usegas",
48 | "kind": "function",
49 | "type": 1
50 | },
51 | {
52 | "moduleStr": "metering",
53 | "fieldStr": "usegas",
54 | "kind": "function",
55 | "type": 2
56 | }
57 | ]
58 | },
59 | {
60 | "name": "function",
61 | "entries": [
62 | 0
63 | ]
64 | },
65 | {
66 | "name": "export",
67 | "entries": [
68 | {
69 | "field_str": "addTwo",
70 | "kind": "function",
71 | "index": 2
72 | }
73 | ]
74 | },
75 | {
76 | "name": "code",
77 | "entries": [
78 | {
79 | "locals": [],
80 | "code": [
81 | {
82 | "return_type": "i64",
83 | "name": "const",
84 | "immediates": "9"
85 | },
86 | {
87 | "name": "call",
88 | "immediates": "1"
89 | },
90 | {
91 | "name": "get_local",
92 | "immediates": "0"
93 | },
94 | {
95 | "name": "get_local",
96 | "immediates": "1"
97 | },
98 | {
99 | "return_type": "i32",
100 | "name": "add"
101 | },
102 | {
103 | "name": "end"
104 | }
105 | ]
106 | }
107 | ]
108 | }
109 | ]
--------------------------------------------------------------------------------
/test/expected-out/json/basic.wast.json:
--------------------------------------------------------------------------------
1 | [{"name":"preramble","magic":[0,97,115,109],"version":[13,0,0,0]},{"name":"type","entries":[{"form":"func","params":["i32","i32"],"return_type":"i32"},{"form":"func","params":["i32"]}]},{"name":"import","entries":[{"moduleStr":"metering","fieldStr":"usegas","kind":"function","type":1}]},{"name":"function","entries":[0]},{"name":"export","entries":[{"field_str":"addTwo","kind":"function","index":1}]},{"name":"code","entries":[{"locals":[],"code":[{"return_type":"i32","name":"const","immediates":"9"},{"name":"call","immediates":"0"},{"name":"get_local","immediates":"0"},{"name":"get_local","immediates":"1"},{"return_type":"i32","name":"add"},{"name":"end"}]}]}]
--------------------------------------------------------------------------------
/test/expected-out/json/element.wast.json:
--------------------------------------------------------------------------------
1 | [{"name":"preramble","magic":[0,97,115,109],"version":[13,0,0,0]},{"name":"type","entries":[{"form":"func","params":[]},{"form":"func","params":[],"return_type":"i32"},{"form":"func","params":["i32"],"return_type":"i32"},{"form":"func","params":["i32"]}]},{"name":"import","entries":[{"moduleStr":"Mt","fieldStr":"call","kind":"function","type":2},{"moduleStr":"Mt","fieldStr":"h","kind":"function","type":1},{"moduleStr":"metering","fieldStr":"usegas","kind":"function","type":3}]},{"name":"function","entries":[1,2,2]},{"name":"table","entries":[{"elementType":"anyFunc","limits":{"flags":1,"intial":5,"maximum":5}}]},{"name":"export","entries":[{"field_str":"Mt.call","kind":"function","index":0},{"field_str":"call Mt.call","kind":"function","index":4},{"field_str":"call","kind":"function","index":5}]},{"name":"element","entries":[{"elements":[3,3,3,1,0],"index":0,"offset":{"return_type":"i32","name":"const","immediates":"0"}}]},{"name":"code","entries":[{"locals":[],"code":[{"return_type":"i32","name":"const","immediates":"5"},{"name":"call","immediates":"2"},{"return_type":"i32","name":"const","immediates":"5"},{"name":"end"}]},{"locals":[],"code":[{"return_type":"i32","name":"const","immediates":"7"},{"name":"call","immediates":"2"},{"name":"get_local","immediates":"0"},{"name":"call","immediates":"0"},{"name":"end"}]},{"locals":[],"code":[{"return_type":"i32","name":"const","immediates":"7"},{"name":"call","immediates":"2"},{"name":"get_local","immediates":"0"},{"name":"call_indirect","immediates":{"index":1,"reserved":0}},{"name":"end"}]}]}]
--------------------------------------------------------------------------------
/test/expected-out/json/fac.wast.json:
--------------------------------------------------------------------------------
1 | [{"name":"preramble","magic":[0,97,115,109],"version":[13,0,0,0]},{"name":"type","entries":[{"form":"func","params":["i64"],"return_type":"i64"},{"form":"func","params":["i32"]}]},{"name":"import","entries":[{"moduleStr":"metering","fieldStr":"usegas","kind":"function","type":1}]},{"name":"function","entries":[0]},{"name":"export","entries":[{"field_str":"fac","kind":"function","index":1}]},{"name":"code","entries":[{"locals":[],"code":[{"return_type":"i32","name":"const","immediates":"8"},{"name":"call","immediates":"0"},{"name":"get_local","immediates":"0"},{"return_type":"i64","name":"const","immediates":"1"},{"return_type":"i64","name":"lt_s"},{"name":"if","immediates":"i64"},{"return_type":"i32","name":"const","immediates":"4"},{"name":"call","immediates":"0"},{"return_type":"i64","name":"const","immediates":"1"},{"name":"else"},{"return_type":"i32","name":"const","immediates":"9"},{"name":"call","immediates":"0"},{"name":"get_local","immediates":"0"},{"name":"get_local","immediates":"0"},{"return_type":"i64","name":"const","immediates":"1"},{"return_type":"i64","name":"sub"},{"name":"call","immediates":"1"},{"return_type":"i64","name":"mul"},{"name":"end"},{"return_type":"i32","name":"const","immediates":"3"},{"name":"call","immediates":"0"},{"name":"end"}]}]}]
--------------------------------------------------------------------------------
/test/expected-out/json/memory0.wast.json:
--------------------------------------------------------------------------------
1 | [{"name":"preramble","magic":[0,97,115,109],"version":[13,0,0,0]},{"name":"type","entries":[{"form":"func","params":["i32"]}]},{"name":"import","entries":[{"moduleStr":"metering","fieldStr":"usegas","kind":"function","type":0}]},{"name":"memory","entries":[{"flags":1,"intial":1,"maximum":2}]},{"name":"data","entries":[{"index":0,"offset":{"return_type":"i32","name":"const","immediates":"0"},"data":[97]},{"index":0,"offset":{"return_type":"i32","name":"const","immediates":"65535"},"data":[98]}]}]
--------------------------------------------------------------------------------
/test/expected-out/json/memory1.wast.json:
--------------------------------------------------------------------------------
1 | [{"name":"preramble","magic":[0,97,115,109],"version":[13,0,0,0]},{"name":"type","entries":[{"form":"func","params":["i32"]}]},{"name":"import","entries":[{"moduleStr":"metering","fieldStr":"usegas","kind":"function","type":0}]},{"name":"memory","entries":[{"flags":1,"intial":1,"maximum":2}]},{"name":"data","entries":[{"index":0,"offset":{"return_type":"i32","name":"const","immediates":"0"},"data":[97]},{"index":0,"offset":{"return_type":"i32","name":"const","immediates":"65535"},"data":[98]}]}]
--------------------------------------------------------------------------------
/test/expected-out/json/memory2.wast.json:
--------------------------------------------------------------------------------
1 | [{"name":"preramble","magic":[0,97,115,109],"version":[13,0,0,0]},{"name":"type","entries":[{"form":"func","params":["i32"]}]},{"name":"import","entries":[{"moduleStr":"metering","fieldStr":"usegas","kind":"function","type":0}]},{"name":"memory","entries":[{"flags":1,"intial":1,"maximum":2}]},{"name":"data","entries":[{"index":0,"offset":{"return_type":"i32","name":"const","immediates":"0"},"data":[97]},{"index":0,"offset":{"return_type":"i32","name":"const","immediates":"65535"},"data":[98]}]}]
--------------------------------------------------------------------------------
/test/expected-out/json/mixedImports.wast.json:
--------------------------------------------------------------------------------
1 | [{"name":"preramble","magic":[0,97,115,109],"version":[13,0,0,0]},{"name":"type","entries":[{"form":"func","params":["i32","i32"],"return_type":"i32"},{"form":"func","params":["i64"]},{"form":"func","params":["i32"]}]},{"name":"import","entries":[{"moduleStr":"teat","fieldStr":"adf","kind":"global","type":{"contentType":"i64","mutability":0}},{"moduleStr":"metering","fieldStr":"usegas","kind":"function","type":2}]},{"name":"function","entries":[0]},{"name":"export","entries":[{"field_str":"addTwo","kind":"function","index":1}]},{"name":"code","entries":[{"locals":[],"code":[{"return_type":"i32","name":"const","immediates":"9"},{"name":"call","immediates":"0"},{"name":"get_local","immediates":"0"},{"name":"get_local","immediates":"1"},{"return_type":"i32","name":"add"},{"name":"end"}]}]}]
--------------------------------------------------------------------------------
/test/expected-out/json/start.wast.json:
--------------------------------------------------------------------------------
1 | [{"name":"preramble","magic":[0,97,115,109],"version":[13,0,0,0]},{"name":"type","entries":[{"form":"func","params":[]},{"form":"func","params":["f32"]},{"form":"func","params":["i32"],"return_type":"i32"},{"form":"func","params":["i32"]}]},{"name":"import","entries":[{"moduleStr":"foo","fieldStr":"bar","kind":"function","type":0},{"moduleStr":"foo","fieldStr":"bar","kind":"function","type":1},{"moduleStr":"metering","fieldStr":"usegas","kind":"function","type":3}]},{"name":"function","entries":[0,1]},{"name":"table","entries":[{"elementType":"anyFunc","limits":{"flags":1,"intial":0,"maximum":1}}]},{"name":"memory","entries":[{"flags":1,"intial":1,"maximum":1}]},{"name":"export","entries":[{"field_str":"e","kind":"function","index":1}]},{"name":"start","index":0},{"name":"code","entries":[{"locals":[],"code":[{"return_type":"i32","name":"const","immediates":"3"},{"name":"call","immediates":"2"},{"name":"end"}]},{"locals":[],"code":[{"return_type":"i32","name":"const","immediates":"6"},{"name":"call","immediates":"2"},{"return_type":"i32","name":"const","immediates":"42"},{"name":"drop"},{"name":"end"}]}]},{"name":"data","entries":[{"index":0,"offset":{"return_type":"i32","name":"const","immediates":"0"},"data":[104,105]}]}]
--------------------------------------------------------------------------------
/test/expected-out/json/stuff.wast.json:
--------------------------------------------------------------------------------
1 | [{"name":"preramble","magic":[0,97,115,109],"version":[13,0,0,0]},{"name":"type","entries":[{"form":"func","params":["f32"]},{"form":"func","params":["i32"],"return_type":"i32"},{"form":"func","params":[]},{"form":"func","params":["i32"]}]},{"name":"import","entries":[{"moduleStr":"foo","fieldStr":"bar","kind":"function","type":0},{"moduleStr":"metering","fieldStr":"usegas","kind":"function","type":3}]},{"name":"function","entries":[2,0]},{"name":"table","entries":[{"elementType":"anyFunc","limits":{"flags":1,"intial":0,"maximum":1}}]},{"name":"memory","entries":[{"flags":1,"intial":1,"maximum":1}]},{"name":"export","entries":[{"field_str":"e","kind":"function","index":2}]},{"name":"start","index":2},{"name":"code","entries":[{"locals":[],"code":[{"return_type":"i32","name":"const","immediates":"3"},{"name":"call","immediates":"1"},{"name":"end"}]},{"locals":[],"code":[{"return_type":"i32","name":"const","immediates":"6"},{"name":"call","immediates":"1"},{"return_type":"i32","name":"const","immediates":"42"},{"name":"drop"},{"name":"end"}]}]},{"name":"data","entries":[{"index":0,"offset":{"return_type":"i32","name":"const","immediates":"0"},"data":[104,105]}]}]
--------------------------------------------------------------------------------
/test/expected-out/json/zeroCostOps.wast.json:
--------------------------------------------------------------------------------
1 | [{"name":"preramble","magic":[0,97,115,109],"version":[13,0,0,0]},{"name":"type","entries":[{"form":"func","params":["i64"],"return_type":"i64"},{"form":"func","params":["i32"]}]},{"name":"import","entries":[{"moduleStr":"metering","fieldStr":"usegas","kind":"function","type":1}]},{"name":"function","entries":[0]},{"name":"export","entries":[{"field_str":"fac","kind":"function","index":1}]},{"name":"code","entries":[{"locals":[],"code":[{"return_type":"i32","name":"const","immediates":"8"},{"name":"call","immediates":"0"},{"name":"get_local","immediates":"0"},{"return_type":"i64","name":"const","immediates":"1"},{"return_type":"i64","name":"lt_s"},{"name":"if","immediates":"i64"},{"return_type":"i32","name":"const","immediates":"4"},{"name":"call","immediates":"0"},{"return_type":"i64","name":"const","immediates":"1"},{"name":"else"},{"return_type":"i32","name":"const","immediates":"8"},{"name":"call","immediates":"0"},{"name":"get_local","immediates":"0"},{"name":"get_local","immediates":"0"},{"return_type":"i64","name":"const","immediates":"1"},{"return_type":"i64","name":"sub"},{"name":"call","immediates":"1"},{"return_type":"i64","name":"mul"},{"name":"end"},{"name":"end"}]}]}]
--------------------------------------------------------------------------------
/test/expected-out/wast/basic+import.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (type $a (func(param i32 i32) (result i32)))
3 | (type $b (func(param i64)))
4 | (type $c (func(param i64)))
5 |
6 | (import "metering" "usegas" (func (type $b)))
7 | (import "metering" "usegas" (func $useGas (type $c)))
8 | (func $addTwo (type $a)
9 | (call $useGas (i64.const 9))
10 | (i32.add
11 | (get_local 0)
12 | (get_local 1)))
13 | (export "addTwo" (func $addTwo)))
14 |
--------------------------------------------------------------------------------
/test/expected-out/wast/basic.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (type $a (func(param i32 i32) (result i32)))
3 | (type $b (func(param i64)))
4 |
5 | (import "metering" "usegas" (func $useGas (type $b)))
6 | (func $addTwo (type $a)
7 | (call $useGas (i64.const 9))
8 | (i32.add
9 | (get_local 0)
10 | (get_local 1)))
11 | (export "addTwo" (func $addTwo)))
12 |
--------------------------------------------------------------------------------
/test/expected-out/wast/element.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (type (func))
3 | (type (func (result i32)))
4 | (type $a (func (param i32) (result i32)))
5 | (type $b (func(param i64)))
6 |
7 | (func $f (import "Mt" "call") (type $a))
8 | (func $h (import "Mt" "h") (result i32))
9 | (import "metering" "usegas" (func $usegas (type $b)))
10 |
11 | (table anyfunc (elem $g $g $g $h $f))
12 | (func $g (result i32)
13 | (call $usegas (i64.const 5))
14 | (i32.const 5))
15 |
16 | (export "Mt.call" (func $f))
17 | (func (export "call Mt.call") (param i32) (result i32)
18 | (call $usegas (i64.const 7))
19 | (call $f (get_local 0))
20 | )
21 | (func (export "call") (param i32) (result i32)
22 | (call $usegas (i64.const 7))
23 | (call_indirect 1 (get_local 0))
24 | )
25 | )
26 |
--------------------------------------------------------------------------------
/test/expected-out/wast/fac.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (type $a (func(param i64) (result i64)))
3 | (type $b (func(param i64)))
4 |
5 | (import "metering" "usegas" (func $useGas (type $b)))
6 |
7 | (func $fac (type $a)
8 | (call $useGas (i64.const 8))
9 | (if i64
10 | (i64.lt_s (get_local 0) (i64.const 1))
11 | (then
12 | (call $useGas (i64.const 4))
13 | (i64.const 1))
14 | (else
15 | (call $useGas (i64.const 9))
16 | (i64.mul
17 | (get_local 0)
18 | (call $fac
19 | (i64.sub
20 | (get_local 0)
21 | (i64.const 1))))))
22 | (call $useGas (i64.const 3))
23 | )
24 | (export "fac" (func $fac)))
25 |
--------------------------------------------------------------------------------
/test/expected-out/wast/memory0.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (type $a (func(param i64)))
3 | (import "metering" "usegas" (func $useGas (type $a)))
4 | (memory 1 2)
5 | (data (i32.const 0) "a")
6 | (data (i32.const 65535) "b"))
7 |
--------------------------------------------------------------------------------
/test/expected-out/wast/memory1.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (type $a (func(param i64)))
3 | (import "metering" "usegas" (func $useGas (type $a)))
4 | (memory 1 2)
5 | (data (i32.const 0) "a")
6 | (data (i32.const 65535) "b"))
7 |
--------------------------------------------------------------------------------
/test/expected-out/wast/memory2.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (type $a (func(param i64)))
3 | (import "metering" "usegas" (func $useGas (type $a)))
4 | (memory 1 2)
5 | (data (i32.const 0) "a")
6 | (data (i32.const 65535) "b"))
7 |
--------------------------------------------------------------------------------
/test/expected-out/wast/mixedImports.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (type $a (func(param i32 i32) (result i32)))
3 | (type $b (func(param i64)))
4 | (type $c (func(param i64)))
5 |
6 | (import "metering" "usegas" (func (type $b)))
7 | (import "teat" "adf" (global i64))
8 | (import "metering" "usegas" (func $useGas (type $c)))
9 | (func $addTwo (type $a)
10 | (call $useGas (i64.const 9))
11 | (i32.add
12 | (get_local 0)
13 | (get_local 1)))
14 | (export "addTwo" (func $addTwo)))
15 |
--------------------------------------------------------------------------------
/test/expected-out/wast/start.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (type $c (func))
3 | (type $a (func (param f32)))
4 | (type $b (func (param i32) (result i32)))
5 | (type $d (func (param i64)))
6 |
7 | (import "foo" "bar" (func))
8 | (import "foo" "bar" (func (type $a)))
9 | (import "metering" "usegas" (func $usegas (type $d)))
10 | (memory (data "hi"))
11 | (start 0)
12 | (table 0 1 anyfunc)
13 | (func (type $c)
14 | (call $usegas (i64.const 3))
15 | )
16 | (func (type $a)
17 | (call $usegas (i64.const 6))
18 | (drop (i32.const 42)))
19 | (export "e" (func 1)))
20 |
21 |
22 |
--------------------------------------------------------------------------------
/test/expected-out/wast/stuff.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (type $a (func (param f32)))
3 | (type $b (func (param i32) (result i32)))
4 | (type $c (func))
5 | (type $d (func (param i64)))
6 |
7 | (import "foo" "bar" (func (type $a)))
8 | (import "metering" "usegas" (func $usegas (type $d)))
9 | (memory (data "hi"))
10 | (start 2)
11 | (table 0 1 anyfunc)
12 | (func (type $c)
13 | (call $usegas (i64.const 3))
14 | )
15 | (func (type 0)
16 | (call $usegas (i64.const 6))
17 | (drop (i32.const 42)))
18 | (export "e" (func 2)))
19 |
20 |
21 |
--------------------------------------------------------------------------------
/test/expected-out/wast/zeroCostOps.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (type $a (func(param i64) (result i64)))
3 | (type $b (func(param i64)))
4 |
5 | (import "metering" "usegas" (func $useGas (type $b)))
6 |
7 | (func $fac (type $a)
8 | (call $useGas (i64.const 8))
9 | (if i64
10 | (i64.lt_s (get_local 0) (i64.const 1))
11 | (then
12 | (call $useGas (i64.const 4))
13 | (i64.const 1))
14 | (else
15 | (call $useGas (i64.const 8))
16 | (i64.mul
17 | (get_local 0)
18 | (call $fac
19 | (i64.sub
20 | (get_local 0)
21 | (i64.const 1))))))
22 | )
23 | (export "fac" (func $fac)))
24 |
--------------------------------------------------------------------------------
/test/in/costTables/memory0.wast.json.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'start': 1,
3 | 'type': {
4 | 'params': {
5 | 'DEFAULT': 1
6 | },
7 | 'return_type': {
8 | 'DEFAULT': 1
9 | }
10 | },
11 | 'import': 1,
12 | 'code': {
13 | 'locals': {
14 | 'DEFAULT': 1
15 | },
16 | 'code': {
17 | 'DEFAULT': 1
18 | }
19 | },
20 | 'memory': (entry) => {
21 | return entry.maximum * 10
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/test/in/costTables/memory1.wast.json.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'start': 1,
3 | 'type': {
4 | 'params': {
5 | 'DEFAULT': 1
6 | },
7 | 'return_type': {
8 | 'DEFAULT': 1
9 | }
10 | },
11 | 'import': 1,
12 | 'code': {
13 | 'locals': {
14 | 'DEFAULT': 1
15 | },
16 | 'code': {
17 | 'DEFAULT': 1
18 | }
19 | },
20 | 'memory': (entry) => {
21 | return entry.maximum * 10
22 | },
23 | 'data': 5
24 | }
25 |
--------------------------------------------------------------------------------
/test/in/costTables/memory2.wast.json.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'start': 1,
3 | 'type': {
4 | 'params': {
5 | 'DEFAULT': 1
6 | },
7 | 'return_type': {
8 | 'DEFAULT': 1
9 | }
10 | },
11 | 'import': 1,
12 | 'code': {
13 | 'locals': {
14 | 'DEFAULT': 1
15 | },
16 | 'code': {
17 | 'DEFAULT': 1
18 | }
19 | },
20 | 'memory': (entry) => {
21 | return entry.maximum * 10
22 | },
23 | 'data': {
24 | 'offset': {
25 | 'return_type': {
26 | 'i32': 3
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/test/in/costTables/zeroCostOps.wast.json.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'start': 1,
3 | 'type': {
4 | 'params': {
5 | 'DEFAULT': 1
6 | },
7 | 'return_type': {
8 | 'DEFAULT': 1
9 | }
10 | },
11 | 'import': 1,
12 | 'code': {
13 | 'locals': {
14 | 'DEFAULT': 1
15 | },
16 | 'code': {
17 | 'DEFAULT': 1,
18 | 'end': 0
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/test/in/json/basic+import.wast.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "preramble",
4 | "magic": [
5 | 0,
6 | 97,
7 | 115,
8 | 109
9 | ],
10 | "version": [
11 | 13,
12 | 0,
13 | 0,
14 | 0
15 | ]
16 | },
17 | {
18 | "name": "type",
19 | "entries": [
20 | {
21 | "form": "func",
22 | "params": [
23 | "i32",
24 | "i32"
25 | ],
26 | "return_type": "i32"
27 | },
28 | {
29 | "form": "func",
30 | "params": [
31 | "i64"
32 | ]
33 | }
34 | ]
35 | },
36 | {
37 | "name": "import",
38 | "entries": [
39 | {
40 | "moduleStr": "metering",
41 | "fieldStr": "usegas",
42 | "kind": "function",
43 | "type": 1
44 | }
45 | ]
46 | },
47 | {
48 | "name": "function",
49 | "entries": [
50 | 0
51 | ]
52 | },
53 | {
54 | "name": "export",
55 | "entries": [
56 | {
57 | "field_str": "addTwo",
58 | "kind": "function",
59 | "index": 1
60 | }
61 | ]
62 | },
63 | {
64 | "name": "code",
65 | "entries": [
66 | {
67 | "locals": [],
68 | "code": [
69 | {
70 | "name": "get_local",
71 | "immediates": "0"
72 | },
73 | {
74 | "name": "get_local",
75 | "immediates": "1"
76 | },
77 | {
78 | "return_type": "i32",
79 | "name": "add"
80 | },
81 | {
82 | "name": "end"
83 | }
84 | ]
85 | }
86 | ]
87 | }
88 | ]
--------------------------------------------------------------------------------
/test/in/json/basic.wast.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "preramble",
4 | "magic": [
5 | 0,
6 | 97,
7 | 115,
8 | 109
9 | ],
10 | "version": [
11 | 13,
12 | 0,
13 | 0,
14 | 0
15 | ]
16 | },
17 | {
18 | "name": "type",
19 | "entries": [
20 | {
21 | "form": "func",
22 | "params": [
23 | "i32",
24 | "i32"
25 | ],
26 | "return_type": "i32"
27 | }
28 | ]
29 | },
30 | {
31 | "name": "function",
32 | "entries": [
33 | 0
34 | ]
35 | },
36 | {
37 | "name": "export",
38 | "entries": [
39 | {
40 | "field_str": "addTwo",
41 | "kind": "function",
42 | "index": 0
43 | }
44 | ]
45 | },
46 | {
47 | "name": "code",
48 | "entries": [
49 | {
50 | "locals": [],
51 | "code": [
52 | {
53 | "name": "get_local",
54 | "immediates": "0"
55 | },
56 | {
57 | "name": "get_local",
58 | "immediates": "1"
59 | },
60 | {
61 | "return_type": "i32",
62 | "name": "add"
63 | },
64 | {
65 | "name": "end"
66 | }
67 | ]
68 | }
69 | ]
70 | }
71 | ]
--------------------------------------------------------------------------------
/test/in/json/element.wast.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "preramble",
4 | "magic": [
5 | 0,
6 | 97,
7 | 115,
8 | 109
9 | ],
10 | "version": [
11 | 13,
12 | 0,
13 | 0,
14 | 0
15 | ]
16 | },
17 | {
18 | "name": "type",
19 | "entries": [
20 | {
21 | "form": "func",
22 | "params": []
23 | },
24 | {
25 | "form": "func",
26 | "params": [],
27 | "return_type": "i32"
28 | },
29 | {
30 | "form": "func",
31 | "params": [
32 | "i32"
33 | ],
34 | "return_type": "i32"
35 | }
36 | ]
37 | },
38 | {
39 | "name": "import",
40 | "entries": [
41 | {
42 | "moduleStr": "Mt",
43 | "fieldStr": "call",
44 | "kind": "function",
45 | "type": 2
46 | },
47 | {
48 | "moduleStr": "Mt",
49 | "fieldStr": "h",
50 | "kind": "function",
51 | "type": 1
52 | }
53 | ]
54 | },
55 | {
56 | "name": "function",
57 | "entries": [
58 | 1,
59 | 2,
60 | 2
61 | ]
62 | },
63 | {
64 | "name": "table",
65 | "entries": [
66 | {
67 | "elementType": "anyFunc",
68 | "limits": {
69 | "flags": 1,
70 | "intial": 5,
71 | "maximum": 5
72 | }
73 | }
74 | ]
75 | },
76 | {
77 | "name": "export",
78 | "entries": [
79 | {
80 | "field_str": "Mt.call",
81 | "kind": "function",
82 | "index": 0
83 | },
84 | {
85 | "field_str": "call Mt.call",
86 | "kind": "function",
87 | "index": 3
88 | },
89 | {
90 | "field_str": "call",
91 | "kind": "function",
92 | "index": 4
93 | }
94 | ]
95 | },
96 | {
97 | "name": "element",
98 | "entries": [
99 | {
100 | "elements": [
101 | 2,
102 | 2,
103 | 2,
104 | 1,
105 | 0
106 | ],
107 | "index": 0,
108 | "offset": {
109 | "return_type": "i32",
110 | "name": "const",
111 | "immediates": "0"
112 | }
113 | }
114 | ]
115 | },
116 | {
117 | "name": "code",
118 | "entries": [
119 | {
120 | "locals": [],
121 | "code": [
122 | {
123 | "return_type": "i32",
124 | "name": "const",
125 | "immediates": "5"
126 | },
127 | {
128 | "name": "end"
129 | }
130 | ]
131 | },
132 | {
133 | "locals": [],
134 | "code": [
135 | {
136 | "name": "get_local",
137 | "immediates": "0"
138 | },
139 | {
140 | "name": "call",
141 | "immediates": "0"
142 | },
143 | {
144 | "name": "end"
145 | }
146 | ]
147 | },
148 | {
149 | "locals": [],
150 | "code": [
151 | {
152 | "name": "get_local",
153 | "immediates": "0"
154 | },
155 | {
156 | "name": "call_indirect",
157 | "immediates": {
158 | "index": 1,
159 | "reserved": 0
160 | }
161 | },
162 | {
163 | "name": "end"
164 | }
165 | ]
166 | }
167 | ]
168 | }
169 | ]
--------------------------------------------------------------------------------
/test/in/json/fac.wast.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "preramble",
4 | "magic": [
5 | 0,
6 | 97,
7 | 115,
8 | 109
9 | ],
10 | "version": [
11 | 13,
12 | 0,
13 | 0,
14 | 0
15 | ]
16 | },
17 | {
18 | "name": "type",
19 | "entries": [
20 | {
21 | "form": "func",
22 | "params": [
23 | "i64"
24 | ],
25 | "return_type": "i64"
26 | }
27 | ]
28 | },
29 | {
30 | "name": "function",
31 | "entries": [
32 | 0
33 | ]
34 | },
35 | {
36 | "name": "export",
37 | "entries": [
38 | {
39 | "field_str": "fac",
40 | "kind": "function",
41 | "index": 0
42 | }
43 | ]
44 | },
45 | {
46 | "name": "code",
47 | "entries": [
48 | {
49 | "locals": [],
50 | "code": [
51 | {
52 | "name": "get_local",
53 | "immediates": "0"
54 | },
55 | {
56 | "return_type": "i64",
57 | "name": "const",
58 | "immediates": "1"
59 | },
60 | {
61 | "return_type": "i64",
62 | "name": "lt_s"
63 | },
64 | {
65 | "name": "if",
66 | "immediates": "i64"
67 | },
68 | {
69 | "return_type": "i64",
70 | "name": "const",
71 | "immediates": "1"
72 | },
73 | {
74 | "name": "else"
75 | },
76 | {
77 | "name": "get_local",
78 | "immediates": "0"
79 | },
80 | {
81 | "name": "get_local",
82 | "immediates": "0"
83 | },
84 | {
85 | "return_type": "i64",
86 | "name": "const",
87 | "immediates": "1"
88 | },
89 | {
90 | "return_type": "i64",
91 | "name": "sub"
92 | },
93 | {
94 | "name": "call",
95 | "immediates": "0"
96 | },
97 | {
98 | "return_type": "i64",
99 | "name": "mul"
100 | },
101 | {
102 | "name": "end"
103 | },
104 | {
105 | "name": "end"
106 | }
107 | ]
108 | }
109 | ]
110 | }
111 | ]
--------------------------------------------------------------------------------
/test/in/json/memory0.wast.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "preramble",
4 | "magic": [
5 | 0,
6 | 97,
7 | 115,
8 | 109
9 | ],
10 | "version": [
11 | 13,
12 | 0,
13 | 0,
14 | 0
15 | ]
16 | },
17 | {
18 | "name": "memory",
19 | "entries": [
20 | {
21 | "flags": 1,
22 | "intial": 1,
23 | "maximum": 2
24 | }
25 | ]
26 | },
27 | {
28 | "name": "data",
29 | "entries": [
30 | {
31 | "index": 0,
32 | "offset": {
33 | "return_type": "i32",
34 | "name": "const",
35 | "immediates": "0"
36 | },
37 | "data": [
38 | 97
39 | ]
40 | },
41 | {
42 | "index": 0,
43 | "offset": {
44 | "return_type": "i32",
45 | "name": "const",
46 | "immediates": "65535"
47 | },
48 | "data": [
49 | 98
50 | ]
51 | }
52 | ]
53 | }
54 | ]
--------------------------------------------------------------------------------
/test/in/json/memory1.wast.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "preramble",
4 | "magic": [
5 | 0,
6 | 97,
7 | 115,
8 | 109
9 | ],
10 | "version": [
11 | 13,
12 | 0,
13 | 0,
14 | 0
15 | ]
16 | },
17 | {
18 | "name": "memory",
19 | "entries": [
20 | {
21 | "flags": 1,
22 | "intial": 1,
23 | "maximum": 2
24 | }
25 | ]
26 | },
27 | {
28 | "name": "data",
29 | "entries": [
30 | {
31 | "index": 0,
32 | "offset": {
33 | "return_type": "i32",
34 | "name": "const",
35 | "immediates": "0"
36 | },
37 | "data": [
38 | 97
39 | ]
40 | },
41 | {
42 | "index": 0,
43 | "offset": {
44 | "return_type": "i32",
45 | "name": "const",
46 | "immediates": "65535"
47 | },
48 | "data": [
49 | 98
50 | ]
51 | }
52 | ]
53 | }
54 | ]
--------------------------------------------------------------------------------
/test/in/json/memory2.wast.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "preramble",
4 | "magic": [
5 | 0,
6 | 97,
7 | 115,
8 | 109
9 | ],
10 | "version": [
11 | 13,
12 | 0,
13 | 0,
14 | 0
15 | ]
16 | },
17 | {
18 | "name": "memory",
19 | "entries": [
20 | {
21 | "flags": 1,
22 | "intial": 1,
23 | "maximum": 2
24 | }
25 | ]
26 | },
27 | {
28 | "name": "data",
29 | "entries": [
30 | {
31 | "index": 0,
32 | "offset": {
33 | "return_type": "i32",
34 | "name": "const",
35 | "immediates": "0"
36 | },
37 | "data": [
38 | 97
39 | ]
40 | },
41 | {
42 | "index": 0,
43 | "offset": {
44 | "return_type": "i32",
45 | "name": "const",
46 | "immediates": "65535"
47 | },
48 | "data": [
49 | 98
50 | ]
51 | }
52 | ]
53 | }
54 | ]
--------------------------------------------------------------------------------
/test/in/json/mixedImports.wast.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "preramble",
4 | "magic": [
5 | 0,
6 | 97,
7 | 115,
8 | 109
9 | ],
10 | "version": [
11 | 13,
12 | 0,
13 | 0,
14 | 0
15 | ]
16 | },
17 | {
18 | "name": "type",
19 | "entries": [
20 | {
21 | "form": "func",
22 | "params": [
23 | "i32",
24 | "i32"
25 | ],
26 | "return_type": "i32"
27 | },
28 | {
29 | "form": "func",
30 | "params": [
31 | "i64"
32 | ]
33 | }
34 | ]
35 | },
36 | {
37 | "name": "import",
38 | "entries": [
39 | {
40 | "moduleStr": "teat",
41 | "fieldStr": "adf",
42 | "kind": "global",
43 | "type": {
44 | "contentType": "i64",
45 | "mutability": 0
46 | }
47 | }
48 | ]
49 | },
50 | {
51 | "name": "function",
52 | "entries": [
53 | 0
54 | ]
55 | },
56 | {
57 | "name": "export",
58 | "entries": [
59 | {
60 | "field_str": "addTwo",
61 | "kind": "function",
62 | "index": 0
63 | }
64 | ]
65 | },
66 | {
67 | "name": "code",
68 | "entries": [
69 | {
70 | "locals": [],
71 | "code": [
72 | {
73 | "name": "get_local",
74 | "immediates": "0"
75 | },
76 | {
77 | "name": "get_local",
78 | "immediates": "1"
79 | },
80 | {
81 | "return_type": "i32",
82 | "name": "add"
83 | },
84 | {
85 | "name": "end"
86 | }
87 | ]
88 | }
89 | ]
90 | }
91 | ]
--------------------------------------------------------------------------------
/test/in/json/start.wast.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "preramble",
4 | "magic": [
5 | 0,
6 | 97,
7 | 115,
8 | 109
9 | ],
10 | "version": [
11 | 13,
12 | 0,
13 | 0,
14 | 0
15 | ]
16 | },
17 | {
18 | "name": "type",
19 | "entries": [
20 | {
21 | "form": "func",
22 | "params": []
23 | },
24 | {
25 | "form": "func",
26 | "params": [
27 | "f32"
28 | ]
29 | },
30 | {
31 | "form": "func",
32 | "params": [
33 | "i32"
34 | ],
35 | "return_type": "i32"
36 | }
37 | ]
38 | },
39 | {
40 | "name": "import",
41 | "entries": [
42 | {
43 | "moduleStr": "foo",
44 | "fieldStr": "bar",
45 | "kind": "function",
46 | "type": 0
47 | },
48 | {
49 | "moduleStr": "foo",
50 | "fieldStr": "bar",
51 | "kind": "function",
52 | "type": 1
53 | }
54 | ]
55 | },
56 | {
57 | "name": "function",
58 | "entries": [
59 | 0,
60 | 1
61 | ]
62 | },
63 | {
64 | "name": "table",
65 | "entries": [
66 | {
67 | "elementType": "anyFunc",
68 | "limits": {
69 | "flags": 1,
70 | "intial": 0,
71 | "maximum": 1
72 | }
73 | }
74 | ]
75 | },
76 | {
77 | "name": "memory",
78 | "entries": [
79 | {
80 | "flags": 1,
81 | "intial": 1,
82 | "maximum": 1
83 | }
84 | ]
85 | },
86 | {
87 | "name": "export",
88 | "entries": [
89 | {
90 | "field_str": "e",
91 | "kind": "function",
92 | "index": 1
93 | }
94 | ]
95 | },
96 | {
97 | "name": "start",
98 | "index": 0
99 | },
100 | {
101 | "name": "code",
102 | "entries": [
103 | {
104 | "locals": [],
105 | "code": [
106 | {
107 | "name": "end"
108 | }
109 | ]
110 | },
111 | {
112 | "locals": [],
113 | "code": [
114 | {
115 | "return_type": "i32",
116 | "name": "const",
117 | "immediates": "42"
118 | },
119 | {
120 | "name": "drop"
121 | },
122 | {
123 | "name": "end"
124 | }
125 | ]
126 | }
127 | ]
128 | },
129 | {
130 | "name": "data",
131 | "entries": [
132 | {
133 | "index": 0,
134 | "offset": {
135 | "return_type": "i32",
136 | "name": "const",
137 | "immediates": "0"
138 | },
139 | "data": [
140 | 104,
141 | 105
142 | ]
143 | }
144 | ]
145 | }
146 | ]
--------------------------------------------------------------------------------
/test/in/json/stuff.wast.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "preramble",
4 | "magic": [
5 | 0,
6 | 97,
7 | 115,
8 | 109
9 | ],
10 | "version": [
11 | 13,
12 | 0,
13 | 0,
14 | 0
15 | ]
16 | },
17 | {
18 | "name": "type",
19 | "entries": [
20 | {
21 | "form": "func",
22 | "params": [
23 | "f32"
24 | ]
25 | },
26 | {
27 | "form": "func",
28 | "params": [
29 | "i32"
30 | ],
31 | "return_type": "i32"
32 | },
33 | {
34 | "form": "func",
35 | "params": []
36 | }
37 | ]
38 | },
39 | {
40 | "name": "import",
41 | "entries": [
42 | {
43 | "moduleStr": "foo",
44 | "fieldStr": "bar",
45 | "kind": "function",
46 | "type": 0
47 | }
48 | ]
49 | },
50 | {
51 | "name": "function",
52 | "entries": [
53 | 2,
54 | 0
55 | ]
56 | },
57 | {
58 | "name": "table",
59 | "entries": [
60 | {
61 | "elementType": "anyFunc",
62 | "limits": {
63 | "flags": 1,
64 | "intial": 0,
65 | "maximum": 1
66 | }
67 | }
68 | ]
69 | },
70 | {
71 | "name": "memory",
72 | "entries": [
73 | {
74 | "flags": 1,
75 | "intial": 1,
76 | "maximum": 1
77 | }
78 | ]
79 | },
80 | {
81 | "name": "export",
82 | "entries": [
83 | {
84 | "field_str": "e",
85 | "kind": "function",
86 | "index": 1
87 | }
88 | ]
89 | },
90 | {
91 | "name": "start",
92 | "index": 1
93 | },
94 | {
95 | "name": "code",
96 | "entries": [
97 | {
98 | "locals": [],
99 | "code": [
100 | {
101 | "name": "end"
102 | }
103 | ]
104 | },
105 | {
106 | "locals": [],
107 | "code": [
108 | {
109 | "return_type": "i32",
110 | "name": "const",
111 | "immediates": "42"
112 | },
113 | {
114 | "name": "drop"
115 | },
116 | {
117 | "name": "end"
118 | }
119 | ]
120 | }
121 | ]
122 | },
123 | {
124 | "name": "data",
125 | "entries": [
126 | {
127 | "index": 0,
128 | "offset": {
129 | "return_type": "i32",
130 | "name": "const",
131 | "immediates": "0"
132 | },
133 | "data": [
134 | 104,
135 | 105
136 | ]
137 | }
138 | ]
139 | }
140 | ]
--------------------------------------------------------------------------------
/test/in/json/zeroCostOps.wast.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "preramble",
4 | "magic": [
5 | 0,
6 | 97,
7 | 115,
8 | 109
9 | ],
10 | "version": [
11 | 13,
12 | 0,
13 | 0,
14 | 0
15 | ]
16 | },
17 | {
18 | "name": "type",
19 | "entries": [
20 | {
21 | "form": "func",
22 | "params": [
23 | "i64"
24 | ],
25 | "return_type": "i64"
26 | }
27 | ]
28 | },
29 | {
30 | "name": "function",
31 | "entries": [
32 | 0
33 | ]
34 | },
35 | {
36 | "name": "export",
37 | "entries": [
38 | {
39 | "field_str": "fac",
40 | "kind": "function",
41 | "index": 0
42 | }
43 | ]
44 | },
45 | {
46 | "name": "code",
47 | "entries": [
48 | {
49 | "locals": [],
50 | "code": [
51 | {
52 | "name": "get_local",
53 | "immediates": "0"
54 | },
55 | {
56 | "return_type": "i64",
57 | "name": "const",
58 | "immediates": "1"
59 | },
60 | {
61 | "return_type": "i64",
62 | "name": "lt_s"
63 | },
64 | {
65 | "name": "if",
66 | "immediates": "i64"
67 | },
68 | {
69 | "return_type": "i64",
70 | "name": "const",
71 | "immediates": "1"
72 | },
73 | {
74 | "name": "else"
75 | },
76 | {
77 | "name": "get_local",
78 | "immediates": "0"
79 | },
80 | {
81 | "name": "get_local",
82 | "immediates": "0"
83 | },
84 | {
85 | "return_type": "i64",
86 | "name": "const",
87 | "immediates": "1"
88 | },
89 | {
90 | "return_type": "i64",
91 | "name": "sub"
92 | },
93 | {
94 | "name": "call",
95 | "immediates": "0"
96 | },
97 | {
98 | "return_type": "i64",
99 | "name": "mul"
100 | },
101 | {
102 | "name": "end"
103 | },
104 | {
105 | "name": "end"
106 | }
107 | ]
108 | }
109 | ]
110 | }
111 | ]
--------------------------------------------------------------------------------
/test/in/wast/basic+import.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (type $a (func(param i32 i32) (result i32)))
3 | (type $b (func(param i64)))
4 | (import "metering" "usegas" (func (type $b)))
5 | (func $addTwo (type $a)
6 | (i32.add
7 | (get_local 0)
8 | (get_local 1)))
9 | (export "addTwo" (func $addTwo)))
10 |
--------------------------------------------------------------------------------
/test/in/wast/basic.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (func $addTwo (param i32 i32) (result i32)
3 | (i32.add
4 | (get_local 0)
5 | (get_local 1)))
6 | (export "addTwo" (func $addTwo)))
7 |
--------------------------------------------------------------------------------
/test/in/wast/element.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (type (func))
3 | (type (func (result i32)))
4 |
5 | (func $f (import "Mt" "call") (param i32) (result i32))
6 | (func $h (import "Mt" "h") (result i32))
7 |
8 | (table anyfunc (elem $g $g $g $h $f))
9 | (func $g (result i32) (i32.const 5))
10 |
11 | (export "Mt.call" (func $f))
12 | (func (export "call Mt.call") (param i32) (result i32)
13 | (call $f (get_local 0))
14 | )
15 | (func (export "call") (param i32) (result i32)
16 | (call_indirect 1 (get_local 0))
17 | )
18 | )
19 |
--------------------------------------------------------------------------------
/test/in/wast/fac.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (func $fac (param i64) (result i64)
3 | (if i64
4 | (i64.lt_s (get_local 0) (i64.const 1))
5 | (then (i64.const 1))
6 | (else
7 | (i64.mul
8 | (get_local 0)
9 | (call $fac
10 | (i64.sub
11 | (get_local 0)
12 | (i64.const 1)))))))
13 | (export "fac" (func $fac)))
14 |
--------------------------------------------------------------------------------
/test/in/wast/memory0.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (memory 1 2)
3 | (data (i32.const 0) "a")
4 | (data (i32.const 65535) "b"))
5 |
--------------------------------------------------------------------------------
/test/in/wast/memory1.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (memory 1 2)
3 | (data (i32.const 0) "a")
4 | (data (i32.const 65535) "b"))
5 |
--------------------------------------------------------------------------------
/test/in/wast/memory2.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (memory 1 2)
3 | (data (i32.const 0) "a")
4 | (data (i32.const 65535) "b"))
5 |
--------------------------------------------------------------------------------
/test/in/wast/mixedImports.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (type $a (func(param i32 i32) (result i32)))
3 | (type $b (func(param i64)))
4 | (import "teat" "adf" (global i64))
5 | (func $addTwo (type $a)
6 | (i32.add
7 | (get_local 0)
8 | (get_local 1)))
9 | (export "addTwo" (func $addTwo)))
10 |
--------------------------------------------------------------------------------
/test/in/wast/start.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (import "foo" "bar" (func))
3 | (import "foo" "bar" (func (param f32)))
4 | (memory (data "hi"))
5 | (type (func (param i32) (result i32)))
6 | (start 0)
7 | (table 0 1 anyfunc)
8 | (func)
9 | (func (type 1) (drop (i32.const 42)))
10 | (export "e" (func 1)))
11 |
--------------------------------------------------------------------------------
/test/in/wast/stuff.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (import "foo" "bar" (func (param f32)))
3 | (memory (data "hi"))
4 | (type (func (param i32) (result i32)))
5 | (start 1)
6 | (table 0 1 anyfunc)
7 | (func)
8 | (func (type 0) (drop (i32.const 42)))
9 | (export "e" (func 1)))
10 |
--------------------------------------------------------------------------------
/test/in/wast/zeroCostOps.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (func $fac (param i64) (result i64)
3 | (if i64
4 | (i64.lt_s (get_local 0) (i64.const 1))
5 | (then (i64.const 1))
6 | (else
7 | (i64.mul
8 | (get_local 0)
9 | (call $fac
10 | (i64.sub
11 | (get_local 0)
12 | (i64.const 1)))))))
13 | (export "fac" (func $fac)))
14 |
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const tape = require('tape')
3 | const metering = require('../')
4 | const defaultCostTable = require('./defaultCostTable')
5 | const toolkit = require('wasm-json-toolkit')
6 |
7 | tape('basic test', t => {
8 | const json = JSON.parse(fs.readFileSync(`${__dirname}/in/json/basic.wast.json`).toString())
9 | const wasm = toolkit.json2wasm(json)
10 |
11 | const meteredWasm = metering.meterWASM(wasm)
12 |
13 | const meteredJSON = toolkit.wasm2json(meteredWasm)
14 | t.equals(meteredJSON[2].entries[0].moduleStr, 'metering')
15 | t.equals(meteredJSON[2].entries[0].fieldStr, 'usegas')
16 | t.equals(meteredJSON[1].entries[1].params[0], 'i32')
17 |
18 | t.end()
19 | })
20 |
21 | tape('basic metering tests', t => {
22 | let files = fs.readdirSync(`${__dirname}/in/json`)
23 | // files = ['zeroCostOps.wast.json']
24 | for (const file of files) {
25 | console.log(file)
26 | const json = JSON.parse(fs.readFileSync(`${__dirname}/in/json/${file}`).toString())
27 | let costTable
28 |
29 | try {
30 | costTable = require(`${__dirname}/in/costTables/${file}.js`)
31 | } catch (e) {
32 | costTable = defaultCostTable
33 | }
34 |
35 | try {
36 | let meteredJson = metering.meterJSON(json, {
37 | costTable
38 | })
39 |
40 | let expectedJson = require(`${__dirname}/expected-out/json/${file}`)
41 | t.deepEquals(meteredJson, expectedJson, `${file} - should have the correct json`)
42 | } catch (e) {
43 | t.equals(file, 'basic+import.wast.json')
44 | }
45 | }
46 | t.end()
47 | })
48 |
49 | tape('wasm test', t => {
50 | const json = require('./in/json/basic.wast.json')
51 | const wasm = toolkit.json2wasm(json)
52 |
53 | const meteredWasm = metering.meterWASM(wasm, {
54 | meterType: 'i32',
55 | fieldStr: 'test',
56 | moduleStr: 'test'
57 | })
58 |
59 | const meteredJSON = toolkit.wasm2json(meteredWasm)
60 | t.equals(meteredJSON[2].entries[0].moduleStr, 'test')
61 | t.equals(meteredJSON[2].entries[0].fieldStr, 'test')
62 | t.equals(meteredJSON[1].entries[1].params[0], 'i32')
63 |
64 | t.end()
65 | })
66 |
--------------------------------------------------------------------------------