diff --git a/assembly/hello-world/index.ts b/assembly/hello-world/index.ts index b63dcde..1888808 100644 --- a/assembly/hello-world/index.ts +++ b/assembly/hello-world/index.ts @@ -1,5 +1,14 @@ import * as env from '../env' +/** + * Examples for linking a library + */ +@external("add", "incr") +export declare function incr(a: u32): u32 + +@external("add", "add") +export declare function add(a: u32, b: u32): u32 + /* * Increments preStateRoot by one */ @@ -10,7 +19,8 @@ export function main(): void { var postStateRootPtr: u32 = __heap_base + 32 var numPtr: u32 = __heap_base + 64 - store(numPtr, 1, 31) + // Silly example of how you can use lib + store(numPtr, add(0, 1), 31) env.bignum_add256(preStateRootPtr, numPtr, postStateRootPtr) diff --git a/assembly/lib/add.ts b/assembly/lib/add.ts new file mode 100644 index 0000000..c5530ca --- /dev/null +++ b/assembly/lib/add.ts @@ -0,0 +1,7 @@ +export function incr(a: u32): u32 { + return a + 1 +} + +export function add(a: u32, b: u32): u32 { + return a + b +} diff --git a/package.json b/package.json index b6755b9..d18444d 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,8 @@ "docs": "typedoc --out docs --mode modules --theme markdown --excludeNotExported src", "asbuild:untouched": "asc assembly/hello-world/index.ts -b build/hello-world-untouched.wasm -t build/hello-world-untouched.wat --sourceMap --validate --debug", "asbuild:optimized": "asc assembly/hello-world/index.ts -b build/hello-world-optimized.wasm -t build/hello-world-optimized.wat --sourceMap --validate --optimize", - "asbuild": "npm run asbuild:untouched && npm run asbuild:optimized" + "asbuild": "npm run asbuild:untouched && npm run asbuild:optimized", + "asbuild:lib": "asc assembly/lib/add.ts -b build/lib-add-optimized.wasm -t build/lib-add-optimized.wat --sourceMap --validate --optimize" }, "author": "s1na", "license": "Apache-2.0", diff --git a/src/cli.ts b/src/cli.ts index 742cda7..6be08c3 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -22,7 +22,10 @@ function main() { const wasmModule = new WebAssembly.Module(wasmFile) let preStateRoot = testCase.preStateRoot for (const block of testCase.blocks) { - const instance = new WebAssembly.Instance(wasmModule, getImports({ preStateRoot, blockData: block })) + let libExports = getLibExports(testCase.libs) + let imports = getImports({ preStateRoot, blockData: block }) + imports = { ...imports, ...libExports } + const instance = new WebAssembly.Instance(wasmModule, imports) setMemory(instance.exports.memory) let t = process.hrtime() instance.exports.main() @@ -34,4 +37,27 @@ function main() { } } +interface Exports { + // { libName: { exportName: Fn } } + [n: string]: { [f: string]: Function } +} + +function getLibExports(libs: { [k: string]: string }): Exports { + let libExports: Exports = {} + for (const libName in libs) { + const libFile = fs.readFileSync(libs[libName]) + const libModule = new WebAssembly.Module(libFile) + const libInstance = new WebAssembly.Instance(libModule, { env: { abort: () => { throw new Error('Wasm aborted') } } }) + const exports: { [k: string]: Function } = {} + for (const fn in libInstance.exports) { + if (fn === 'memory' || fn.startsWith('_')) { + continue + } + exports[fn] = libInstance.exports[fn] + } + libExports[libName] = exports + } + return libExports +} + main() diff --git a/src/lib.ts b/src/lib.ts index 20c2597..2aa9c7a 100644 --- a/src/lib.ts +++ b/src/lib.ts @@ -29,6 +29,7 @@ export interface ShardBlock { export interface TestCase { script: string + libs: { [k: string]: string } // { name: file } preStateRoot: Buffer blocks: Buffer[] postStateRoot: Buffer @@ -100,6 +101,9 @@ export const getImports = (env: EnvData) => { export function parseYaml (file: string): TestCase[] { const testCase = safeLoad(file) const scripts = testCase.beacon_state.execution_scripts + const libs = (testCase.beacon_state.libraries || []).reduce( + (a: { [k: string]: string }, v: { name: string, file: string }) => { a[v.name] = v.file; return a }, {} + ) const shardBlocks = testCase.shard_blocks const testCases = [] for (let i = 0; i < scripts.length; i++) { @@ -118,6 +122,7 @@ export function parseYaml (file: string): TestCase[] { testCases.push({ script, + libs, preStateRoot, postStateRoot, blocks diff --git a/test.yaml b/test.yaml index a491ad2..40e52fc 100644 --- a/test.yaml +++ b/test.yaml @@ -1,6 +1,9 @@ beacon_state: execution_scripts: - build/hello-world-optimized.wasm + libraries: + - name: "add" + file: build/lib-add-optimized.wasm shard_pre_state: exec_env_states: - "0000000000000000000000000000000000000000000000000000000000000001"