summaryrefslogtreecommitdiff
path: root/src/wasm.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm.js')
-rw-r--r--src/wasm.js1145
1 files changed, 0 insertions, 1145 deletions
diff --git a/src/wasm.js b/src/wasm.js
deleted file mode 100644
index d77dd3bf..00000000
--- a/src/wasm.js
+++ /dev/null
@@ -1,1145 +0,0 @@
-/*
- * Copyright 2016 WebAssembly Community Group participants
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var wasm = {};
-
-wasm.ready = new Promise(function(resolve, reject) {
- wasm.$resolve = resolve;
- wasm.$reject = reject;
-});
-
-var Module = {};
-Module.onRuntimeInitialized = function() {
-
-// Helpers /////////////////////////////////////////////////////////////////////
-
-function loadi8(addr) { return HEAP8[addr]; }
-function loadi16(addr) { return HEAP16[addr>>1]; }
-function loadi32(addr) { return HEAP32[addr>>2]; }
-function loadu8(addr) { return HEAPU8[addr]; }
-function loadu16(addr) { return HEAPU16[addr>>1]; }
-function loadu32(addr) { return HEAPU32[addr>>2]; }
-function loadf32(addr) { return HEAPF32[addr>>2]; }
-function loadf64(addr) { return HEAPF64[addr>>4]; }
-function storei8(addr, value) { HEAP8[addr] = value; }
-function storei16(addr, value) { HEAP16[addr>>1] = value; }
-function storei32(addr, value) { HEAP32[addr>>2] = value; }
-function storeu8(addr, value) { HEAPU8[addr] = value; }
-function storeu16(addr, value) { HEAPU16[addr>>1] = value; }
-function storeu32(addr, value) { HEAPU32[addr>>2] = value; }
-function storef32(addr, value) { HEAPF32[addr>>2] = value; }
-function storef64(addr, value) { HEAPF64[addr>>4] = value; }
-
-function loadcstr(addr) { return Module.AsciiToString(addr); }
-function loadstrslice(addr, len) { return Module.Pointer_stringify(addr, len); }
-function loadbuffer(addr, len) {
- return new Uint8Array(HEAPU8.buffer, addr, len);
-}
-
-function sizeof(structName) { return Module['_wasm_sizeof_' + structName](); }
-function offsetof(structName, fieldName) {
- return Module['_wasm_offsetof_' + structName + '_' + fieldName]();
-}
-
-function malloc(size) {
- var addr = Module._malloc(size);
- if (addr == 0) {
- throw new Error('out of memory');
- }
- return addr;
-}
-
-function mallocz(size) {
- var addr = malloc(size);
- HEAPU8.fill(0, addr, addr + size);
- return addr;
-}
-
-function free(addr) { Module._free(addr); }
-
-// Types ///////////////////////////////////////////////////////////////////////
-
-function Type(name, id) {
- this.name = name;
- if (id) {
- // alias
- this.id = id;
- } else {
- this.id = Type.id++;
- Type.map[this.id] = this;
- }
-}
-Type.id = 0;
-Type.map = {};
-Type.check = function(expected, actual) {
- if (actual.id != expected.id) {
- throw new Error('type mismatch; expected ' + expected.toString() +
- ', got ' + actual.toString());
- }
-};
-Type.prototype = Object.create(Object.prototype);
-Type.prototype.toString = function(name, lastPrec) {
- var result = ''
- if (this.name) {
- result = this.name;
- if (name) {
- result += ' ' + name;
- }
- return result;
- }
- name = name || '';
- var prec = this.prec;
-
- if (prec && lastPrec && prec > lastPrec) {
- name = '(' + name + ')';
- }
-
- if (this.kind == 'ptr') {
- return this.pointee.toString('*' + result + name, prec);
- } else if (this.kind == 'array') {
- return this.element.toString(result + '[]', prec);
- } else if (this.kind == 'fn') {
- name += '(';
- if (this.params.length > 0) {
- var paramNames = [];
- for (var i = 0; i < this.params.length; ++i) {
- paramNames.push(this.params[i].toString());
- }
- name += paramNames.join(', ');
- }
- name += ')';
- return this.result.toString(name, prec);
- } else {
- throw new Error('unknown type kind');
- }
-};
-Type.prototype.load = function() {
- throw new Error(this.toString() + " cannot be loaded");
-};
-Type.prototype.store = function() {
- throw new Error(this.toString() + " cannot be stored");
-};
-Type.prototype.call = function() {
- throw new Error(this.toString() + " cannot be called");
-};
-
-function PrimitiveType(name, size, sig, min, max) {
- Type.call(this, name);
- this.size = size;
- this.sig = sig;
- this.min = min;
- this.max = max;
-}
-PrimitiveType.prototype = Object.create(Type.prototype);
-PrimitiveType.prototype.kind = 'primitive'
-PrimitiveType.prototype.primitive = true;
-PrimitiveType.prototype.checkRange = function(value) {
- if (value < this.min || value > this.max) {
- throw new Error('value out of range: ' + value + ' not in [' + this.min + ',' +
- this.max + ']');
- }
-};
-PrimitiveType.prototype.toJS = function(value) {
- return value;
-};
-PrimitiveType.prototype.initAccessors = function(value, addr) {
- var type = this;
- value.load = function() { return type.toJS(type.load(addr)); };
- value.store = function(value) { type.store(addr, type.fromJS(value)); };
-};
-
-// TODO(binji): figure out what the signature chars actually are
-var Void = new PrimitiveType('Void', 0, 'v');
-var Bool = new PrimitiveType('Bool', 1, 'i');
-var I8 = new PrimitiveType('I8', 1, 'i', -128, 127);
-var I16 = new PrimitiveType('I16', 2, 'i', -32768, 32767);
-var I32 = new PrimitiveType('I32', 4, 'i', -0x80000000, 0x7fffffff);
-var U8 = new PrimitiveType('U8', 1, 'i', 0, 255);
-var U16 = new PrimitiveType('U16', 2, 'i', 0, 65535);
-var U32 = new PrimitiveType('U32', 4, 'i', 0, 0xffffffff);
-var U64 = new PrimitiveType('U64', 8, 'i');
-var F32 = new PrimitiveType('F32', 4, 'f');
-var F64 = new PrimitiveType('F64', 8, 'd');
-
-Void.fromJS = function(value) {}
-Bool.fromJS = function(value) { return !!value; };
-I8.fromJS = function(value) { this.checkRange(value); return value|0; };
-I16.fromJS = function(value) { this.checkRange(value); return value|0; };
-I32.fromJS = function(value) { this.checkRange(value); return value|0; };
-U8.fromJS = function(value) { this.checkRange(value); return value>>>0; };
-U16.fromJS = function(value) { this.checkRange(value); return value>>>0; };
-U32.fromJS = function(value) { this.checkRange(value); return value>>>0; };
-U64.fromJS = function(value) { throw new Error('u64 not yet supported'); };
-F32.fromJS = function(value) { return Math.fround(value); };
-F64.fromJS = function(value) { return +value; };
-
-Bool.toJS = function(value) { return value ? true : false; };
-
-Bool.load = function(addr) { return loadu8(addr); };
-I8.load = function(addr) { return loadi8(addr); };
-I16.load = function(addr) { return loadi16(addr); };
-I32.load = function(addr) { return loadi32(addr); };
-U8.load = function(addr) { return loadu8(addr); };
-U16.load = function(addr) { return loadu16(addr); };
-U32.load = function(addr) { return loadu32(addr); };
-U64.load = function(addr) { throw new Error('u64 not yet supported'); };
-F32.load = function(addr) { return loadf32(addr); };
-F64.load = function(addr) { return loadf64(addr); };
-
-Bool.store = function(addr, value) { return storeu8(addr, value); };
-I8.store = function(addr, value) { return storei8(addr, value); };
-I16.store = function(addr, value) { return storei16(addr, value); };
-I32.store = function(addr, value) { return storei32(addr, value); };
-U8.store = function(addr, value) { return storeu8(addr, value); };
-U16.store = function(addr, value) { return storeu16(addr, value); };
-U32.store = function(addr, value) { return storeu32(addr, value); };
-U64.store = function(addr, value) { throw new Error('u64 not yet supported'); };
-F32.store = function(addr, value) { return storef32(addr, value); };
-F64.store = function(addr, value) { return storef64(addr, value); };
-
-function Alias(name, type) {
- var alias = Object.create(type);
- alias.name = name;
- return alias;
-}
-
-function PtrType(type) {
- Type.call(this);
- this.pointee = type;
-}
-PtrType.map = {};
-PtrType.prototype = Object.create(Type.prototype);
-PtrType.prototype.kind = 'ptr';
-PtrType.prototype.prec = 1;
-PtrType.prototype.primitive = true;
-PtrType.prototype.sig = 'i'
-PtrType.prototype.size = 4;
-PtrType.prototype.fromJS = function(value) {
- if (value === null) {
- return 0;
- }
- Value.$check(value);
- Type.check(this, value.$ptrType);
- return value.$addr;
-};
-PtrType.prototype.toJS = function(value) {
- if (value == 0) {
- return null;
- }
- return new Value(this.pointee, value);
-};
-PtrType.prototype.initAccessors = function(value, addr) {
- var type = this;
- value.load = function() { return type.toJS(loadu32(addr)); };
- value.store = function(value) { storeu32(addr, type.fromJS(value)); };
-};
-
-function Ptr(type) {
- if (type.id in PtrType.map) {
- return PtrType.map[type.id];
- }
- var result = new PtrType(type);
- PtrType.map[type.id] = result;
- return result;
-}
-
-var VoidPtr = Ptr(Void);
-var ArrayLen = Alias('ArrayLen', U32);
-var BufLen = Alias('BufLen', U32);
-var BufPtr = Alias('BufPtr', VoidPtr);
-var Str = Alias('Str', Ptr(U8));
-var StrLen = Alias('StrLen', U32);
-var StrPtr = Alias('StrPtr', Ptr(U8));
-var UserData = Alias('UserData', VoidPtr);
-
-Str.toJS = function(addr) { return loadcstr(addr); };
-Str.initAccessors = function(value, addr) {
- value.load = function() { return loadcstr(loadu32(addr)); }
-};
-
-function ArrayType(type) {
- Type.call(this);
- this.element = type;
-}
-ArrayType.map = {};
-ArrayType.prototype = Object.create(Type.prototype);
-ArrayType.prototype.kind = 'ptr';
-ArrayType.prototype.prec = 2;
-ArrayType.prototype.primitive = true;
-ArrayType.prototype.sig = 'i'
-ArrayType.prototype.size = 4;
-ArrayType.prototype.initAccessors = function(value, arrayAddr) {
- var type = this;
- value.index = function(index) {
- return new Value(type.element, arrayAddr + index * type.element.size);
- };
-};
-
-function ArrayPtr(type) {
- if (type.id in ArrayType.map) {
- return ArrayType.map[type.id];
- }
- var result = new ArrayType(type);
- ArrayType.map[type.id] = result;
- return result;
-}
-
-function FnType(result, params) {
- if (!result.primitive) {
- throw new Error(result.toString() + " is not a primitive type");
- }
- for (var i = 0; i < params.length; ++i) {
- var param = params[i];
- if (!param.primitive) {
- throw new Error(param.toString() + " is not a primitive type");
- }
- }
- Type.call(this);
- this.result = result;
- this.params = params;
- this.funcSig = this.generateSig();
-}
-FnType.generateKey = function(result, params) {
- var key = result.id + ',';
- for (var i = 0; i < params.length; ++i) {
- key += params[i].id + ',';
- }
- return key;
-};
-FnType.map = {};
-FnType.prototype = Object.create(Type.prototype);
-FnType.prototype.kind = 'fn';
-FnType.prototype.prec = 3;
-FnType.prototype.primitive = true;
-FnType.prototype.sig = 'i'
-FnType.prototype.size = 4;
-FnType.prototype.generateSig = function() {
- var result = this.result.sig;
- for (var i = 0; i < this.params.length; ++i) {
- result += this.params[i].sig;
- }
- return result;
-};
-FnType.prototype.argsFromJS = function(inArgs) {
- if (inArgs.length != this.params.length) {
- throw new Error("argument count mismatch: expecting " + this.params.length +
- ", got " + inArgs.length);
- }
- var outArgs = [];
- for (var i = 0; i < inArgs.length; ++i) {
- outArgs.push(this.params[i].fromJS(inArgs[i]));
- }
- return outArgs;
-};
-FnType.prototype.argsToJS = function(inArgs) {
- var outArgs = [];
- for (var i = 0; i < inArgs.length; ++i) {
- outArgs.push(this.params[i].toJS(inArgs[i]));
- }
- return outArgs;
-};
-FnType.prototype.define = function(name) {
- var type = this;
- return function() {
- var result = Module[name].apply(Module, type.argsFromJS(arguments));
- return type.result.toJS(result);
- };
-};
-FnType.prototype.initAccessors = function(value, addr) {
- var type = this;
- value.load = function() { return new FnValue(type, loadu32(addr)); };
- value.store = function(value) {
- if (!(value instanceof FnValue)) {
- throw new Error('fn value ' + value + ' not instanceof FnValue');
- }
- Type.check(type, value.$type);
- return storeu32(addr, value.$index);
- };
- value.call = function() {
- var result = Runtime.dynCall(type.funcSig, loadu32(addr),
- type.argsFromJS(arguments));
- return type.result.toJS(result);
- };
-};
-
-function Fn(result, params) {
- var key = FnType.generateKey(result, params);
- if (key in FnType.map) {
- return FnType.map[key];
- }
- var result = new FnType(result, params);
- FnType.map[key] = result;
- return result;
-}
-
-function Field(name, type, offset) {
- this.name = name;
- this.type = type;
- this.offset = offset;
-}
-Field.prototype = Object.create(Object.prototype);
-Field.prototype.initAccessors = function(value, structAddr) {
- value[this.name] = new Value(this.type, structAddr + this.offset);
-};
-
-function StructType(name) {
- Type.call(this, name);
- this.fields = {};
-}
-StructType.prototype = Object.create(Type.prototype);
-StructType.prototype.kind = 'struct';
-StructType.prototype.primitive = false;
-StructType.prototype.define = function(cName, fieldTypes) {
- this.cName = cName;
- this.size = sizeof(cName);
- for (fieldName in fieldTypes) {
- var type = fieldTypes[fieldName];
- var offset = offsetof(cName, fieldName);
- this.fields[fieldName] = new Field(fieldName, type, offset);
- }
-};
-StructType.prototype.describe = function() {
- var result = 'struct ' + this.name + ' {\n';
- var lines = [];
- for (fieldName in this.fields) {
- var field = this.fields[fieldName];
- lines.push(' ' + field.type.toString(fieldName) + ';');
- }
- result += lines.join('\n');
- result += '\n};';
- return result;
-};
-StructType.prototype.initAccessors = function(value, addr) {
- var type = this;
- for (fieldName in this.fields) {
- var field = this.fields[fieldName];
- field.initAccessors(value, addr);
- }
-};
-
-function Struct(name) {
- return new StructType(name);
-}
-
-// Values //////////////////////////////////////////////////////////////////////
-
-function Value(type, addr) {
- this.$type = type;
- this.$ptrType = Ptr(type);
- this.$addr = addr;
- type.initAccessors(this, this.$addr);
-}
-Value.$at = function(type, addr) { return new Value(type, addr); };
-Value.$malloc = function(type) { return new Value(type, mallocz(type.size)); };
-Value.$check = function(value) {
- if (!(value instanceof Value)) {
- throw new Error('value ' + value + ' not instanceof Value');
- }
-};
-Value.prototype = Object.create(Object.prototype);
-Value.prototype.toString = function() {
- return '<' + this.$type + '>@' + this.$addr;
-};
-Value.prototype.$free = function() { free(this.$addr); };
-
-function FnValue(type, f) {
- if (!(type instanceof FnType)) {
- throw new Error('type ' + type + ' not instanceof FnType');
- }
- this.$type = type;
- if (typeof f == 'function') {
- if (f.length != type.params.length) {
- throw new Error("argument count mismatch: expecting " + type.params.length +
- ", got " + f.length);
- }
- var wrapped = function() {
- return type.result.fromJS(f.apply(null, type.argsToJS(arguments)));
- };
-
- this.$index = Runtime.addFunction(wrapped);
- this.$owned = true;
- } else {
- // assume that if is the table index.
- this.$index = f | 0;
- this.$owned = false;
- }
-}
-FnValue.prototype = Object.create(Object.prototype);
-FnValue.prototype.toString = function() {
- return '<' + this.type + '>@' + this.$index;
-};
-FnValue.prototype.$destroy = function() {
- if (this.$owned) {
- Runtime.removeFunction(this.$index);
- }
-};
-
-function StrValue(addr) {
- Value.call(this, Str.pointee, addr);
-}
-StrValue.$at = function(addr) { return new StrValue(addr); }
-StrValue.$mallocCStr = function(s) {
- var addr = malloc(s.length + 1);
- Module.writeAsciiToMemory(s, addr);
- return new StrValue(addr);
-}
-StrValue.prototype = Object.create(Value.prototype);
-StrValue.prototype.toString = function() {
- return '<Str>@' + this.$addr;
-};
-
-function BufferValue(addr, size) {
- Value.call(this, VoidPtr.pointee, addr);
- this.size = size;
-}
-BufferValue.$malloc = function(buf) {
- var addr;
- var size;
- if (buf instanceof ArrayBuffer) {
- size = buf.byteLength;
- addr = malloc(size);
- HEAPU8.set(new Uint8Array(buf), addr);
- } else if (ArrayBuffer.isView(buf)) {
- size = buf.byteLength;
- addr = malloc(size);
- HEAPU8.set(new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength),
- addr);
- } else if (typeof buf == 'string') {
- size = buf.length;
- addr = malloc(size);
- Module.writeAsciiToMemory(buf, addr, true); // don't null-terminate
- } else {
- throw new Error('unknown buffer type: ' + buf);
- }
- return new BufferValue(addr, size);
-};
-BufferValue.prototype = Object.create(Value.prototype);
-BufferValue.prototype.toString = function() {
- return '<Buffer>@' + this.$addr + ', ' + this.size + ' bytes';
-};
-
-// Wasm enums //////////////////////////////////////////////////////////////////
-
-// WasmResult
-var OK = 0;
-var ERROR = 1;
-
-// Wasm low-level types ////////////////////////////////////////////////////////
-
-var I = (function() {
-
-var Allocator = Struct('Allocator');
-var AstLexer = Struct('AstLexer');
-var BinaryErrorHandler = Struct('BinaryErrorHandler');
-var Location = Struct('Location');
-var MemoryWriter = Struct('MemoryWriter');
-var OutputBuffer = Struct('OutputBuffer');
-var ReadBinaryOptions = Struct('ReadBinaryOptions');
-var Script = Struct('Script');
-var SourceErrorHandler = Struct('SourceErrorHandler');
-var StackAllocator = Struct('StackAllocator');
-var Stream = Struct('Stream');
-var StrSlice = Struct('StrSlice');
-var WriteBinaryOptions = Struct('WriteBinaryOptions');
-var Writer = Struct('Writer');
-
-var BinaryErrorHandlerCallback = Fn(Void, [U32, Str, UserData]);
-var SourceErrorHandlerCallback =
- Fn(Void, [Ptr(Location), Str, StrPtr, StrLen, U32, UserData]);
-
-Allocator.define('allocator', {
- alloc: Fn(VoidPtr, [Ptr(Allocator), U32, U32, Str, I32]),
- realloc: Fn(VoidPtr, [Ptr(Allocator), VoidPtr, U32, U32, Str, I32]),
- free: Fn(VoidPtr, [Ptr(Allocator), VoidPtr, Str, I32]),
- destroy: Fn(Void, [Ptr(Allocator)]),
- mark: Fn(I32, [Ptr(Allocator)]),
- reset_to_mark: Fn(Void, [Ptr(Allocator), I32]),
- print_stats: Fn(Void, [Ptr(Allocator)]),
-});
-
-BinaryErrorHandler.define('binary_error_handler', {
- on_error: BinaryErrorHandlerCallback,
- user_data: UserData,
-});
-
-Location.define('location', {
- filename: Str,
- line: U32,
- first_column: U32,
- last_column: U32,
-});
-
-MemoryWriter.define('memory_writer', {
- base: Writer,
- buf: OutputBuffer,
-});
-
-OutputBuffer.define('output_buffer', {
- allocator: Allocator,
- start: BufPtr,
- size: BufLen,
- capacity: U32,
-});
-
-ReadBinaryOptions.define('read_binary_options', {
- read_debug_names: Bool,
-});
-
-Script.define('script');
-
-SourceErrorHandler.define('source_error_handler', {
- on_error: SourceErrorHandlerCallback,
- source_line_max_length: U32,
- user_data: UserData,
-});
-
-StackAllocator.define('stack_allocator', {
- allocator: Allocator,
-});
-
-Stream.define('stream', {
- writer: Ptr(Writer),
- result: U32,
- offset: U32,
- log_stream: Ptr(Stream),
-});
-
-StrSlice.define('string_slice', {
- start: StrPtr,
- length: StrLen,
-});
-
-WriteBinaryOptions.define('write_binary_options', {
- log_stream: Ptr(Stream),
- canonicalize_lebs: Bool,
- write_debug_names: Bool,
-});
-
-Writer.define('writer', {
- write_data: Fn(I32, [U32, BufPtr, BufLen, UserData]),
- move_data: Fn(I32, [U32, U32, U32, UserData]),
-});
-
-// Wasm low-level functions ////////////////////////////////////////////////////
-
-var checkAst = Fn(I32, [Ptr(Allocator), Ptr(AstLexer), Ptr(Script), Ptr(SourceErrorHandler)]).define('_wasm_check_ast');
-var closeMemWriter = Fn(Void, [Ptr(MemoryWriter)]).define('_wasm_close_mem_writer');
-var defaultBinaryErrorCallback = BinaryErrorHandlerCallback.define('_wasm_default_binary_error_callback');
-var defaultSourceErrorCallback = SourceErrorHandlerCallback.define('_wasm_default_source_error_callback');
-var destroyAstLexer = Fn(Void, [Ptr(AstLexer)]).define('_wasm_destroy_ast_lexer');
-var destroyOutputBuffer = Fn(Void, [Ptr(OutputBuffer)]).define('_wasm_destroy_output_buffer');
-var destroyScript = Fn(Void, [Ptr(Script)]).define('_wasm_destroy_script');
-var destroyStackAllocator = Fn(Void, [Ptr(StackAllocator)]).define('_wasm_destroy_stack_allocator');
-var getLibcAllocator = Fn(Ptr(Allocator), []).define('_wasm_get_libc_allocator');
-var initMemWriter = Fn(I32, [Ptr(Allocator), Ptr(MemoryWriter)]).define('_wasm_init_mem_writer');
-var initStackAllocator = Fn(Void, [Ptr(StackAllocator), Ptr(Allocator)]).define('_wasm_init_stack_allocator');
-var initStream = Fn(Void, [Ptr(Stream), Ptr(Writer), Ptr(Stream)]).define('_wasm_init_stream');
-var newAstBufferLexer = Fn(Ptr(AstLexer), [Ptr(Allocator), Str, BufPtr, BufLen]).define('_wasm_new_ast_buffer_lexer');
-var parseAst = Fn(I32, [Ptr(AstLexer), Ptr(Script), Ptr(SourceErrorHandler)]).define('_wasm_parse_ast');
-var writeBinaryScript = Fn(I32, [Ptr(Allocator), Ptr(Writer), Ptr(Script), Ptr(WriteBinaryOptions)]).define('_wasm_write_binary_script');
-
-return {
- // Types
- Allocator: Allocator,
- AstLexer: AstLexer,
- BinaryErrorHandler: BinaryErrorHandler,
- Location: Location,
- MemoryWriter: MemoryWriter,
- OutputBuffer: OutputBuffer,
- ReadBinaryOptions: ReadBinaryOptions,
- Script: Script,
- SourceErrorHandler: SourceErrorHandler,
- StackAllocator: StackAllocator,
- Stream: Stream,
- StrSlice: StrSlice,
- WriteBinaryOptions: WriteBinaryOptions,
- Writer: Writer,
-
- // Functions
- checkAst: checkAst,
- closeMemWriter: closeMemWriter,
- defaultBinaryErrorCallback: defaultBinaryErrorCallback,
- defaultSourceErrorCallback: defaultSourceErrorCallback,
- destroyAstLexer: destroyAstLexer,
- destroyOutputBuffer: destroyOutputBuffer,
- destroyScript: destroyScript,
- destroyStackAllocator: destroyStackAllocator,
- getLibcAllocator: getLibcAllocator,
- initMemWriter: initMemWriter,
- initStackAllocator: initStackAllocator,
- initStream: initStream,
- newAstBufferLexer: newAstBufferLexer,
- parseAst: parseAst,
- writeBinaryScript: writeBinaryScript,
-};
-
-})();
-
-// Helpers for friendly objects ////////////////////////////////////////////////
-
-function define$From(obj) {
- obj.$from = function($) {
- var o = Object.create(obj.prototype);
- o.$ = $;
- return o;
- };
-}
-
-function definePrimitiveGetter(proto, name, cName) {
- cName = cName || name;
- Object.defineProperty(proto, name, {
- get: function() { return this.$[cName].load(); }
- });
-}
-
-function definePrimitiveGetterSetter(proto, name, cName) {
- cName = cName || name;
- Object.defineProperty(proto, name, {
- get: function() { return this.$[cName].load(); },
- set: function(value) { this.$[cName].store(value); },
- });
-}
-
-function defineStrGetter(proto, name, cName) {
- cName = cName || name;
- Object.defineProperty(proto, name, {
- get: function() {
- return this.$[cName].load();
- }
- });
-}
-
-// Get a StrSlice, given a pointer and length
-function defineStrSliceGetter(proto, name, ptrName, lenName) {
- Object.defineProperty(proto, name, {
- get: function() {
- var offset = this.$[ptrName].load();
- var length = this.$[lenName].load();
- return loadstrslice(offset.$addr, length);
- }
- });
-}
-
-// Get a StrSlice, given a StrSlice object
-function defineStrSliceObjGetter(proto, name, cName) {
- cName = cName || name;
- Object.defineProperty(proto, name, {
- get: function() {
- var offset = this.$[cName].start.load();
- var length = this.$[cName].length.load();
- return loadstrslice(offset.$addr, length);
- }
- });
-}
-
-function defineBufferGetter(proto, name, ptrName, lenName) {
- Object.defineProperty(proto, name, {
- get: function() {
- var offset = this.$[ptrName].load();
- var length = this.$[lenName].load();
- return loadbuffer(offset.$addr, length);
- }
- });
-}
-
-// Friendly objects ////////////////////////////////////////////////////////////
-
-// Allocator
-function Allocator() {
- this.$ = null;
-}
-define$From(Allocator);
-Allocator.prototype = Object.create(Object.prototype);
-
-// StackAllocator
-function StackAllocator(fallbackAllocator) {
- this.$ = Value.$malloc(I.StackAllocator);
- I.initStackAllocator(this.$, fallbackAllocator.$);
- this.allocator = Allocator.$from(this.$.allocator);
-}
-StackAllocator.prototype = Object.create(Object.prototype);
-StackAllocator.prototype.$destroy = function() {
- I.destroyStackAllocator(this.$);
- this.$.$free();
-};
-
-// LibcAllocator
-LibcAllocator = Allocator.$from(I.getLibcAllocator());
-
-// Writer
-function Writer(writeData, moveData) {
- this.$ = Value.$malloc(I.Writer);
- this.$writeData = new FnValue(I.Writer.fields.write_data.type, writeData);
- this.$moveData = new FnValue(I.Writer.fields.move_data.type, moveData);
- this.$.write_data.store(this.$writeData);
- this.$.move_data.store(this.$moveData);
-}
-define$From(Writer);
-Writer.prototype = Object.create(Object.prototype);
-Writer.prototype.$destroy = function() {
- this.$moveData.$destroy();
- this.$writeData.$destroy();
- this.$.$free();
-};
-
-// MemoryWriter
-function MemoryWriter(allocator) {
- this.$ = Value.$malloc(I.MemoryWriter);
- var result = I.initMemWriter(allocator.$, this.$);
- if (result != OK) {
- throw new Error('unable to initialize MemoryWriter');
- }
- this.writer = Writer.$from(this.$.base);
- this.buf = OutputBuffer.$from(this.$.buf);
-}
-MemoryWriter.prototype = Object.create(MemoryWriter.prototype);
-MemoryWriter.prototype.$destroy = function() {
- I.closeMemWriter(this.$);
- this.$.$free();
-};
-
-// OutputBuffer
-function OutputBuffer() {
- this.$ = null;
-}
-define$From(OutputBuffer);
-OutputBuffer.prototype = Object.create(Object.prototype);
-defineBufferGetter(OutputBuffer.prototype, 'buf', 'start', 'size');
-defineStrSliceGetter(OutputBuffer.prototype, 'bufStr', 'start', 'size');
-definePrimitiveGetter(OutputBuffer.prototype, 'size');
-definePrimitiveGetter(OutputBuffer.prototype, 'capacity');
-OutputBuffer.prototype.$destroy = function() {
- I.destroyOutputBuffer(this.$);
- this.$.$free();
-};
-
-// Stream
-function Stream(writer, logStream) {
- this.$ = Value.$malloc(I.Stream);
- I.initStream(this.$, writer.$, logStream ? logStream.$ : null);
-}
-Stream.prototype = Object.create(Object.prototype);
-definePrimitiveGetter(Stream.prototype, 'offset');
-definePrimitiveGetter(Stream.prototype, 'result');
-Stream.prototype.$destroy = function() {
- this.$.$free();
-};
-
-// StringStream
-function StringStream() {
- this.$writer = new MemoryWriter(LibcAllocator);
- Stream.call(this, this.$writer.writer, null);
-}
-StringStream.prototype = Object.create(Object.prototype);
-Object.defineProperty(StringStream.prototype, 'string', {
- get: function() {
- return this.$writer.buf.bufStr;
- }
-});
-StringStream.prototype.$destroy = function() {
- Stream.prototype.$destroy.call(this);
- this.$writer.$destroy();
-};
-
-// parseAst
-function parseAst(allocator, filename, buffer) {
- var sourceLineMaxLength = 80;
- var astLexer = new AstLexer(allocator, filename, buffer);
- var errorHandler = new SourceErrorHandler(sourceLineMaxLength);
- var script = new Script();
- var result = I.parseAst(astLexer.$, script.$, errorHandler.$);
- script.$allocator = allocator;
- script.$astLexer = astLexer;
- script.$errorHandler = errorHandler;
- if (result != OK) {
- script.$destroy();
- throw new Error('parseAst failed:\n' + errorHandler.errorMessage);
- }
- return script;
-}
-
-// AstLexer
-function AstLexer(allocator, filename, buffer) {
- this.$filename = StrValue.$mallocCStr(filename);
- this.$buffer = BufferValue.$malloc(buffer);
- this.$ = I.newAstBufferLexer(allocator.$, this.$filename, this.$buffer,
- this.$buffer.size);
- if (this.$ === null) {
- this.$buffer.$free();
- this.$filename.$free();
- throw new Error('unable to create AstLexer');
- }
-}
-AstLexer.prototype = Object.create(Object.prototype);
-AstLexer.prototype.$destroy = function() {
- I.destroyAstLexer(this.$);
- this.$.$free();
- this.$buffer.$free();
- this.$filename.$free();
-}
-
-// SourceErrorHandler
-function SourceErrorHandler(sourceLineMaxLength) {
- this.$ = Value.$malloc(I.SourceErrorHandler);
- var wrapper = function(loc, error, sourceLine, sourceLineLength,
- sourceLineColumnOffset, userData){
- loc = Location.$from(loc);
- sourceLine = loadstrslice(sourceLine.$addr, sourceLineLength);
-
- var lines = [
- loc.filename + ':' + loc.line + ':' + loc.firstColumn,
- error
- ];
- if (sourceLine.length > 0) {
- var numSpaces = loc.firstColumn - 1 - sourceLineColumnOffset;
- var numCarets =
- Math.min(loc.lastColumn - loc.firstColumn, sourceLine.length);
- lines.push(sourceLine);
- lines.push(' '.repeat(numSpaces) + '^'.repeat(numCarets));
- }
- this.errorMessage += lines.join('\n') + '\n';
- }.bind(this);
- this.$callback =
- new FnValue(I.SourceErrorHandler.fields.on_error.type, wrapper);
- this.$.on_error.store(this.$callback);
- this.$.source_line_max_length.store(sourceLineMaxLength);
- this.errorMessage = '';
-}
-SourceErrorHandler.prototype = Object.create(Object.prototype);
-SourceErrorHandler.prototype.$destroy = function() {
- this.$callback.$destroy();
- this.$.$free();
-};
-
-// Location
-function Location() {
- this.$ = null;
-}
-define$From(Location);
-Location.prototype = Object.create(Object.prototype);
-defineStrGetter(Location.prototype, 'filename');
-definePrimitiveGetter(Location.prototype, 'line');
-definePrimitiveGetter(Location.prototype, 'firstColumn', 'first_column');
-definePrimitiveGetter(Location.prototype, 'lastColumn', 'last_column');
-Location.prototype.$destroy = function() {
- this.$.$free();
-};
-
-// Script
-function Script() {
- this.$ = Value.$malloc(I.Script);
- this.$allocator = null;
- this.$astLexer = null;
- this.$errorHandler = null;
-}
-Script.prototype = Object.create(Object.prototype);
-Script.prototype.check = function() {
- var result = I.checkAst(
- this.$allocator.$, this.$astLexer.$, this.$, this.$errorHandler.$);
- if (result != OK) {
- throw new Error('check failed:\n' + this.$errorHandler.errorMessage);
- }
-};
-Script.prototype.toBinary = function(options) {
- var mw = new MemoryWriter(this.$allocator);
- options = new WriteBinaryOptions(this.$allocator, options || {});
- try {
- var result =
- I.writeBinaryScript(this.$allocator.$, mw.writer.$, this.$, options.$);
- if (result != OK) {
- throw new Error('writeBinaryScript failed');
- }
- return {buffer: mw.buf.buf, log: options.log}
- } finally {
- options.$destroy();
- mw.$destroy();
- }
-};
-Script.prototype.$destroy = function() {
- I.destroyScript(this.$);
- if (this.$errorHandler) this.$errorHandler.$destroy();
- if (this.$astLexer) this.$astLexer.$destroy();
- this.$.$free();
-};
-
-// WriteBinaryOptions
-function WriteBinaryOptions(allocator, options) {
- this.$ = Value.$malloc(I.WriteBinaryOptions);
- if (options.log) {
- this.$logStream = new StringStream();
- this.$.log_stream.store(this.$logStream.$);
- } else {
- this.$logStream = null;
- this.$.log_stream.store(null);
- }
- var optBool = function(v, def) { return v === undefined ? def : v; };
- this.$.canonicalize_lebs.store(optBool(options.canonicalizeLebs, true));
- this.$.write_debug_names.store(optBool(options.writeDebugNames, false));
-}
-WriteBinaryOptions.prototype = Object.create(Object.prototype);
-Object.defineProperty(WriteBinaryOptions.prototype, 'log', {
- get: function() {
- return this.$logStream ? this.$logStream.string : '';
- }
-});
-WriteBinaryOptions.prototype.$destroy = function() {
- if (this.$logStream) {
- this.$logStream.$destroy();
- }
- this.$.$free();
-};
-
-// BinaryErrorHandler
-function BinaryErrorHandler() {
- this.$ = Value.$malloc(I.BinaryErrorHandler);
- this.$callback = new FnValue(
- I.BinaryErrorHandler.fields.on_error.type,
- function(offset, error, userData) {
- this.errorMessage += '@0x' + offset.toString(16) + ': ' + error + '\n';
- }.bind(this));
- this.$.on_error.store(this.$callback);
- this.$.user_data.store(null);
- this.errorMessage = '';
-}
-BinaryErrorHandler.prototype = Object.create(Object.prototype);
-BinaryErrorHandler.prototype.$destroy = function() {
- this.$callback.$destroy();
- this.$.$free();
-};
-
-// ReadBinaryOptions
-function ReadBinaryOptions(options) {
- this.$ = Value.$malloc(I.ReadBinaryOptions);
- this.$.read_debug_names.store(options.readDebugNames || false);
-}
-ReadBinaryOptions.prototype = Object.create(Object.prototype);
-ReadBinaryOptions.prototype.$destroy = function() {
- this.$.$free();
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-var resolve = wasm.$resolve;
-
-wasm = {
- ready: wasm.ready,
-
- // Types
- LibcAllocator: LibcAllocator,
- StackAllocator: StackAllocator,
-
- // Functions
- parseAst: parseAst,
-};
-
-resolve();
-
-};
-
-/*
-wasm.ready.then(function() {
- if (false) {
- try {
- var sa = new wasm.StackAllocator(wasm.LibcAllocator);
- var a = sa.allocator;
- var data = '(module\n (func (result i32)\n (i32.const 1)))';
- var s = wasm.parseAst(a, 'foo.wast', data);
- s.check();
- var output = s.toBinary({log: true});
- print('log output:\n' + output.log);
- print('output:\n' + output.buffer);
- } catch(e) {
- print('ERROR' + (e.stack ? e.stack : e));
- }
- if (s) s.$destroy();
- if (sa) sa.$destroy();
- }
-
- if (false) {
- try {
- var a = new wasm.StackAllocator(wasm.LibcAllocator);
- var ma = wasm.LibcAllocator;
- var buf = new Uint8Array([
- 0, 97, 115, 109, 11, 0, 0, 0, 4, 116, 121, 112, 101, 8, 2, 64,
- 1, 1, 0, 64, 0, 0, 6, 105, 109, 112, 111, 114, 116, 12, 1, 0,
- 3, 115, 116, 100, 5, 112, 114, 105, 110, 116, 8, 102, 117, 110, 99, 116,
- 105, 111, 110, 2, 1, 1, 6, 101, 120, 112, 111, 114, 116, 4, 1, 0,
- 1, 102, 4, 99, 111, 100, 101, 8, 1, 6, 0, 16, 42, 24, 1, 0,
- ]);
- var im = wasm.readInterpreterModule(a.allocator, ma, buf, {});
- var it = new wasm.InterpreterThread(a.allocator, im);
- im.run(it, 1000, 0);
- } catch(e) {
- print('ERROR:' + (e.stack ? e.stack : e));
- }
- if (it) it.$destroy();
- if (im) im.$destroy();
- if (a) a.$destroy();
- }
-
- if (true) {
- try {
- var sa = new wasm.StackAllocator(wasm.LibcAllocator);
- var a = sa.allocator;
- var source = `
- (module
- (func $test (result i32)
- (call $fib (i32.const 4)))
- (func $fib (param $p i32) (result i32)
- (local $a i32)
- (local $b i32)
- (local $t i32)
- (set_local $a (i32.const 1))
- (set_local $b (i32.const 1))
- (loop $exit $cont
- (set_local $p (i32.sub (get_local $p) (i32.const 1)))
- (br_if $exit (i32.le_s (get_local $p) (i32.const 0)))
- (set_local $t (get_local $b))
- (set_local $b (i32.add (get_local $a) (get_local $b)))
- (set_local $a (get_local $t))
- (br $cont))
- (return (get_local $b)))
- (export "test" $test))
- `;
- var s = wasm.parseAst(a, 'foo.wast', source);
- s.check();
- var output = s.toBinary();
- var im = wasm.readInterpreterModule(a, wasm.LibcAllocator, output.buffer);
- if (true) {
- print('disassemble:\n' + im.disassemble(0, 1000));
- }
- if (true) {
- var it = new wasm.InterpreterThread(a, im);
- print('running');
- do {
- print(im.tracePC(it).trimRight());
- } while (im.run(it, 1, 0));
- print('done');
- }
- } catch(e) {
- print('ERROR:' + (e.stack ? e.stack : e));
- }
- if (it) it.$destroy();
- if (im) im.$destroy();
- if (s) s.$destroy();
- if (sa) sa.$destroy();
- }
-
-}).catch(function(error) {
- print('ERROR:' + (error.stack ? error.stack : error));
-});
-*/