diff options
author | Ben Smith <binjimin@gmail.com> | 2017-01-31 17:16:19 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-31 17:16:19 -0800 |
commit | 4fdbb4647c519a42f3e54ed7a858194780ca2ae4 (patch) | |
tree | 3aebad7746c492930c32786061c655bb017fdc81 /src/wasm.js | |
parent | edb3a471bc249855d5ece45dc21ee69af700b19b (diff) | |
download | wabt-4fdbb4647c519a42f3e54ed7a858194780ca2ae4.tar.gz wabt-4fdbb4647c519a42f3e54ed7a858194780ca2ae4.tar.bz2 wabt-4fdbb4647c519a42f3e54ed7a858194780ca2ae4.zip |
Rename all wasm prefixes to wabt (#298)
Diffstat (limited to 'src/wasm.js')
-rw-r--r-- | src/wasm.js | 1145 |
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)); -}); -*/ |