blob: f8818315277f0adf551603dedb7db2b45a559a7d [file] [log] [blame] [edit]
/*
* 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 wabt = wabt || {};
(function (wabt) {
"use strict";
var WABT_OK = 0;
var WABT_ERROR = 1;
/// Allocate memory in the Module.
function malloc(size) {
var addr = Module._malloc(size);
if (addr == 0) {
throw new Error('out of memory');
}
return addr;
}
/// Convert an ArrayBuffer/TypedArray/string into a buffer that can be
/// used by the Module.
function allocateBuffer(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 {addr: addr, size: size};
}
function allocateCString(s) {
var size = s.length;
var addr = malloc(size);
Module.writeAsciiToMemory(s, addr);
return {addr: addr, size: size};
}
/// Lexer
function Lexer(filename, buffer) {
this.filenameObj = allocateCString(filename);
this.bufferObj = allocateBuffer(buffer);
this.addr = Module._wabt_new_wast_buffer_lexer(
this.filenameObj.addr, this.bufferObj.addr, this.bufferObj.size);
}
Lexer.prototype = Object.create(Object.prototype);
Lexer.prototype.destroy = function() {
Module._wabt_destroy_wast_lexer(this.addr);
Module._free(this.bufferObj.addr);
Module._free(this.filenameObj.addr);
};
/// OutputBuffer
function OutputBuffer(addr) {
this.addr = addr;
}
OutputBuffer.prototype = Object.create(Object.prototype);
OutputBuffer.prototype.toTypedArray = function() {
if (!this.addr) {
return null;
}
var addr = Module._wabt_output_buffer_get_data(this.addr);
var size = Module._wabt_output_buffer_get_size(this.addr);
var buffer = new Uint8Array(size);
buffer.set(new Uint8Array(HEAPU8.buffer, addr, size));
return buffer;
};
OutputBuffer.prototype.toString = function() {
if (!this.addr) {
return '';
}
var addr = Module._wabt_output_buffer_get_data(this.addr);
var size = Module._wabt_output_buffer_get_size(this.addr);
return Module.Pointer_stringify(addr, size);
};
OutputBuffer.prototype.destroy = function() {
Module._wabt_destroy_output_buffer(this.addr);
};
/// ErrorHandler
function ErrorHandler() {
this.addr = Module._wabt_new_source_error_handler_buffer();
}
ErrorHandler.prototype = Object.create(Object.prototype);
ErrorHandler.prototype.getMessage = function() {
var addr = Module._wabt_source_error_handler_buffer_get_data(this.addr);
var size = Module._wabt_source_error_handler_buffer_get_size(this.addr);
return Module.Pointer_stringify(addr, size);
}
ErrorHandler.prototype.destroy = function() {
Module._wabt_destroy_source_error_handler_buffer(this.addr);
};
/// parseWast
function parseWast(filename, buffer) {
var lexer = new Lexer(filename, buffer);
var errorHandler = new ErrorHandler();
try {
var parseResult_addr =
Module._wabt_parse_wast(lexer.addr, errorHandler.addr);
var result = Module._wabt_parse_wast_result_get_result(parseResult_addr);
if (result !== WABT_OK) {
throw new Error('parseWast failed:\n' + errorHandler.getMessage());
}
var script_addr =
Module._wabt_parse_wast_result_release_script(parseResult_addr);
var result = new Script(lexer, script_addr);
// Clear lexer so it isn't destroyed below.
lexer = null;
return result;
} finally {
Module._wabt_destroy_parse_wast_result(parseResult_addr);
errorHandler.destroy();
if (lexer) {
lexer.destroy();
}
}
}
/// Script
function Script(lexer, script_addr) {
this.lexer = lexer;
this.script_addr = script_addr;
}
Script.prototype = Object.create(Object.prototype);
Script.prototype.resolveNames = function() {
var errorHandler = new ErrorHandler();
try {
var result = Module._wabt_resolve_names_script(
this.lexer.addr, this.script_addr, errorHandler.addr);
if (result !== WABT_OK) {
throw new Error('resolveNames failed:\n' + errorHandler.getMessage());
}
} finally {
errorHandler.destroy();
}
};
Script.prototype.validate = function() {
var errorHandler = new ErrorHandler();
try {
var result = Module._wabt_validate_script(this.lexer.addr, this.script_addr,
errorHandler.addr);
if (result !== WABT_OK) {
throw new Error('validate failed:\n' + errorHandler.getMessage());
}
} finally {
errorHandler.destroy();
}
};
Script.prototype.toBinary = function(options) {
var log = options.log || false;
var canonicalize_lebs = options.canonicalize_lebs || true;
var relocatable = options.relocatable || false;
var write_debug_names = options.write_debug_names || false;
var writeBinaryResult_addr = Module._wabt_write_binary_module(
this.script_addr, log, canonicalize_lebs, relocatable, write_debug_names);
var result = Module._wabt_write_binary_module_result_get_result(
writeBinaryResult_addr);
try {
if (result !== WABT_OK) {
throw new Error('writeBinaryModule failed.');
}
var binaryOutputBuffer = new OutputBuffer(
Module._wabt_write_binary_module_result_release_binary_output_buffer(
writeBinaryResult_addr));
var logOutputBuffer = new OutputBuffer(
Module._wabt_write_binary_module_result_release_log_output_buffer(
writeBinaryResult_addr));
return {
buffer : binaryOutputBuffer.toTypedArray(),
log : logOutputBuffer.toString()
};
} finally {
if (binaryOutputBuffer) {
binaryOutputBuffer.destroy();
}
if (logOutputBuffer) {
logOutputBuffer.destroy();
}
Module._wabt_destroy_write_binary_module_result(writeBinaryResult_addr);
}
};
Script.prototype.destroy = function() {
Module._wabt_destroy_script(this.script_addr);
this.lexer.destroy();
};
wabt.ready = Promise.resolve();
wabt.parseWast = parseWast;
})(wabt);