From 98a0aa863d23f9b556d17b8bdca81dd9e489db4a Mon Sep 17 00:00:00 2001 From: dcodeIO Date: Sat, 19 May 2018 13:38:47 +0200 Subject: [PATCH] Initial loader that unifies utils and demangle --- lib/demangle/README.md | 39 ------ lib/demangle/index.js | 58 --------- lib/demangle/tests/index.js | 45 ------- lib/loader/README.md | 132 +++++++++++++++++++++ lib/loader/index.d.ts | 47 ++++++++ lib/loader/index.js | 163 ++++++++++++++++++++++++++ lib/{demangle => loader}/package.json | 9 +- lib/loader/tests/assembly/index.ts | 46 ++++++++ lib/loader/tests/build/untouched.wasm | Bin 0 -> 1104 bytes lib/loader/tests/index.js | 34 ++++++ lib/utils/README.md | 17 --- lib/utils/index.js | 103 ---------------- lib/utils/package.json | 6 - 13 files changed, 429 insertions(+), 270 deletions(-) delete mode 100644 lib/demangle/README.md delete mode 100644 lib/demangle/index.js delete mode 100644 lib/demangle/tests/index.js create mode 100644 lib/loader/README.md create mode 100644 lib/loader/index.d.ts create mode 100644 lib/loader/index.js rename lib/{demangle => loader}/package.json (51%) create mode 100644 lib/loader/tests/assembly/index.ts create mode 100644 lib/loader/tests/build/untouched.wasm create mode 100644 lib/loader/tests/index.js delete mode 100644 lib/utils/README.md delete mode 100644 lib/utils/index.js delete mode 100644 lib/utils/package.json diff --git a/lib/demangle/README.md b/lib/demangle/README.md deleted file mode 100644 index 96672013..00000000 --- a/lib/demangle/README.md +++ /dev/null @@ -1,39 +0,0 @@ -![AS](https://avatars1.githubusercontent.com/u/28916798?s=48) demangle -====================== - -Demangles AssemblyScript module exports to a friendly object structure compatible with WebIDL and TypeScript definitions. - -Usage ------ - -```js -var module = require("@assemblyscript/demangle")(myWasmModule.instance.exports); -// use module as defined in the .d.ts -``` - -Converting a memory offset (`this` value) to a class instance, i.e. where a class instance is returned by a WebAssembly function: - -```js - -var thisValue = wasmFunctionReturningAClassInstance(); -var myClass = MyClass.wrap(thisValue); -``` - -Converting a class instance to a memory offset (`this` value), i.e. where calling a WebAssembly function that expects a class instance: - -```js -var thisValue = myClass.this; -wasmFunctionExpectingAClassInstance(thisValue); -``` - -How does it work? ------------------ - -AssemblyScript modules expose their exported elements by their internal name, which is a JSDoc-style fully qualified name indicating layers of nesting, and this module is able to recreate the original object structure from those names. - -* A `.` seperates a parent from a static child -* A `#` separates a parent from an instance child -* The `get:` prefix indicates a getter -* The `set:` prefix indicates a setter - -Note that the compiler generates implicit getters and setters for instance fields for convenience. Support for instance members is achieved by generating wrappers that prepend the `this` value (offset of the instance in memory returned by the constructor) as the first argument when calling an instance method, getter or setter. diff --git a/lib/demangle/index.js b/lib/demangle/index.js deleted file mode 100644 index 05422085..00000000 --- a/lib/demangle/index.js +++ /dev/null @@ -1,58 +0,0 @@ -module.exports = demangle; - -/** Demangles AssemblyScript module exports to a friendly object structure. */ -function demangle(exports) { - var root = {}; - for (let internalName in exports) { - if (!exports.hasOwnProperty(internalName)) continue; - let elem = exports[internalName]; - let parts = internalName.split("."); - let curr = root; - while (parts.length > 1) { - let part = parts.shift(); - if (!curr.hasOwnProperty(part)) curr[part] = {}; - curr = curr[part]; - } - let name = parts[0]; - let hash = name.indexOf("#"); - if (hash >= 0) { - let className = name.substring(0, hash); - let classElem = curr[className]; - if (typeof classElem === "undefined" || !classElem.prototype) { - let ctor = function(...args) { - return ctor.wrap(ctor.prototype.constructor(...args)); - }; - ctor.prototype = {}; - ctor.wrap = function(thisValue) { - return Object.create(ctor.prototype, { "this": { value: thisValue, writable: false } }); - }; - if (classElem) Object.getOwnPropertyNames(classElem).forEach(name => - Object.defineProperty(ctor, name, Object.getOwnPropertyDescriptor(classElem, name)) - ); - curr[className] = ctor; - } - name = name.substring(hash + 1); - curr = curr[className].prototype; - if (/^(get|set):/.test(name)) { - if (!curr.hasOwnProperty(name = name.substring(4))) { - let getter = exports[internalName.replace("set:", "get:")]; - let setter = exports[internalName.replace("get:", "set:")]; - Object.defineProperty(curr, name, { - get: function() { return getter(this.this); }, - set: function(value) { setter(this.this, value); } - }); - } - } else curr[name] = function(...args) { return elem(this.this, ...args); }; - } else { - if (/^(get|set):/.test(name)) { - if (!curr.hasOwnProperty(name = name.substring(4))) { - Object.defineProperty(curr, name, { - get: exports[internalName.replace("set:", "get:")], - set: exports[internalName.replace("get:", "set:")] - }); - } - } else curr[name] = elem; - } - } - return root; -} diff --git a/lib/demangle/tests/index.js b/lib/demangle/tests/index.js deleted file mode 100644 index 4ba0733d..00000000 --- a/lib/demangle/tests/index.js +++ /dev/null @@ -1,45 +0,0 @@ -var assert = require("assert"); -var inspect = require("util").inspect; -var demangle = require(".."); - -var __this = 8; -var __usualDoors = 3; -var __doors = -1; - -var exports = demangle({ - "vroom": function() { console.log("vroom", arguments); }, - "Car.MAX_DOORS": 5, - "Car.get:usualDoors": function() { console.log("Car#get:usualDoors", arguments); return __usualDoors; }, - "Car.set:usualDoors": function(value) { console.log("Car#set:usualDoors", arguments); __usualDoors = value; }, - "Car#constructor": function(this_, doors) { console.log("Car#constructor", arguments); __doors = doors; return __this; }, - "Car#openDoors": function(this_) { console.log("Car#openDoors", arguments); return true; }, - "Car#get:doors": function(this_) { console.log("Car#get:doors", arguments); return __doors; }, - "Car#set:doors": function(this_, value) { console.log("Car#set:doors", arguments); __doors = value; } -}); - -console.log(inspect(exports, true)); - -exports.vroom(1, 2, 3); - -var Car = exports.Car; - -assert(Car.usualDoors == 3); -exports.Car.usualDoors = exports.Car.usualDoors + 2; -assert(Car.usualDoors == 5); - -var car = new exports.Car(2); - -assert(car.this == 8); - -assert(car.openDoors() == true); -assert(car.doors == 2); -car.doors = car.doors + 2; -assert(car.doors == 4); - -console.log(inspect(car, true)); - -var wrappedCar = exports.Car.wrap(16); - -assert(wrappedCar.this == 16); - -console.log(inspect(wrappedCar, true)); diff --git a/lib/loader/README.md b/lib/loader/README.md new file mode 100644 index 00000000..6eab1dcf --- /dev/null +++ b/lib/loader/README.md @@ -0,0 +1,132 @@ +![AS](https://avatars1.githubusercontent.com/u/28916798?s=48) loader +====================== + +A convenient loader for AssemblyScript modules. Demangles module exports to a friendly object structure compatible with WebIDL and TypeScript definitions and provides some useful utility to read/write data from/to memory. + +Usage +----- + +```js +const loader = require("@assemblyscript/loader"); +... +``` + +API +--- + +* **instantiate**<`T`>(module: `WebAssembly.Module`, imports?: `WasmImports`): `ASModule`
+ Instantiates an AssemblyScript module using the specified imports. + +* **instantiateBuffer**<`T`>(buffer: `Uint8Array`, imports?: `WasmImports`): `ASModule`
+ Instantiates an AssemblyScript module from a buffer using the specified imports. + +* **instantiateStreaming**<`T`>(response: `Response`, imports?: `WasmImports`): `Promise>`
+ Instantiates an AssemblyScript module from a response using the sspecified imports. + +* **demangle**<`T`>(exports: `WasmExports`): `T`
+ Demangles an AssemblyScript module's exports to a friendly object structure. You usually don't have to call this manually as instantiation does this implicitly. + +**Note:** `T` above can either be omitted if the structure of the module is unknown, or can reference a `.d.ts` as produced by the compiler with the `-d` option. + +Instances of `ASModule` are automatically populated with some useful utility: + +* **I8**: `Int8Array`
+ An 8-bit signed integer view on the memory. + +* **U8**: `Uint8Array`
+ An 8-bit unsigned integer view on the memory. + +* **I16**: `Int16Array`
+ A 16-bit signed integer view on the memory. + +* **U16**: `Uint16Array`
+ A 16-bit unsigned integer view on the memory. + +* **I32**: `Int32Array`
+ A 32-bit signed integer view on the memory. + +* **U32**: `Uint32Array`
+ A 32-bit unsigned integer view on the memory. + +* **F32**: `Float32Array`
+ A 32-bit float view on the memory. + +* **F64**: `Float64Array`
+ A 64-bit float view on the memory. + +* **newString**(str: `string`): `number`
+ Allocates a new string in the module's memory and returns its pointer. Requires `allocate_memory` to be exported from your module's entry file, i.e.: + + ```js + import "allocator/tlsf"; + export { allocate_memory, free_memory }; + ``` + +* **getString**(ptr: `number`): `string`
+ Gets a string from the module's memory by its pointer. + +Examples +-------- + +### Instantiating a module + +```js +// From a module provided as a buffer, i.e. as returned by fs.readFileSync +const myModule = loader.instatiateBuffer(fs.readFileSync("myModule.wasm"), myImports); + +// From a response object, i.e. as returned by window.fetch +const myModule = await loader.instantiateStreaming(fetch("myModule.wasm"), myImports); +``` + +### Reading/writing basic values to/from memory + +```js +var ptrToInt8 = ...; +var value = myModule.U16[ptrToInt8]; // alignment of log2(1)=0 + +var ptrToInt16 = ...; +var value = myModule.U16[ptrToInt16 >>> 1]; // alignment of log2(2)=1 + +var ptrToInt32 = ...; +var value = myModule.U32[ptrToInt32 >>> 2]; // alignment of log2(4)=2 + +var ptrToFloat32 = ...; +var value = myModule.F32[ptrToFloat32 >>> 2]; // alignment of log2(4)=2 + +var ptrToFloat64 = ...; +var value = myModule.F64[ptrToFloat64 >>> 3]; // alignment of log2(8)=3 + +// Likewise, for writing +myModule.U16[ptrToInt8] = newValue; +myModule.U16[ptrToInt16 >>> 1] = newValue; +myModule.U32[ptrToInt32 >>> 2] = newValue; +myModule.F32[ptrToFloat32 >>> 2] = newValue; +myModule.F64[ptrToFloat64 >>> 3] = newValue; +``` + +**Note:** Make sure to reference the views as shown above as these will automatically be updated when the module's memory grows. + +### Allocating/obtaining strings to/from memory + +```js +// Allocating a string, i.e. to be passed to an export expecting one +var str = "Hello world!"; +var ptr = module.newString(str); + +// Disposing a string that is no longer needed (requires free_memory to be exported) +module.free_memory(ptr); + +// Obtaining a string, i.e. as returned by an export +var ptrToString = ...; +var str = module.getString(ptrToString); +``` + +### Usage with TypeScript definitions produced by the compiler + +```ts +import MyModule from "myModule"; // pointing at the d.ts + +const myModule = loader.instatiateBuffer(fs.readFileSync("myModule.wasm"), myImports); +``` + +**Hint:** You can produce a `.d.ts` for your module with the `-d` option on the command line. diff --git a/lib/loader/index.d.ts b/lib/loader/index.d.ts new file mode 100644 index 00000000..d810ad57 --- /dev/null +++ b/lib/loader/index.d.ts @@ -0,0 +1,47 @@ +import "@types/webassembly-js-api"; + +/** WebAssembly imports with two levels of nesting. */ +interface ImportsObject { + [key: string]: {}, + env: { + memory?: WebAssembly.Memory, + table?: WebAssembly.Table, + abort?: (msg: number, file: number, line: number, column: number) => void + } +} + +/** Utility mixed in by the loader. */ +interface ASUtil { + /** An 8-bit signed integer view on the memory. */ + readonly I8: Uint8Array, + /** An 8-bit unsigned integer view on the memory. */ + readonly U8: Uint8Array, + /** A 16-bit signed integer view on the memory. */ + readonly I16: Uint16Array, + /** A 16-bit unsigned integer view on the memory. */ + readonly U16: Uint16Array, + /** A 32-bit signed integer view on the memory. */ + readonly I32: Uint32Array, + /** A 32-bit unsigned integer view on the memory. */ + readonly U32: Uint32Array, + /** A 32-bit float view on the memory. */ + readonly F32: Float32Array, + /** A 64-bit float view on the memory. */ + readonly F64: Float64Array, + /** Allocates a new string in the module's memory and returns its pointer. */ + newString(str: string): number; + /** Gets a string from the module's memory by its pointer. */ + getString(ptr: number): string; +} + +/** Instantiates an AssemblyScript module using the specified imports. */ +export declare function instantiate(module: WebAssembly.Module, imports?: ImportsObject): ASUtil & T; + +/** Instantiates an AssemblyScript module from a buffer using the specified imports. */ +export declare function instantiateBuffer(buffer: Uint8Array, imports?: ImportsObject): ASUtil & T; + +/** Instantiates an AssemblyScript module from a response using the sspecified imports. */ +export declare function instantiateStreaming(response: Response, imports?: ImportsObject): Promise; + +/** Demangles an AssemblyScript module's exports to a friendly object structure. */ +export declare function demangle(exports: {}): T; diff --git a/lib/loader/index.js b/lib/loader/index.js new file mode 100644 index 00000000..f4ec2f8f --- /dev/null +++ b/lib/loader/index.js @@ -0,0 +1,163 @@ +"use strict"; + +/** Instantiates an AssemblyScript module using the specified imports. */ +function instantiate(module, imports) { + + // Set up the imports object + if (!imports) imports = {}; + if (!imports.env) imports.env = {}; + if (!imports.env.abort) imports.env.abort = function(mesg, file, line, colm) { + mesg = mem ? getString(mesg) : ""; + file = mem ? getString(file) : ""; + throw Error("abort: " + mesg + " at " + file + ":" + line + ":" + colm); + } + + // Instantiate the module and obtain its (flat) exports + var instance = new WebAssembly.Instance(module, imports); + var exports = instance.exports; + + // Provide views for all sorts of basic values + var mem, I8, U8, I16, U16, I32, U32, F32, F64; + + /** Updates memory views if memory has grown meanwhile. */ + function checkMem() { + // see: https://github.com/WebAssembly/design/issues/1210 + if (mem !== exports.memory.buffer) { + mem = exports.memory.buffer; + I8 = new Int8Array(mem); + U8 = new Uint8Array(mem); + I16 = new Int16Array(mem); + U16 = new Uint16Array(mem); + I32 = new Int32Array(mem); + U32 = new Uint32Array(mem); + F32 = new Float32Array(mem); + F64 = new Float64Array(mem); + } + } + checkMem(); + + /** Allocates a new string in the module's memory and returns its pointer. */ + function newString(str) { + var dataLength = str.length; + var ptr = exports.allocate_memory(4 + (dataLength << 1)); + var dataOffset = (4 + ptr) >>> 1; + checkMem(); + U32[ptr >>> 2] = dataLength; + for (let i = 0; i < dataLength; ++i) U16[dataOffset + i] = str.charCodeAt(i); + return ptr; + } + + /** Gets a string from the module's memory by its pointer. */ + function getString(ptr) { + checkMem(); + var dataLength = U32[ptr >>> 2]; + var dataOffset = (ptr + 4) >>> 1; + var dataRemain = dataLength; + var parts = []; + const chunkSize = 1024; + while (dataRemain > chunkSize) { + let last = U16[dataOffset + chunkSize - 1]; + let size = last >= 0xD800 && last < 0xDC00 ? chunkSize - 1 : chunkSize; + let part = U16.subarray(dataOffset, dataOffset += size); + parts.push(String.fromCharCode.apply(String, part)); + dataRemain -= size; + } + return parts.join("") + String.fromCharCode.apply(String, U16.subarray(dataOffset, dataOffset + dataRemain)); + } + + // Demangle exports and provide the usual utility on the prototype + return demangle(exports, { + get I8() { checkMem(); return I8; }, + get U8() { checkMem(); return U8; }, + get I16() { checkMem(); return I16; }, + get U16() { checkMem(); return U16; }, + get I32() { checkMem(); return I32; }, + get U32() { checkMem(); return U32; }, + get F32() { checkMem(); return F32; }, + get F64() { checkMem(); return F64; }, + newString, + getString + }); +} + +exports.instantiate = instantiate; + +/** Instantiates an AssemblyScript module from a buffer using the specified imports. */ +function instantiateBuffer(buffer, imports) { + var module = new WebAssembly.Module(buffer); + return instantiate(module, imports); +} + +exports.instantiateBuffer = instantiateBuffer; + +/** Instantiates an AssemblyScript module from a response using the specified imports. */ +async function instantiateStreaming(response, imports) { + var module = await WebAssembly.compileStreaming(response); + return instantiate(module, imports); +} + +exports.instantiateStreaming = instantiateStreaming; + +/** Demangles an AssemblyScript module's exports to a friendly object structure. */ +function demangle(exports, baseModule) { + var module = baseModule ? Object.create(baseModule) : {}; + function hasOwnProperty(elem, prop) { + return Object.prototype.hasOwnProperty.call(elem, prop); + } + for (let internalName in exports) { + if (!hasOwnProperty(exports, internalName)) continue; + let elem = exports[internalName]; + let parts = internalName.split("."); + let curr = module; + while (parts.length > 1) { + let part = parts.shift(); + if (!hasOwnProperty(curr, part)) curr[part] = {}; + curr = curr[part]; + } + let name = parts[0]; + let hash = name.indexOf("#"); + if (hash >= 0) { + let className = name.substring(0, hash); + let classElem = curr[className]; + if (typeof classElem === "undefined" || !classElem.prototype) { + let ctor = function(...args) { + return ctor.wrap(ctor.prototype.constructor(...args)); + }; + ctor.prototype = {}; + ctor.wrap = function(thisValue) { + return Object.create(ctor.prototype, { "this": { value: thisValue, writable: false } }); + }; + if (classElem) Object.getOwnPropertyNames(classElem).forEach(name => + Object.defineProperty(ctor, name, Object.getOwnPropertyDescriptor(classElem, name)) + ); + curr[className] = ctor; + } + name = name.substring(hash + 1); + curr = curr[className].prototype; + if (/^(get|set):/.test(name)) { + if (!hasOwnProperty(curr, name = name.substring(4))) { + let getter = exports[internalName.replace("set:", "get:")]; + let setter = exports[internalName.replace("get:", "set:")]; + Object.defineProperty(curr, name, { + get: function() { return getter(this.this); }, + set: function(value) { setter(this.this, value); }, + enumerable: true + }); + } + } else curr[name] = function(...args) { return elem(this.this, ...args); }; + } else { + if (/^(get|set):/.test(name)) { + if (!hasOwnProperty(curr, name = name.substring(4))) { + Object.defineProperty(curr, name, { + get: exports[internalName.replace("set:", "get:")], + set: exports[internalName.replace("get:", "set:")], + enumerable: true + }); + } + } else curr[name] = elem; + } + } + return module; +} + +exports.demangle = demangle; diff --git a/lib/demangle/package.json b/lib/loader/package.json similarity index 51% rename from lib/demangle/package.json rename to lib/loader/package.json index 445e8b77..7ff06ee8 100644 --- a/lib/demangle/package.json +++ b/lib/loader/package.json @@ -1,13 +1,18 @@ { - "name": "@assemblyscript/demangle", + "name": "@assemblyscript/loader", "version": "1.0.0", "main": "index.js", + "types": "index.d.ts", "scripts": { "test": "node tests" }, "files": [ + "index.d.ts", "index.js", "package.json", "README.md" - ] + ], + "dependencies": { + "@types/webassembly-js-api": "0.0.1" + } } diff --git a/lib/loader/tests/assembly/index.ts b/lib/loader/tests/assembly/index.ts new file mode 100644 index 00000000..cee93791 --- /dev/null +++ b/lib/loader/tests/assembly/index.ts @@ -0,0 +1,46 @@ +import "allocator/arena"; + +export const COLOR: string = "red"; + +export function strlen(str: string): i32 { + return str.length; +} + +export namespace math { + export function add(a: i32, b: i32): i32 { + return a + b; + } +} + +export class Car { + static readonly MAX_DOORS: i32 = 5; + static usualDoors: i32 = 3; + + numDoors: i32; + private doorsOpen: bool = false; + + get isDoorsOpen(): bool { return this.doorsOpen; } + set isDoorsOpen(value: bool) { this.doorsOpen = value; } + + constructor(numDoors: i32) { + this.numDoors = numDoors; + } + + openDoors(): bool { + if (this.doorsOpen) return false; + this.doorsOpen = true; + return true; + } + + closeDoors(): bool { + if (!this.doorsOpen) return false; + this.doorsOpen = false; + return true; + } + + dispose(): void { + free_memory(changetype(this)); + } +} + +export { allocate_memory, free_memory }; diff --git a/lib/loader/tests/build/untouched.wasm b/lib/loader/tests/build/untouched.wasm new file mode 100644 index 0000000000000000000000000000000000000000..f1ba66e0a2ecb1dd5715bc47402de83e63a25fcf GIT binary patch literal 1104 zcmZ`&%Wl&^6utAZ6Hih{DiW0{q{(B^4Gk-hx*?+$3Gq;*vSHV_$p9&Sv>q4H4dy3U z@+bTdUs3MZPKY4!jPJ}n_sqSXnPZ4-LI8jqh#4tKIiqD`0ezSOu)Qu2Y!n+X#sx#q zdlrZeg{;3$j#adyc(v^ zBAwtD?Y2O{5rt5?i6U1a9*0*d;1kuH*=s%lITU@Oh=MEaW7nm<>C@-XXNoGOdj)cE zMn3ENdv@iFW9Z(OK38lY6d!m>DDTx_UnnsF4KI<8X{!lHDHRfHuFUi<+% CB^~?# literal 0 HcmV?d00001 diff --git a/lib/loader/tests/index.js b/lib/loader/tests/index.js new file mode 100644 index 00000000..625b420f --- /dev/null +++ b/lib/loader/tests/index.js @@ -0,0 +1,34 @@ +var fs = require("fs"); +var assert = require("assert"); +var inspect = require("util").inspect; + +var loader = require(".."); +var buffer = fs.readFileSync(__dirname + "/build/untouched.wasm"); +var module = loader.instantiateBuffer(buffer, {}); + +console.log(inspect(module, true, 100, true)); + +// should inherit the usual utility +var proto = Object.getPrototypeOf(module); +assert(proto.I8 instanceof Int8Array); +assert(proto.U8 instanceof Uint8Array); +assert(proto.I16 instanceof Int16Array); +assert(proto.U16 instanceof Uint16Array); +assert(proto.I32 instanceof Int32Array); +assert(proto.U32 instanceof Uint32Array); +assert(proto.F32 instanceof Float32Array); +assert(proto.F64 instanceof Float64Array); +assert(typeof proto.newString === "function"); +assert(typeof proto.getString === "function"); + +// should export memory +assert(module.memory instanceof WebAssembly.Memory); + +// should be able to get an exported string +assert.strictEqual(module.getString(module.COLOR), "red"); + +// should be able to allocate and work with a new string +var str = "Hello world!𤭢"; +var ptr = module.newString(str); +assert.strictEqual(module.getString(ptr), str); +assert.strictEqual(module.strlen(ptr), str.length); diff --git a/lib/utils/README.md b/lib/utils/README.md deleted file mode 100644 index cf3a2d0d..00000000 --- a/lib/utils/README.md +++ /dev/null @@ -1,17 +0,0 @@ -![AS](https://avatars1.githubusercontent.com/u/28916798?s=48) utils -================= - -Utilities for working with [AssemblyScript](http://assemblyscript.org) modules. - -Usage ------ - -```js -import utils from "@assemblyscript/utils"; - -var myModule = ...; - -var helpers = utils(myModule); - -var str = helpers.string(myModule.exportReturningAString()); -``` diff --git a/lib/utils/index.js b/lib/utils/index.js deleted file mode 100644 index d5aaec69..00000000 --- a/lib/utils/index.js +++ /dev/null @@ -1,103 +0,0 @@ -function utils(module) { - - var i8, - u8 = new Uint8Array(0), - i16, - u16, - i32, - u32, - f32, - f64; - - function maybeUpdate() { - var mem = module.memory.buffer; - if (mem.byteLength === u8.length) - return; - i8 = Int8Array(mem); - u8 = Uint8Array(mem); - i16 = Int16Array(mem); - u16 = Uint16Array(mem); - i32 = Int32Array(mem); - u32 = Uint32Array(mem); - f32 = Float32Array(mem); - f64 = Float64Array(mem); - } - - var helpers = { - - i8: function(ptr) { - maybeUpdate(); - return i8[ptr]; - }, - - u8: function(ptr) { - maybeUpdate(); - return u8[ptr]; - }, - - i16: function(ptr) { - maybeUpdate(); - return i16[ptr >>> 1]; - }, - - u16: function(ptr) { - maybeUpdate(); - return u16[ptr >>> 1]; - }, - - i32: function(ptr) { - maybeUpdate(); - return i32[ptr >>> 2]; - }, - - u32: function(ptr) { - maybeUpdate(); - return u32[ptr >>> 2]; - }, - - i64: function(ptr) { - maybeUpdate(); - return { - low: i32[ptr >>> 2], - high: i32[(ptr >>> 2) + 1] - }; - }, - - u64: function(ptr) { - maybeUpdate(); - return { - low: u32[ptr >>> 2], - high: u32[(ptr >>> 2) + 1] - }; - }, - - bool: function(ptr) { - maybeUpdate(); - return u8[ptr] === 1; - }, - - f32: function(ptr) { - maybeUpdate(); - return f32[ptr >>> 2]; - }, - - f64: function(ptr) { - maybeUpdate(); - return f64[ptr >>> 3]; - }, - - string: function(ptr) { - maybeUpdate(); - var len = u32[ptr >>> 2]; - var off = (ptr >>> 1) + 2; - return String.fromCharCode.apply(String, u16.subarray(off, off + len)); - } - }; - - return helpers; -}; - -Object.defineProperties(module.exports = utils, { - __esModule: { value: true }, - default: { value: utils } -}); diff --git a/lib/utils/package.json b/lib/utils/package.json deleted file mode 100644 index 157e140d..00000000 --- a/lib/utils/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "@assemblyscript/utils", - "version": "0.5.0", - "description": "Utilities for working with AssemblyScript modules.", - "license": "Apache-2.0" -}