├── .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 | [![NPM Package](https://img.shields.io/npm/v/wasm-metering.svg?style=flat-square)](https://www.npmjs.org/package/wasm-metering) 4 | [![Build Status](https://img.shields.io/travis/ewasm/wasm-metering.svg?branch=master&style=flat-square)](https://travis-ci.org/ewasm/wasm-metering) 5 | [![Coverage Status](https://img.shields.io/coveralls/ewasm/wasm-metering.svg?style=flat-square)](https://coveralls.io/r/ewasm/wasm-metering) 6 | 7 | [![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](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 Akl -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------