CString/CArray was an illusion; Update and test tsconfig files

This commit is contained in:
dcodeIO 2017-12-11 02:03:15 +01:00
parent 0228ab91d9
commit d0b189b437
33 changed files with 477 additions and 509 deletions

13
assembly.d.ts vendored
View File

@ -78,6 +78,8 @@ declare function unreachable(): any; // sic
declare const NaN: f32 | f64;
/** Positive infinity as a 32-bit or 64-bit float depending on context. */
declare const Infinity: f32 | f64;
/** Heap start offset. */
declare const HEAP_START: usize;
/** Determines the byte size of the specified core or class type. Compiles to a constant. */
declare function sizeof<T>(): usize;
/** Changes the type of a value to another one. Useful for casting class instances to their pointer values and vice-versa. */
@ -100,6 +102,13 @@ declare function struct(): any;
// Standard library (not yet implemented)
/// <reference path="./std/carray.d.ts" />
/// <reference path="./std/cstring.d.ts" />
/// <reference path="./std/heap.d.ts" />
interface Array<T> {}
interface Boolean {}
interface Function {}
interface IArguments {}
interface Number {}
interface Object {}
interface RegExp {}
interface String {}

15
assembly.json Normal file
View File

@ -0,0 +1,15 @@
{
"extends": "./tsconfig-base.json",
"compilerOptions": {
"target": "esnext",
"noLib": true,
"types": [],
"rootDirs": [
"./std/assembly",
"./node_modules"
]
},
"files": [
"./assembly.d.ts"
]
}

View File

@ -39,9 +39,13 @@
"scripts": {
"build": "webpack",
"clean": "rm dist/assemblyscript.*",
"test:parser": "ts-node -P src tests/parser",
"test:compiler": "ts-node -P src tests/compiler",
"test": "npm run test:parser && npm run test:compiler"
"test:config": "npm run test:config:assembly --scripts-prepend-node-path && npm run test:config:portable --scripts-prepend-node-path && npm run test:config:src --scripts-prepend-node-path",
"test:config:assembly": "tsc --noEmit -p std/assembly --diagnostics --listFiles",
"test:config:portable": "tsc --noEmit -p std/portable --diagnostics --listFiles",
"test:config:src": "tsc --noEmit -p src --diagnostics --listFiles",
"test:parser": "node tests/parser",
"test:compiler": "node tests/compiler",
"test": "npm run test:config --scripts-prepend-node-path && npm run test:parser --scripts-prepend-node-path && npm run test:compiler --scripts-prepend-node-path"
},
"files": [
"assembly.d.ts",

View File

@ -44,5 +44,100 @@ declare function trunc<T = f32 | f64>(value: T): T;
/** Emits an unreachable operation that results in a runtime error when executed. */
declare function unreachable(): any; // sic
/** Changes the type of a value to another one. Useful for casting class instances to their pointer values and vice-versa. */
declare function changetype<T1,T2>(value: T1): T2;
/** Traps if the specified value evaluates to `false`. */
declare function assert(isTrue: bool): void;
// Portable standard library
// Everything marked @deprecated is a temporary filler. Do not use.
declare const NaN: f32 | f64;
declare const Infinity: f32 | f64;
declare class Array<T> {
[key: number]: T;
length: i32;
constructor(capacity?: i32);
push(value: T): void;
pop(): T;
join(delim: string): string;
slice(from: i32, to?: i32): T[];
splice(index: i32, count: i32): T[];
}
declare class Uint8Array extends Array<u8> {}
declare class Uint16Array extends Array<u16> {}
declare class Uint32Array extends Array<u32> {}
declare class Int8Array extends Array<i8> {}
declare class Int16Array extends Array<i16> {}
declare class Int32Array extends Array<i32> {}
declare class String {
static fromCharCode(ls: i32, hs?: i32): string;
readonly length: i32;
indexOf(subject: string): i32;
charCodeAt(index: i32): i32;
substring(from: i32, to?: i32): string;
startsWith(subject: string): bool;
endsWith(subject: string): bool;
replace(search: string, replacement: string): string;
}
declare class Boolean {}
declare class Number {
toString(radix: i32): string;
}
declare class Object {}
declare class Function {
/** @deprecated */
apply(subject: any): any;
}
declare class RegExp {}
declare interface IArguments {}
declare class Error {
constructor(message: string);
message: string;
}
declare class Symbol {
static iterator: symbol;
}
declare class Set<T> {
constructor(entries?: T[]);
add(value: T): void;
has(value: T): bool;
clear(): void;
[Symbol.iterator](): Iterator<T>;
}
declare class Map<K,V> {
constructor(entries?: [K, V][]);
set(key: K, value: V): void;
has(key: K): bool;
get(key: K): V | null;
clear(): void;
[Symbol.iterator](): Iterator<[K, V]>;
}
declare interface Iterator<T> {}
declare namespace JSON {
/** @deprecated */
function stringify(subject: any): string;
}
declare namespace console {
/** @deprecated */
function log(message: string): void;
}
/** @deprecated */
declare function parseFloat(str: string): f64;

View File

@ -27,3 +27,4 @@ AssertionError.prototype.name = "AssertionError";
AssertionError.prototype.message = "assertion failed";
globalScope["assert"] = function assert(isTrue) { if (!isTrue) throw new AssertionError(); };
globalScope["changetype"] = function changetype(value) { return value; }

22
portable-assembly.json Normal file
View File

@ -0,0 +1,22 @@
{
"extends": "./tsconfig-base.json",
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"downlevelIteration": true,
"preserveConstEnums": true,
"noLib": true,
"types": [],
"rootDirs": [
"./std/portable",
"./node_modules"
],
"allowJs": true
},
"files": [
"./portable-assembly.d.ts",
"./portable-assembly.js",
"./std/portable/heap.d.ts",
"./std/portable/heap.js"
]
}

View File

@ -475,7 +475,7 @@ export class FloatLiteralExpression extends LiteralExpression {
value: f64;
serialize(sb: string[]): void {
sb.push(this.value.toString());
sb.push(this.value.toString(10));
}
}
@ -1030,7 +1030,7 @@ export class BreakStatement extends Statement {
serialize(sb: string[]): void {
if (this.label) {
sb.push("break ");
(<IdentifierExpression>this.label).serialize(name);
(<IdentifierExpression>this.label).serialize(sb);
} else
sb.push("break");
}

View File

@ -85,7 +85,7 @@ export function formatDiagnosticMessage(message: DiagnosticMessage, useColors: b
sb.push(diagnosticCategoryToString(message.category));
if (useColors) sb.push(colorReset);
sb.push(" AS");
sb.push(message.code.toString());
sb.push(message.code.toString(10));
sb.push(": ");
sb.push(message.message);
@ -109,9 +109,9 @@ export function formatDiagnosticMessage(message: DiagnosticMessage, useColors: b
sb.push(" in ");
sb.push(range.source.path);
sb.push("(");
sb.push(line.toString());
sb.push(line.toString(10));
sb.push(",");
sb.push(column.toString());
sb.push(column.toString(10));
sb.push(")");
}
return sb.join("");

View File

@ -60,10 +60,7 @@ declare type BinaryenModuleRef = usize;
declare function _BinaryenModuleCreate(): BinaryenModuleRef;
declare function _BinaryenModuleDispose(module: BinaryenModuleRef): void;
declare type CString = usize;
declare type CArray<T> = usize;
declare type BinaryenLiteral = CArray<u8>;
declare type BinaryenLiteral = usize;
// LLVM C ABI with `out` being a buffer of 16 bytes receiving the BinaryenLiteral struct.
// union value starts at offset 8 due to alignment (?)
@ -218,19 +215,19 @@ declare function _BinaryenAtomicRMWXchg(): BinaryenAtomicRMWOp;
declare type BinaryenExpressionRef = usize;
declare function _BinaryenBlock(module: BinaryenModuleRef, name: CString, children: CArray<BinaryenExpressionRef>, numChildren: BinaryenIndex, type: BinaryenType): BinaryenExpressionRef;
declare function _BinaryenBlock(module: BinaryenModuleRef, name: usize, children: usize, numChildren: BinaryenIndex, type: BinaryenType): BinaryenExpressionRef;
declare function _BinaryenIf(module: BinaryenModuleRef, condition: BinaryenExpressionRef, ifTrue: BinaryenExpressionRef, ifFalse: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenLoop(module: BinaryenModuleRef, name: CString, body: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenBreak(module: BinaryenModuleRef, name: CString, condition: BinaryenExpressionRef, value: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenSwitch(module: BinaryenModuleRef, names: CArray<CString>, numNames: BinaryenIndex, defaultName: CString, condition: BinaryenExpressionRef, value: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenCall(module: BinaryenModuleRef, target: CString, operands: CArray<BinaryenExpressionRef>, numOperands: BinaryenIndex, returnType: BinaryenType): BinaryenExpressionRef;
declare function _BinaryenCallImport(module: BinaryenModuleRef, target: CString, operands: CArray<BinaryenExpressionRef>, numOperands: BinaryenIndex, returnType: BinaryenType): BinaryenExpressionRef;
declare function _BinaryenCallIndirect(module: BinaryenModuleRef, target: BinaryenExpressionRef, operands: CArray<BinaryenExpressionRef>, numOperands: BinaryenIndex, type: CString): BinaryenExpressionRef;
declare function _BinaryenLoop(module: BinaryenModuleRef, name: usize, body: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenBreak(module: BinaryenModuleRef, name: usize, condition: BinaryenExpressionRef, value: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenSwitch(module: BinaryenModuleRef, names: usize, numNames: BinaryenIndex, defaultName: usize, condition: BinaryenExpressionRef, value: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenCall(module: BinaryenModuleRef, target: usize, operands: usize, numOperands: BinaryenIndex, returnType: BinaryenType): BinaryenExpressionRef;
declare function _BinaryenCallImport(module: BinaryenModuleRef, target: usize, operands: usize, numOperands: BinaryenIndex, returnType: BinaryenType): BinaryenExpressionRef;
declare function _BinaryenCallIndirect(module: BinaryenModuleRef, target: BinaryenExpressionRef, operands: usize, numOperands: BinaryenIndex, type: usize): BinaryenExpressionRef;
declare function _BinaryenGetLocal(module: BinaryenModuleRef, index: BinaryenIndex, type: BinaryenType): BinaryenExpressionRef;
declare function _BinaryenSetLocal(module: BinaryenModuleRef, index: BinaryenIndex, value: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenTeeLocal(module: BinaryenModuleRef, index: BinaryenIndex, value: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenGetGlobal(module: BinaryenModuleRef, name: CString, type: BinaryenType): BinaryenExpressionRef;
declare function _BinaryenSetGlobal(module: BinaryenModuleRef, name: CString, value: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenGetGlobal(module: BinaryenModuleRef, name: usize, type: BinaryenType): BinaryenExpressionRef;
declare function _BinaryenSetGlobal(module: BinaryenModuleRef, name: usize, value: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenLoad(module: BinaryenModuleRef, bytes: u32, signed: i8, offset: u32, align: u32, type: BinaryenType, ptr: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenStore(module: BinaryenModuleRef, bytes: u32, offset: u32, align: u32, ptr: BinaryenExpressionRef, value: BinaryenExpressionRef, type: BinaryenType): BinaryenExpressionRef;
declare function _BinaryenConst(module: BinaryenModuleRef, value: BinaryenLiteral): BinaryenExpressionRef;
@ -239,7 +236,7 @@ declare function _BinaryenBinary(module: BinaryenModuleRef, op: BinaryenOp, left
declare function _BinaryenSelect(module: BinaryenModuleRef, condition: BinaryenExpressionRef, ifTrue: BinaryenExpressionRef, ifFalse: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenDrop(module: BinaryenModuleRef, value: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenReturn(module: BinaryenModuleRef, value: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenHost(module: BinaryenModuleRef, op: BinaryenOp, name: CString | 0, operands: CArray<BinaryenExpressionRef>, numOperands: BinaryenIndex): BinaryenExpressionRef;
declare function _BinaryenHost(module: BinaryenModuleRef, op: BinaryenOp, name: usize | 0, operands: usize, numOperands: BinaryenIndex): BinaryenExpressionRef;
declare function _BinaryenNop(module: BinaryenModuleRef): BinaryenExpressionRef;
declare function _BinaryenUnreachable(module: BinaryenModuleRef): BinaryenExpressionRef;
declare function _BinaryenAtomicLoad(module: BinaryenModuleRef, bytes: BinaryenIndex, offset: BinaryenIndex, type: BinaryenType, ptr: BinaryenExpressionRef): BinaryenExpressionRef;
@ -253,7 +250,7 @@ declare function _BinaryenExpressionGetId(expr: BinaryenExpressionRef): Binaryen
declare function _BinaryenExpressionGetType(expr: BinaryenExpressionRef): BinaryenType;
declare function _BinaryenExpressionPrint(expr: BinaryenExpressionRef): void;
declare function _BinaryenBlockGetName(expr: BinaryenExpressionRef): CString;
declare function _BinaryenBlockGetName(expr: BinaryenExpressionRef): usize;
declare function _BinaryenBlockGetNumChildren(expr: BinaryenExpressionRef): BinaryenIndex;
declare function _BinaryenBlockGetChild(expr: BinaryenExpressionRef, index: BinaryenIndex): BinaryenExpressionRef;
@ -261,24 +258,24 @@ declare function _BinaryenIfGetCondition(expr: BinaryenExpressionRef): BinaryenE
declare function _BinaryenIfGetIfTrue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenIfGetIfFalse(expr: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenLoopGetName(expr: BinaryenExpressionRef): CString;
declare function _BinaryenLoopGetName(expr: BinaryenExpressionRef): usize;
declare function _BinaryenLoopGetBody(expr: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenBreakGetName(expr: BinaryenExpressionRef): CString;
declare function _BinaryenBreakGetName(expr: BinaryenExpressionRef): usize;
declare function _BinaryenBreakGetCondition(expr: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenBreakGetValue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenSwitchGetNumNames(expr: BinaryenExpressionRef): BinaryenIndex;
declare function _BinaryenSwitchGetName(expr: BinaryenExpressionRef, index: BinaryenIndex): CString;
declare function _BinaryenSwitchGetDefaultName(expr: BinaryenExpressionRef): CString;
declare function _BinaryenSwitchGetName(expr: BinaryenExpressionRef, index: BinaryenIndex): usize;
declare function _BinaryenSwitchGetDefaultName(expr: BinaryenExpressionRef): usize;
declare function _BinaryenSwitchGetCondition(expr: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenSwitchGetValue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenCallGetTarget(expr: BinaryenExpressionRef): CString;
declare function _BinaryenCallGetTarget(expr: BinaryenExpressionRef): usize;
declare function _BinaryenCallGetNumOperands(expr: BinaryenExpressionRef): BinaryenIndex;
declare function _BinaryenCallGetOperand(expr: BinaryenExpressionRef, index: BinaryenIndex): BinaryenExpressionRef;
declare function _BinaryenCallImportGetTarget(expr: BinaryenExpressionRef): CString;
declare function _BinaryenCallImportGetTarget(expr: BinaryenExpressionRef): usize;
declare function _BinaryenCallImportGetNumOperands(expr: BinaryenExpressionRef): BinaryenIndex;
declare function _BinaryenCallImportGetOperand(expr: BinaryenExpressionRef, index: BinaryenIndex): BinaryenExpressionRef;
@ -292,13 +289,13 @@ declare function _BinaryenSetLocalIsTee(expr: BinaryenExpressionRef): bool;
declare function _BinaryenSetLocalGetIndex(expr: BinaryenExpressionRef): BinaryenIndex;
declare function _BinaryenSetLocalGetValue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenGetGlobalGetName(expr: BinaryenExpressionRef): CString;
declare function _BinaryenGetGlobalGetName(expr: BinaryenExpressionRef): usize;
declare function _BinaryenSetGlobalGetName(expr: BinaryenExpressionRef): CString;
declare function _BinaryenSetGlobalGetName(expr: BinaryenExpressionRef): usize;
declare function _BinaryenSetGlobalGetValue(expr: BinaryenExpressionRef): BinaryenExpressionRef;
declare function _BinaryenHostGetOp(expr: BinaryenExpressionRef): BinaryenOp;
declare function _BinaryenHostGetNameOperand(expr: BinaryenExpressionRef): CString;
declare function _BinaryenHostGetNameOperand(expr: BinaryenExpressionRef): usize;
declare function _BinaryenHostGetNumOperands(expr: BinaryenExpressionRef): BinaryenIndex;
declare function _BinaryenHostGetOperand(expr: BinaryenExpressionRef, index: BinaryenIndex): BinaryenExpressionRef;
@ -359,21 +356,21 @@ declare function _BinaryenAtomicWakeGetWakeCount(expr: BinaryenExpressionRef): B
declare type BinaryenFunctionTypeRef = usize;
declare function _BinaryenAddFunctionType(module: BinaryenModuleRef, name: CString, result: BinaryenType, paramTypes: CArray<BinaryenType>, numParams: BinaryenIndex): BinaryenFunctionTypeRef;
declare function _BinaryenGetFunctionTypeBySignature(module: BinaryenModuleRef, result: BinaryenType, paramTypes: CArray<BinaryenType>, numParams: BinaryenIndex): BinaryenFunctionTypeRef;
declare function _BinaryenAddFunctionType(module: BinaryenModuleRef, name: usize, result: BinaryenType, paramTypes: usize, numParams: BinaryenIndex): BinaryenFunctionTypeRef;
declare function _BinaryenGetFunctionTypeBySignature(module: BinaryenModuleRef, result: BinaryenType, paramTypes: usize, numParams: BinaryenIndex): BinaryenFunctionTypeRef;
declare function _BinaryenFunctionTypeGetName(ftype: BinaryenFunctionTypeRef): CString;
declare function _BinaryenFunctionTypeGetName(ftype: BinaryenFunctionTypeRef): usize;
declare function _BinaryenFunctionTypeGetNumParams(ftype: BinaryenFunctionTypeRef): BinaryenIndex;
declare function _BinaryenFunctionTypeGetParam(ftype: BinaryenFunctionTypeRef, index: BinaryenIndex): BinaryenType;
declare function _BinaryenFunctionTypeGetResult(ftype: BinaryenFunctionTypeRef): BinaryenType;
declare type BinaryenFunctionRef = usize;
declare function _BinaryenAddFunction(module: BinaryenModuleRef, name: CString, type: BinaryenFunctionTypeRef, varTypes: CArray<BinaryenType>, numVarTypes: BinaryenIndex, body: BinaryenExpressionRef): BinaryenFunctionRef;
declare function _BinaryenGetFunction(module: BinaryenModuleRef, name: CString): BinaryenFunctionRef;
declare function _BinaryenRemoveFunction(module: BinaryenModuleRef, name: CString): void;
declare function _BinaryenAddFunction(module: BinaryenModuleRef, name: usize, type: BinaryenFunctionTypeRef, varTypes: usize, numVarTypes: BinaryenIndex, body: BinaryenExpressionRef): BinaryenFunctionRef;
declare function _BinaryenGetFunction(module: BinaryenModuleRef, name: usize): BinaryenFunctionRef;
declare function _BinaryenRemoveFunction(module: BinaryenModuleRef, name: usize): void;
declare function _BinaryenFunctionGetName(func: BinaryenFunctionRef): CString;
declare function _BinaryenFunctionGetName(func: BinaryenFunctionRef): usize;
declare function _BinaryenFunctionGetType(func: BinaryenFunctionRef): BinaryenFunctionTypeRef;
declare function _BinaryenFunctionGetNumParams(func: BinaryenFunctionRef): BinaryenIndex;
declare function _BinaryenFunctionGetParam(func: BinaryenFunctionRef, index: BinaryenIndex): BinaryenType;
@ -382,43 +379,43 @@ declare function _BinaryenFunctionGetNumVars(func: BinaryenFunctionRef): Binarye
declare function _BinaryenFunctionGetVar(func: BinaryenFunctionRef, index: BinaryenIndex): BinaryenType;
declare function _BinaryenFunctionGetBody(func: BinaryenFunctionRef): BinaryenExpressionRef;
declare function _BinaryenFunctionOptimize(func: BinaryenFunctionRef, module: BinaryenModuleRef): void;
declare function _BinaryenFunctionRunPasses(func: BinaryenFunctionRef, module: BinaryenModuleRef, passes: CArray<CString>, numPasses: BinaryenIndex): void;
declare function _BinaryenFunctionRunPasses(func: BinaryenFunctionRef, module: BinaryenModuleRef, passes: usize, numPasses: BinaryenIndex): void;
declare type BinaryenImportRef = usize;
declare function _BinaryenAddFunctionImport(module: BinaryenModuleRef, internalName: CString, externalModuleName: CString, externalBaseName: CString, functionType: BinaryenFunctionTypeRef): BinaryenImportRef;
declare function _BinaryenAddTableImport(module: BinaryenModuleRef, internalName: CString, externalModuleName: CString, externalBaseName: CString): BinaryenImportRef;
declare function _BinaryenAddMemoryImport(module: BinaryenModuleRef, internalName: CString, externalModuleName: CString, externalBaseName: CString): BinaryenImportRef;
declare function _BinaryenAddGlobalImport(module: BinaryenModuleRef, internalName: CString, externalModuleName: CString, externalBaseName: CString, globalType: BinaryenType): BinaryenImportRef;
declare function _BinaryenRemoveImport(module: BinaryenModuleRef, internalName: CString): void;
declare function _BinaryenAddFunctionImport(module: BinaryenModuleRef, internalName: usize, externalModuleName: usize, externalBaseName: usize, functionType: BinaryenFunctionTypeRef): BinaryenImportRef;
declare function _BinaryenAddTableImport(module: BinaryenModuleRef, internalName: usize, externalModuleName: usize, externalBaseName: usize): BinaryenImportRef;
declare function _BinaryenAddMemoryImport(module: BinaryenModuleRef, internalName: usize, externalModuleName: usize, externalBaseName: usize): BinaryenImportRef;
declare function _BinaryenAddGlobalImport(module: BinaryenModuleRef, internalName: usize, externalModuleName: usize, externalBaseName: usize, globalType: BinaryenType): BinaryenImportRef;
declare function _BinaryenRemoveImport(module: BinaryenModuleRef, internalName: usize): void;
declare type BinaryenExportRef = usize;
declare function _BinaryenAddFunctionExport(module: BinaryenModuleRef, internalName: CString, externalName: CString): BinaryenExportRef;
declare function _BinaryenAddTableExport(module: BinaryenModuleRef, internalName: CString, externalName: CString): BinaryenExportRef;
declare function _BinaryenAddMemoryExport(module: BinaryenModuleRef, internalName: CString, externalName: CString): BinaryenExportRef;
declare function _BinaryenAddGlobalExport(module: BinaryenModuleRef, internalName: CString, externalName: CString): BinaryenExportRef;
declare function _BinaryenRemoveExport(module: BinaryenModuleRef, externalName: CString): void;
declare function _BinaryenAddFunctionExport(module: BinaryenModuleRef, internalName: usize, externalName: usize): BinaryenExportRef;
declare function _BinaryenAddTableExport(module: BinaryenModuleRef, internalName: usize, externalName: usize): BinaryenExportRef;
declare function _BinaryenAddMemoryExport(module: BinaryenModuleRef, internalName: usize, externalName: usize): BinaryenExportRef;
declare function _BinaryenAddGlobalExport(module: BinaryenModuleRef, internalName: usize, externalName: usize): BinaryenExportRef;
declare function _BinaryenRemoveExport(module: BinaryenModuleRef, externalName: usize): void;
declare type BinaryenGlobalRef = usize;
declare function _BinaryenAddGlobal(module: BinaryenModuleRef, name: CString, type: BinaryenType, mutable: i8, init: BinaryenExpressionRef): BinaryenGlobalRef;
declare function _BinaryenAddGlobal(module: BinaryenModuleRef, name: usize, type: BinaryenType, mutable: i8, init: BinaryenExpressionRef): BinaryenGlobalRef;
declare function _BinaryenSetFunctionTable(module: BinaryenModuleRef, funcs: CArray<BinaryenFunctionRef>, numFuncs: BinaryenIndex): void;
declare function _BinaryenSetFunctionTable(module: BinaryenModuleRef, funcs: usize, numFuncs: BinaryenIndex): void;
declare function _BinaryenSetMemory(module: BinaryenModuleRef, initial: BinaryenIndex, maximum: BinaryenIndex, exportName: CString, segments: CArray<CArray<u8>>, segmentOffsets: CArray<BinaryenExpressionRef>, segmentSizes: CArray<BinaryenIndex>, numSegments: BinaryenIndex): void;
declare function _BinaryenSetMemory(module: BinaryenModuleRef, initial: BinaryenIndex, maximum: BinaryenIndex, exportName: usize, segments: usize, segmentOffsets: usize, segmentSizes: usize, numSegments: BinaryenIndex): void;
declare function _BinaryenSetStart(module: BinaryenModuleRef, start: BinaryenFunctionRef): void;
declare function _BinaryenModuleParse(text: CString): BinaryenModuleRef;
declare function _BinaryenModuleParse(text: usize): BinaryenModuleRef;
declare function _BinaryenModulePrint(module: BinaryenModuleRef): void;
declare function _BinaryenModulePrintAsmjs(module: BinaryenModuleRef): void;
declare function _BinaryenModuleValidate(module: BinaryenModuleRef): i32;
declare function _BinaryenModuleOptimize(module: BinaryenModuleRef): void;
declare function _BinaryenModuleRunPasses(module: BinaryenModuleRef, passes: CArray<CString>, numPasses: BinaryenIndex): void;
declare function _BinaryenModuleRunPasses(module: BinaryenModuleRef, passes: usize, numPasses: BinaryenIndex): void;
declare function _BinaryenModuleAutoDrop(module: BinaryenModuleRef): void;
declare function _BinaryenModuleWrite(module: BinaryenModuleRef, output: CString, outputSize: usize): usize;
declare function _BinaryenModuleRead(input: CString, inputSize: usize): BinaryenModuleRef;
declare function _BinaryenModuleWrite(module: BinaryenModuleRef, output: usize, outputSize: usize): usize;
declare function _BinaryenModuleRead(input: usize, inputSize: usize): BinaryenModuleRef;
declare function _BinaryenModuleInterpret(module: BinaryenModuleRef): void;
declare type RelooperRef = usize;
@ -428,7 +425,7 @@ declare function _RelooperCreate(): RelooperRef;
declare function _RelooperAddBlock(relooper: RelooperRef, code: BinaryenExpressionRef): RelooperBlockRef;
declare function _RelooperAddBranch(from: RelooperBlockRef, to: RelooperBlockRef, condition: BinaryenExpressionRef, code: BinaryenExpressionRef): void;
declare function _RelooperAddBlockWithSwitch(relooper: RelooperRef, code: BinaryenExpressionRef, condition: BinaryenExpressionRef): RelooperBlockRef;
declare function _RelooperAddBranchForSwitch(from: RelooperBlockRef, to: RelooperBlockRef, indexes: CArray<BinaryenIndex>, numIndexes: BinaryenIndex, code: BinaryenExpressionRef): void;
declare function _RelooperAddBranchForSwitch(from: RelooperBlockRef, to: RelooperBlockRef, indexes: usize, numIndexes: BinaryenIndex, code: BinaryenExpressionRef): void;
declare function _RelooperRenderAndDispose(relooper: RelooperRef, entry: RelooperBlockRef, labelHelper: BinaryenIndex, module: BinaryenModuleRef): BinaryenExpressionRef;
declare function _BinaryenSetAPITracing(on: i32): void;

3
src/glue/js.d.ts vendored
View File

@ -1,6 +1,3 @@
/// <reference path="../../portable-assembly.d.ts" />
/// <reference path="./binaryen-c.d.ts" />
// Raw memory accesses to Binaryen memory
declare function store<T = u8>(ptr: usize, val: T): void;
declare function load<T = u8>(ptr: usize): T;

View File

@ -1,7 +1,7 @@
require("../../portable-assembly");
require("../../portable-assembly"); // not inherited from tsconfig by ts-node otherwise :(
// Copy Binaryen exports to global scope
var globalScope = typeof window !== "undefined" && window || typeof global !== "undefined" && global || self;
var binaryen;
try {
binaryen = require("binaryen");
@ -9,29 +9,36 @@ try {
binaryen = globalScope["Binaryen"];
}
for (var key in binaryen)
if (/^_(?:Binaryen|Relooper|malloc$|free$)/.test(key))
if (/^_(?:Binaryen|Relooper)/.test(key))
globalScope[key] = binaryen[key];
// Use Binaryen's heap
Object.defineProperties(globalScope['Heap'] = {
allocate: binaryen._malloc,
dispose: binaryen._free
}, {
free: { get: function() { return binaryen.HEAPU8.length; } },
used: { get: function() { return 0; } },
size: { get: function() { return binaryen.HEAPU8.length; } }
});
globalScope["store"] = function store(ptr, val) {
binaryen.HEAPU8[ptr] = val;
};
globalScope["load"] = function load_u8(ptr) {
return binaryen.HEAPU8[ptr];
};
// Implement module stubs
var Module = require("../module").Module;
Module.prototype.toBinary = function toBinary(bufferSize) {
if (!bufferSize) bufferSize = 1024 * 1024;
if (!bufferSize) bufferSize = 1024 * 1024; // FIXME: see binaryen.js-post.js in Binaryen
var ptr = _malloc(bufferSize);
var len = this.write(ptr, bufferSize);
var ret = new Uint8Array(len);
ret.set(binaryen.HEAPU8.subarray(ptr, ptr + len));
_free(ptr);
return ret;
}
};
Module.prototype.toText = function toText() {
var previousPrint = binaryen.print;
var ret = "";
@ -39,8 +46,7 @@ Module.prototype.toText = function toText() {
this.print();
binaryen.print = previousPrint;
return ret;
}
};
Module.prototype.toAsmjs = function toAsmjs() {
var previousPrint = binaryen.print;
var ret = "";
@ -48,4 +54,4 @@ Module.prototype.toAsmjs = function toAsmjs() {
this.printAsmjs();
binaryen.print = previousPrint;
return ret;
}
};

View File

@ -1,14 +1,14 @@
import { I64, U64 } from "./util";
import { Target } from "./compiler";
export type ModuleRef = BinaryenModuleRef;
export type FunctionTypeRef = BinaryenFunctionTypeRef;
export type FunctionRef = BinaryenFunctionRef;
export type ExpressionRef = BinaryenExpressionRef;
export type GlobalRef = BinaryenGlobalRef;
export type ImportRef = BinaryenImportRef;
export type ExportRef = BinaryenExportRef;
export type Index = BinaryenIndex;
export type ModuleRef = usize;
export type FunctionTypeRef = usize;
export type FunctionRef = usize;
export type ExpressionRef = usize;
export type GlobalRef = usize;
export type ImportRef = usize;
export type ExportRef = usize;
export type Index = u32;
export enum NativeType {
None = _BinaryenNone(),
@ -219,28 +219,28 @@ export class Module {
static create(): Module {
const module: Module = new Module();
module.ref = _BinaryenModuleCreate();
module.lit = _malloc(16);
module.lit = changetype<usize,BinaryenLiteral>(Heap.allocate(16));
module.noEmit = false;
return module;
}
static createFrom(buffer: Uint8Array): Module {
const cArr: CArray<u8> = allocU8Array(buffer);
const cArr: usize = allocU8Array(buffer);
try {
const module: Module = new Module();
module.ref = _BinaryenModuleRead(cArr, buffer.length);
module.lit = _malloc(16);
module.lit = changetype<usize,BinaryenLiteral>(Heap.allocate(16));
module.noEmit = false;
return module;
} finally {
_free(cArr);
Heap.dispose(changetype<usize,usize>(cArr));
}
}
static createStub(): Module {
const module: Module = new Module();
module.ref = 0;
module.lit = 0;
module.lit = changetype<usize,BinaryenLiteral>(0);
module.noEmit = true;
return module;
}
@ -251,23 +251,23 @@ export class Module {
addFunctionType(name: string, result: NativeType, paramTypes: NativeType[]): FunctionRef {
if (this.noEmit) return 0;
const cStr: CString = allocString(name);
const cArr: CArray<i32> = allocI32Array(paramTypes);
const cStr: usize = allocString(name);
const cArr: usize = allocI32Array(paramTypes);
try {
return _BinaryenAddFunctionType(this.ref, cStr, result, cArr, paramTypes.length);
} finally {
_free(cArr);
_free(cStr);
Heap.dispose(cArr);
Heap.dispose(cStr);
}
}
getFunctionTypeBySignature(result: NativeType, paramTypes: NativeType[]): FunctionTypeRef {
if (this.noEmit) return 0;
const cArr: CArray<i32> = allocI32Array(paramTypes);
const cArr: usize = allocI32Array(paramTypes);
try {
return _BinaryenGetFunctionTypeBySignature(this.ref, result, cArr, paramTypes.length);
} finally {
_free(cArr);
Heap.dispose(cArr);
}
}
@ -309,13 +309,13 @@ export class Module {
createHost(op: HostOp, name: string | null = null, operands: ExpressionRef[] | null = null): ExpressionRef {
if (this.noEmit) return 0;
const cStr: CString = allocString(name);
const cArr: CArray<i32> = allocI32Array(operands);
const cStr: usize = allocString(name);
const cArr: usize = allocI32Array(operands);
try {
return _BinaryenHost(this.ref, op, cStr, cArr, operands ? (<ExpressionRef[]>operands).length : 0);
} finally {
_free(cArr);
_free(cStr);
Heap.dispose(cArr);
Heap.dispose(cStr);
}
}
@ -331,11 +331,11 @@ export class Module {
createGetGlobal(name: string, type: NativeType): ExpressionRef {
if (this.noEmit) return 0;
const cStr: CString = allocString(name);
const cStr: usize = allocString(name);
try {
return _BinaryenGetGlobal(this.ref, cStr, type);
} finally {
_free(cStr);
Heap.dispose(cStr);
}
}
@ -388,33 +388,33 @@ export class Module {
createSetGlobal(name: string, value: ExpressionRef): ExpressionRef {
if (this.noEmit) return 0;
const cStr: CString = allocString(name);
const cStr: usize = allocString(name);
try {
return _BinaryenSetGlobal(this.ref, cStr, value);
} finally {
_free(cStr);
Heap.dispose(cStr);
}
}
createBlock(label: string | null, children: ExpressionRef[], type: NativeType = NativeType.Undefined): ExpressionRef {
if (this.noEmit) return 0;
const cStr: CString = allocString(label);
const cArr: CArray<i32> = allocI32Array(children);
const cStr: usize = allocString(label);
const cArr: usize = allocI32Array(children);
try {
return _BinaryenBlock(this.ref, cStr, cArr, children.length, type);
} finally {
_free(cArr);
_free(cStr);
Heap.dispose(cArr);
Heap.dispose(cStr);
}
}
createBreak(label: string | null, condition: ExpressionRef = 0, value: ExpressionRef = 0): ExpressionRef {
if (this.noEmit) return 0;
const cStr: CString = allocString(label);
const cStr: usize = allocString(label);
try {
return _BinaryenBreak(this.ref, cStr, condition, value);
} finally {
_free(cStr);
Heap.dispose(cStr);
}
}
@ -425,11 +425,11 @@ export class Module {
createLoop(label: string | null, body: ExpressionRef): ExpressionRef {
if (this.noEmit) return 0;
const cStr: CString = allocString(label);
const cStr: usize = allocString(label);
try {
return _BinaryenLoop(this.ref, cStr, body);
} finally {
_free(cStr);
Heap.dispose(cStr);
}
}
@ -455,41 +455,41 @@ export class Module {
createSwitch(names: string[], defaultName: string | null, condition: ExpressionRef, value: ExpressionRef = 0): ExpressionRef {
if (this.noEmit) return 0;
const strs: CString[] = new Array(names.length);
const strs: usize[] = new Array(names.length);
let i: i32, k: i32 = names.length;
for (i = 0; i < k; ++i) strs[i] = allocString(names[i]);
const cArr: CArray<i32> = allocI32Array(strs);
const cStr: CString = allocString(defaultName);
const cArr: usize = allocI32Array(strs);
const cStr: usize = allocString(defaultName);
try {
return _BinaryenSwitch(this.ref, cArr, k, cStr, condition, value);
} finally {
_free(cStr);
_free(cArr);
for (i = k - 1; i >= 0; --i) _free(strs[i]);
Heap.dispose(cStr);
Heap.dispose(cArr);
for (i = k - 1; i >= 0; --i) Heap.dispose(strs[i]);
}
}
createCall(target: string, operands: ExpressionRef[], returnType: NativeType): ExpressionRef {
if (this.noEmit) return 0;
const cStr: CString = allocString(target);
const cArr: CArray<i32> = allocI32Array(operands);
const cStr: usize = allocString(target);
const cArr: usize = allocI32Array(operands);
try {
return _BinaryenCall(this.ref, cStr, cArr, operands.length, returnType);
} finally {
_free(cArr);
_free(cStr);
Heap.dispose(cArr);
Heap.dispose(cStr);
}
}
createCallImport(target: string, operands: ExpressionRef[], returnType: NativeType): ExpressionRef {
if (this.noEmit) return 0;
const cStr: CString = allocString(target);
const cArr: CArray<i32> = allocI32Array(operands);
const cStr: usize = allocString(target);
const cArr: usize = allocI32Array(operands);
try {
return _BinaryenCallImport(this.ref, cStr, cArr, operands.length, returnType);
} finally {
_free(cArr);
_free(cStr);
Heap.dispose(cArr);
Heap.dispose(cStr);
}
}
@ -502,80 +502,80 @@ export class Module {
addGlobal(name: string, type: NativeType, mutable: bool, initializer: ExpressionRef): GlobalRef {
if (this.noEmit) return 0;
const cStr: CString = allocString(name);
const cStr: usize = allocString(name);
try {
return _BinaryenAddGlobal(this.ref, cStr, type, mutable ? 1 : 0, initializer);
} finally {
_free(cStr);
Heap.dispose(cStr);
}
}
addFunction(name: string, type: FunctionTypeRef, varTypes: NativeType[], body: ExpressionRef): FunctionRef {
if (this.noEmit) return 0;
const cStr: CString = allocString(name);
const cArr: CArray<i32> = allocI32Array(varTypes);
const cStr: usize = allocString(name);
const cArr: usize = allocI32Array(varTypes);
try {
return _BinaryenAddFunction(this.ref, cStr, type, cArr, varTypes.length, body);
} finally {
_free(cArr);
_free(cStr);
Heap.dispose(cArr);
Heap.dispose(cStr);
}
}
removeFunction(name: string): void {
const cStr: CString = allocString(name);
const cStr: usize = allocString(name);
try {
_BinaryenRemoveFunction(this.ref, cStr);
} finally {
_free(cStr);
Heap.dispose(cStr);
}
}
addFunctionExport(internalName: string, externalName: string): ExportRef {
if (this.noEmit) return 0;
const cStr1: CString = allocString(internalName);
const cStr2: CString = allocString(externalName);
const cStr1: usize = allocString(internalName);
const cStr2: usize = allocString(externalName);
try {
return _BinaryenAddFunctionExport(this.ref, cStr1, cStr2);
} finally {
_free(cStr2);
_free(cStr1);
Heap.dispose(cStr2);
Heap.dispose(cStr1);
}
}
addTableExport(internalName: string, externalName: string): ExportRef {
if (this.noEmit) return 0;
const cStr1: CString = allocString(internalName);
const cStr2: CString = allocString(externalName);
const cStr1: usize = allocString(internalName);
const cStr2: usize = allocString(externalName);
try {
return _BinaryenAddTableExport(this.ref, cStr1, cStr2);
} finally {
_free(cStr2);
_free(cStr1);
Heap.dispose(cStr2);
Heap.dispose(cStr1);
}
}
addMemoryExport(internalName: string, externalName: string): ExportRef {
if (this.noEmit) return 0;
const cStr1: CString = allocString(internalName);
const cStr2: CString = allocString(externalName);
const cStr1: usize = allocString(internalName);
const cStr2: usize = allocString(externalName);
try {
return _BinaryenAddMemoryExport(this.ref, cStr1, cStr2);
} finally {
_free(cStr2);
_free(cStr1);
Heap.dispose(cStr2);
Heap.dispose(cStr1);
}
}
addGlobalExport(internalName: string, externalName: string): ExportRef {
if (this.noEmit) return 0;
const cStr1: CString = allocString(internalName);
const cStr2: CString = allocString(externalName);
const cStr1: usize = allocString(internalName);
const cStr2: usize = allocString(externalName);
try {
return _BinaryenAddGlobalExport(this.ref, cStr1, cStr2);
} finally {
_free(cStr2);
_free(cStr1);
Heap.dispose(cStr2);
Heap.dispose(cStr1);
}
}
@ -585,81 +585,81 @@ export class Module {
try {
_BinaryenRemoveExport(this.ref, cStr);
} finally {
_free(cStr);
Heap.dispose(cStr);
}
}
addFunctionImport(internalName: string, externalModuleName: string, externalBaseName: string, functionType: FunctionTypeRef): ImportRef {
if (this.noEmit) return 0;
const cStr1: CString = allocString(internalName);
const cStr2: CString = allocString(externalModuleName);
const cStr3: CString = allocString(externalBaseName);
const cStr1: usize = allocString(internalName);
const cStr2: usize = allocString(externalModuleName);
const cStr3: usize = allocString(externalBaseName);
try {
return _BinaryenAddFunctionImport(this.ref, cStr1, cStr2, cStr3, functionType);
} finally {
_free(cStr3);
_free(cStr2);
_free(cStr1);
Heap.dispose(cStr3);
Heap.dispose(cStr2);
Heap.dispose(cStr1);
}
}
addTableImport(internalName: string, externalModuleName: string, externalBaseName: string): ImportRef {
if (this.noEmit) return 0;
const cStr1: CString = allocString(internalName);
const cStr2: CString = allocString(externalModuleName);
const cStr3: CString = allocString(externalBaseName);
const cStr1: usize = allocString(internalName);
const cStr2: usize = allocString(externalModuleName);
const cStr3: usize = allocString(externalBaseName);
try {
return _BinaryenAddTableImport(this.ref, cStr1, cStr2, cStr3);
} finally {
_free(cStr3);
_free(cStr2);
_free(cStr1);
Heap.dispose(cStr3);
Heap.dispose(cStr2);
Heap.dispose(cStr1);
}
}
addMemoryImport(internalName: string, externalModuleName: string, externalBaseName: string): ImportRef {
if (this.noEmit) return 0;
const cStr1: CString = allocString(internalName);
const cStr2: CString = allocString(externalModuleName);
const cStr3: CString = allocString(externalBaseName);
const cStr1: usize = allocString(internalName);
const cStr2: usize = allocString(externalModuleName);
const cStr3: usize = allocString(externalBaseName);
try {
return _BinaryenAddMemoryImport(this.ref, cStr1, cStr2, cStr3);
} finally {
_free(cStr3);
_free(cStr2);
_free(cStr1);
Heap.dispose(cStr3);
Heap.dispose(cStr2);
Heap.dispose(cStr1);
}
}
addGlobalImport(internalName: string, externalModuleName: string, externalBaseName: string, globalType: NativeType): ImportRef {
if (this.noEmit) return 0;
const cStr1: CString = allocString(internalName);
const cStr2: CString = allocString(externalModuleName);
const cStr3: CString = allocString(externalBaseName);
const cStr1: usize = allocString(internalName);
const cStr2: usize = allocString(externalModuleName);
const cStr3: usize = allocString(externalBaseName);
try {
return _BinaryenAddGlobalImport(this.ref, cStr1, cStr2, cStr3, globalType);
} finally {
_free(cStr3);
_free(cStr2);
_free(cStr1);
Heap.dispose(cStr3);
Heap.dispose(cStr2);
Heap.dispose(cStr1);
}
}
removeImport(internalName: string): void {
if (this.noEmit) return;
const cStr: CString = allocString(internalName);
const cStr: usize = allocString(internalName);
try {
_BinaryenRemoveImport(this.ref, cStr);
} finally {
_free(cStr);
Heap.dispose(cStr);
}
}
setMemory(initial: Index, maximum: Index, segments: MemorySegment[], target: Target, exportName: string | null = null): void {
if (this.noEmit) return;
const cStr: CString = allocString(exportName);
const cStr: usize = allocString(exportName);
let i: i32, k: i32 = segments.length;
const segs: CArray<u8>[] = new Array(k);
const segs: usize[] = new Array(k);
const offs: ExpressionRef[] = new Array(k);
const sizs: Index[] = new Array(k);
for (i = 0; i < k; ++i) {
@ -671,27 +671,27 @@ export class Module {
: this.createI32(offset.toI32());
sizs[i] = buffer.length;
}
const cArr1: CArray<i32> = allocI32Array(segs);
const cArr2: CArray<i32> = allocI32Array(offs);
const cArr3: CArray<i32> = allocI32Array(sizs);
const cArr1: usize = allocI32Array(segs);
const cArr2: usize = allocI32Array(offs);
const cArr3: usize = allocI32Array(sizs);
try {
_BinaryenSetMemory(this.ref, initial, maximum, cStr, cArr1, cArr2, cArr3, k);
} finally {
_free(cArr3);
_free(cArr2);
_free(cArr1);
for (i = k - 1; i >= 0; --i) _free(segs[i]);
_free(cStr);
Heap.dispose(cArr3);
Heap.dispose(cArr2);
Heap.dispose(cArr1);
for (i = k - 1; i >= 0; --i) Heap.dispose(segs[i]);
Heap.dispose(cStr);
}
}
setFunctionTable(funcs: BinaryenFunctionRef[]): void {
setFunctionTable(funcs: FunctionRef[]): void {
if (this.noEmit) return;
const cArr: CArray<i32> = allocI32Array(funcs);
const cArr: usize = allocI32Array(funcs);
try {
_BinaryenSetFunctionTable(this.ref, cArr, funcs.length);
} finally {
_free(cArr);
Heap.dispose(cArr);
}
}
@ -712,17 +712,17 @@ export class Module {
runPasses(passes: string[], func: FunctionRef = 0): void {
let i: i32, k: i32 = passes.length;
const names: CString[] = new Array(k);
const names: usize[] = new Array(k);
for (i = 0; i < k; ++i) names[i] = allocString(passes[i]);
const cArr: CArray<i32> = allocI32Array(names);
const cArr: usize = allocI32Array(names);
try {
if (func)
_BinaryenFunctionRunPasses(func, this.ref, cArr, k);
else
_BinaryenModuleRunPasses(this.ref, cArr, k);
} finally {
_free(cArr);
for (; i >= 0; --i) _free(names[i]);
Heap.dispose(cArr);
for (; i >= 0; --i) Heap.dispose(names[i]);
}
}
@ -760,7 +760,7 @@ export class Module {
dispose(): void {
if (!this.ref) return; // sic
_BinaryenModuleDispose(this.ref);
_free(this.lit);
Heap.dispose(changetype<BinaryenLiteral, usize>(this.lit));
}
createRelooper(): Relooper {
@ -900,11 +900,11 @@ export class Relooper {
addBranchForSwitch(from: RelooperBlockRef, to: RelooperBlockRef, indexes: i32[], code: ExpressionRef = 0): void {
if (this.noEmit) return;
const cArr: CArray<i32> = allocI32Array(indexes);
const cArr: usize = allocI32Array(indexes);
try {
_RelooperAddBranchForSwitch(from, to, cArr, indexes.length, code);
} finally {
_free(cArr);
Heap.dispose(cArr);
}
}
@ -921,18 +921,18 @@ export function setAPITracing(on: bool): void {
// helpers
// can't do stack allocation here: STACKTOP is a global in WASM but a hidden variable in asm.js
function allocU8Array(u8s: Uint8Array | null): CArray<u8> {
function allocU8Array(u8s: Uint8Array | null): usize {
if (!u8s) return 0;
const ptr: usize = _malloc((<Uint8Array>u8s).length);
const ptr: usize = Heap.allocate((<Uint8Array>u8s).length);
let idx: usize = ptr;
for (let i: i32 = 0, k: i32 = (<Uint8Array>u8s).length; i < k; ++i)
store<u8>(idx++, (<Uint8Array>u8s)[i])
return ptr;
}
function allocI32Array(i32s: i32[] | null): CArray<i32> {
function allocI32Array(i32s: i32[] | null): usize {
if (!i32s) return 0;
const ptr: usize = _malloc((<i32[]>i32s).length << 2);
const ptr: usize = Heap.allocate((<i32[]>i32s).length << 2);
let idx: usize = ptr;
for (let i: i32 = 0, k: i32 = (<i32[]>i32s).length; i < k; ++i) {
let val: i32 = (<i32[]>i32s)[i];
@ -967,9 +967,9 @@ function stringLengthUTF8(str: string): usize {
return len;
}
function allocString(str: string | null): CString {
function allocString(str: string | null): usize {
if (!str) return 0;
const ptr: usize = _malloc(stringLengthUTF8((<string>str)) + 1);
const ptr: usize = Heap.allocate(stringLengthUTF8((<string>str)) + 1);
let idx: usize = ptr;
for (let i: i32 = 0, k: i32 = (<string>str).length; i < k; ++i) {
let u: i32 = (<string>str).charCodeAt(i);

View File

@ -81,7 +81,7 @@ export class Parser extends DiagnosticEmitter {
const normalizedPath: string = normalizePath(path);
for (let i: i32 = 0, k: i32 = this.program.sources.length; i < k; ++i)
if (this.program.sources[i].normalizedPath == normalizedPath)
throw Error("duplicate source");
throw new Error("duplicate source");
this.seenlog.add(normalizedPath);
const source: Source = new Source(path, text, isEntry);

View File

@ -83,6 +83,7 @@ export class Program extends DiagnosticEmitter {
/** Initializes the program and its elements prior to compilation. */
initialize(target: Target = Target.WASM32): void {
this.target = target;
this.types = new Map([
["i8", Type.i8],
["i16", Type.i16],

View File

@ -1,47 +1,10 @@
{
"extends": "../portable-assembly.json",
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"lib": [
"dom",
"es6"
],
"types": [
"node"
],
"downlevelIteration": true,
"experimentalDecorators": true,
"strictNullChecks": true,
"alwaysStrict": true,
"noImplicitReturns": true,
"noImplicitAny": true,
"noImplicitThis": true,
"preserveConstEnums": true,
"outDir": "../out",
"sourceMap": true
},
"files": [
"ast.ts",
"builtins.ts",
"compiler.ts",
"diagnosticMessages.generated.ts",
"diagnostics.ts",
"evaluator.ts",
"glue/js.d.ts",
"index.ts",
"module.ts",
"parser.ts",
"program.ts",
"tokenizer.ts",
"types.ts",
"util.ts",
"util/charcode.ts",
"util/i64.ts",
"util/path.ts"
],
"assembly": {
"exclude": [
"glue/js.d.ts"
]
}
"include": [
"./**/*.ts"
]
}

View File

@ -421,7 +421,7 @@ export class I64 {
lo = "0" + lo;
return (negative ? "-0x" : "0x") + (i64_hi as u32 >>> 0).toString(16) + lo;
}
return negative ? "-" + i64_lo.toString() : i64_lo.toString();
return negative ? "-" + i64_lo.toString(10) : i64_lo.toString(10);
}
}

View File

@ -1,5 +1,3 @@
/// <reference path="../../assembly.d.ts" />
const ALIGN_LOG2: usize = 3;
const ALIGN_SIZE: usize = 1 << ALIGN_LOG2;
const ALIGN_MASK: usize = ALIGN_SIZE - 1;

View File

@ -0,0 +1,9 @@
{
"extends": "../../assembly.json",
"compilerOptions": {
"diagnostics": true
},
"include": [
"./**/*.ts"
]
}

12
std/carray.d.ts vendored
View File

@ -1,12 +0,0 @@
/// <reference path="../assembly.d.ts" />
/** A C-compatible array class. */
declare class CArray<T> {
[key: number]: T;
/** Constructs a new C-Array of the specified capacity. */
constructor(capacity: usize);
/** Disposes this instance and the memory associated with it. */
dispose(): void;
}

12
std/cstring.d.ts vendored
View File

@ -1,12 +0,0 @@
/// <reference path="../assembly.d.ts" />
/** A C-compatible string class. */
declare class CString {
readonly [key: number]: u8;
/** Constructs a new C-String from a standard string. */
constructor(string: string);
/** Disposes this instance and the memory associated with it. */
dispose(): void;
}

View File

@ -1,25 +0,0 @@
/// <reference path="../../assembly.d.ts" />
@global()
@struct()
class CArray<T> {
constructor(capacity: usize) {
return changetype<usize, this>(Heap.allocate(capacity * sizeof<T>()));
}
@inline()
"[]"(index: usize): T {
return load<T>(changetype<this, usize>(this) + index * sizeof<T>());
}
@inline()
"[]="(index: usize, value: T): T {
store<T>(changetype<this, usize>(this) + index * sizeof<T>(), value);
return value;
}
dispose(): void {
Heap.dispose(changetype<this, usize>(this));
}
}

View File

@ -1,58 +0,0 @@
/// <reference path="../../assembly.d.ts" />
@global()
@struct()
class CString {
constructor(string: string) {
const ptr: usize = Heap.allocate(<usize>string.length * 2 + 1);
let idx: usize = ptr;
for (let i: usize = 0, k: usize = <usize>(<string>str).length; i < k; ++i) {
let u: i32 = string.charCodeAt(i);
if (u >= 0xD800 && u <= 0xDFFF && i + 1 < k)
u = 0x10000 + ((u & 0x3FF) << 10) | (string.charCodeAt(++i) & 0x3FF);
if (u <= 0x7F)
store<u8>(idx++, u as u8);
else if (u <= 0x7FF) {
// TODO: maybe combine multiple stores into the next larger one
store<u8>(idx++, (0xC0 | (u >>> 6) ) as u8);
store<u8>(idx++, (0x80 | ( u & 63)) as u8);
} else if (u <= 0xFFFF) {
store<u8>(idx++, (0xE0 | (u >>> 12) ) as u8);
store<u8>(idx++, (0x80 | ((u >>> 6) & 63)) as u8);
store<u8>(idx++, (0x80 | ( u & 63)) as u8);
} else if (u <= 0x1FFFFF) {
store<u8>(idx++, (0xF0 | (u >>> 18) ) as u8);
store<u8>(idx++, (0x80 | ((u >>> 12) & 63)) as u8);
store<u8>(idx++, (0x80 | ((u >>> 6) & 63)) as u8);
store<u8>(idx++, (0x80 | ( u & 63)) as u8);
} else if (u <= 0x3FFFFFF) {
store<u8>(idx++, (0xF8 | (u >>> 24) ) as u8);
store<u8>(idx++, (0x80 | ((u >>> 18) & 63)) as u8);
store<u8>(idx++, (0x80 | ((u >>> 12) & 63)) as u8);
store<u8>(idx++, (0x80 | ((u >>> 6) & 63)) as u8);
store<u8>(idx++, (0x80 | ( u & 63)) as u8);
} else {
store<u8>(idx++, (0xFC | (u >>> 30) ) as u8);
store<u8>(idx++, (0x80 | ((u >>> 24) & 63)) as u8);
store<u8>(idx++, (0x80 | ((u >>> 18) & 63)) as u8);
store<u8>(idx++, (0x80 | ((u >>> 12) & 63)) as u8);
store<u8>(idx++, (0x80 | ((u >>> 6) & 63)) as u8);
store<u8>(idx++, (0x80 | ( u & 63)) as u8);
}
}
store<u8>(idx, 0);
return changetype<usize, this>(ptr);
}
@inline()
"[]"(index: usize): u8 {
return load<u8>(changetype<this, usize>(this) + index /* * sizeof<u8>() */);
}
// read-only
dispose(): void {
Heap.dispose(changetype<this, usize>(this));
}
}

View File

@ -1,11 +0,0 @@
{
"compilerOptions": {
"noLib": true,
"experimentalDecorators": true
},
"files": [
"carray.ts",
"cstring.ts",
"heap.ts"
]
}

View File

@ -1,5 +1,3 @@
/// <reference path="../assembly.d.ts" />
/** A static class representing the heap. */
declare class Heap {
@ -10,11 +8,11 @@ declare class Heap {
static dispose(ptr: usize): void;
/** Gets the amount of used heap space, in bytes. */
static get used(): usize;
static readonly used: usize;
/** Gets the amount of free heap space, in bytes. */
static get free(): usize;
static readonly free: usize;
/** Gets the size of the heap, in bytes. */
static get size(): usize;
static readonly size: usize;
}

9
std/portable/heap.js Normal file
View File

@ -0,0 +1,9 @@
var globalScope = typeof window !== "undefined" && window || typeof global !== "undefined" && global || self;
globalScope["Heap"] = {
allocate: function() { throw new Error("not implemented"); },
dispose: function() { throw new Error("not implemented"); },
used: 0,
free: 0,
size: 0
};

View File

@ -0,0 +1,9 @@
{
"extends": "../../portable-assembly.json",
"compilerOptions": {
"diagnostics": true
},
"include": [
"./**/*.ts"
]
}

View File

@ -1,11 +0,0 @@
{
"compilerOptions": {
"noLib": true,
"experimentalDecorators": true
},
"files": [
"carray.d.ts",
"cstring.d.ts",
"heap.d.ts"
]
}

View File

@ -1,50 +0,0 @@
/// <reference path="../lib/binaryen.d.ts" />
import "../src/glue/js";
import { NativeType, Module, MemorySegment, BinaryOp } from "../src/module";
import { Target } from "../src/compiler";
import { U64 } from "../src/util";
const mod = Module.create();
mod.setMemory(1, Module.MAX_MEMORY_WASM32, [
MemorySegment.create(new Uint8Array(4), U64.fromI32(8)),
MemorySegment.create(new Uint8Array(4), U64.fromI32(12))
], Target.WASM32, "memory");
const add = mod.addFunctionType("iii", NativeType.I32, [ NativeType.I32, NativeType.I32 ]);
mod.addFunction("add", add, [], mod.createReturn(
mod.createBinary(BinaryOp.AddI32,
mod.createGetLocal(0, NativeType.I32),
mod.createGetLocal(1, NativeType.I32)
)
));
mod.addFunctionExport("add", "add");
const lit = mod.addFunctionType("I", NativeType.I64, []);
mod.addFunction("lit", lit, [], mod.createReturn(
mod.createI64(0, 0x80000000) // I64_MIN
));
mod.addFunctionExport("lit", "lit");
mod.addGlobal("42", NativeType.I32, false, mod.createI32(42));
const aSwitch = mod.addFunctionType("ii", NativeType.I32, [ NativeType.I32 ]);
const rl = mod.createRelooper();
const b0 = rl.addBlockWithSwitch(mod.createNop(), mod.createGetLocal(0, NativeType.I32));
let b1, b2, b3;
rl.addBranchForSwitch(b0, b2 = rl.addBlock(mod.createReturn(mod.createI32(1))), [1]); // indexed branch
rl.addBranchForSwitch(b0, b3 = rl.addBlock(mod.createReturn(mod.createI32(2))), [2]); // indexed branch
rl.addBranch(b0, b1 = rl.addBlock(mod.createDrop(mod.createI32(0)))); // default branch
rl.addBranch(b1, b2);
mod.addFunction("aSwitch", aSwitch, [ NativeType.I32 ], mod.createBlock(null, [
rl.renderAndDispose(b0, 1),
mod.createUnreachable()
]));
mod.addFunctionExport("aSwitch", "aSwitch");
// mod.optimize();
if (mod.validate())
_BinaryenModulePrint(mod.ref);
_BinaryenModuleDispose(mod.ref);

View File

@ -1,16 +1,18 @@
import * as fs from "fs";
import * as path from "path";
import * as chalk from "chalk";
import * as glob from "glob";
var fs = require("fs");
var path = require("path");
var chalk = require("chalk");
var glob = require("glob");
var diff = require("./util/diff");
import "../src/glue/js";
import { Compiler } from "../src/compiler";
import { Module } from "../src/module";
import { Parser } from "../src/parser";
import { diff } from "./util/diff";
require("ts-node").register({ project: require("path").join(__dirname, "..", "src") });
require("../src/glue/js");
const isCreate = process.argv[2] === "--create";
const filter = process.argv.length > 2 && !isCreate ? "*" + process.argv[2] + "*.ts" : "*.ts";
var Compiler = require("../src/compiler").Compiler;
var Module = require("../src/module").Module;
var Parser = require("../src/parser").Parser;
var isCreate = process.argv[2] === "--create";
var filter = process.argv.length > 2 && !isCreate ? "*" + process.argv[2] + "*.ts" : "*.ts";
glob.sync(filter, { cwd: __dirname + "/compiler" }).forEach(filename => {
if (filename.charAt(0) == "_" || filename.endsWith(".fixture.ts"))
@ -18,12 +20,12 @@ glob.sync(filter, { cwd: __dirname + "/compiler" }).forEach(filename => {
console.log(chalk.default.whiteBright("Testing compiler/" + filename));
const parser = new Parser();
const sourceText = fs.readFileSync(__dirname + "/compiler/" + filename, { encoding: "utf8" });
var parser = new Parser();
var sourceText = fs.readFileSync(__dirname + "/compiler/" + filename, { encoding: "utf8" });
parser.parseFile(sourceText, filename, true);
let nextFile;
var nextFile;
while ((nextFile = parser.nextFile()) !== null) {
let nextSourceText: string;
var nextSourceText;
try {
nextSourceText = fs.readFileSync(path.join(__dirname, "compiler", nextFile + ".ts"), { encoding: "utf8" });
} catch (e) {
@ -31,12 +33,12 @@ glob.sync(filter, { cwd: __dirname + "/compiler" }).forEach(filename => {
}
parser.parseFile(nextSourceText, nextFile, false);
}
const program = parser.finish();
const module = Compiler.compile(program);
const actual = module.toText() + "(;\n[program.elements]\n " + iterate(program.elements.keys()).join("\n ") + "\n[program.exports]\n " + iterate(program.exports.keys()).join("\n ") + "\n;)\n";
let actualOptimized: string | null = null;
let actualInlined: string | null = null;
const fixture = path.basename(filename, ".ts") + ".wast";
var program = parser.finish();
var module = Compiler.compile(program);
var actual = module.toText() + "(;\n[program.elements]\n " + iterate(program.elements.keys()).join("\n ") + "\n[program.exports]\n " + iterate(program.exports.keys()).join("\n ") + "\n;)\n";
var actualOptimized = null;
var actualInlined = null;
var fixture = path.basename(filename, ".ts") + ".wast";
if (module.validate()) {
console.log(chalk.default.green("validate OK"));
@ -75,8 +77,8 @@ glob.sync(filter, { cwd: __dirname + "/compiler" }).forEach(filename => {
}
}
} else {
const expected = fs.readFileSync(__dirname + "/compiler/" + fixture, { encoding: "utf8" });
const diffs = diff("compiler/" + fixture, expected, actual);
var expected = fs.readFileSync(__dirname + "/compiler/" + fixture, { encoding: "utf8" });
var diffs = diff("compiler/" + fixture, expected, actual);
if (diffs !== null) {
process.exitCode = 1;
console.log(diffs);
@ -90,11 +92,10 @@ glob.sync(filter, { cwd: __dirname + "/compiler" }).forEach(filename => {
console.log();
});
function iterate<T>(it: IterableIterator<T>): T[] {
let current: IteratorResult<T>;
var arr: T[] = [];
while ((current = it.next()) && !current.done) {
function iterate(it) {
var current;
var arr = [];
while ((current = it.next()) && !current.done)
arr.push(current.value);
}
return arr;
}
}

45
tests/parser.js Normal file
View File

@ -0,0 +1,45 @@
var fs = require("fs");
var chalk = require("chalk");
var glob = require("glob");
var diff = require("./util/diff");
require("ts-node").register({ project: require("path").join(__dirname, "..", "src", "tsconfig.json") });
require("../src/glue/js");
var Parser = require("../src/parser").Parser;
var isCreate = process.argv[2] === "--create";
var filter = process.argv.length > 2 && !isCreate ? "*" + process.argv[2] + "*.ts" : "**.ts";
glob.sync(filter, { cwd: __dirname + "/parser" }).forEach(filename => {
if (filename.charAt(0) == "_" || filename.endsWith(".fixture.ts"))
return;
console.log(chalk.default.whiteBright("Testing parser/" + filename));
var parser = new Parser();
var sourceText = fs.readFileSync(__dirname + "/parser/" + filename, { encoding: "utf8" }).replace(/\r?\n/g, "\n").replace(/^\/\/.*\r?\n/mg, "");
parser.parseFile(sourceText, filename, true);
var sb = [];
parser.program.sources[0].serialize(sb);
var actual = sb.join("");
var fixture = filename + ".fixture.ts";
if (isCreate) {
fs.writeFileSync(__dirname + "/parser/" + fixture, actual, { encoding: "utf8" });
console.log("Created\n");
} else {
var expected = fs.readFileSync(__dirname + "/parser/" + fixture, { encoding: "utf8" });
var diffs = diff("parser/" + fixture, expected, actual);
if (diffs !== null) {
process.exitCode = 1;
console.log(diffs);
console.log(chalk.default.red("diff ERROR"));
} else {
console.log(chalk.default.green("diff OK"));
}
}
console.log();
});

View File

@ -1,43 +0,0 @@
import * as fs from "fs";
import * as chalk from "chalk";
import * as glob from "glob";
import "../src/glue/js";
import { Parser } from "../src/parser";
import { diff } from "./util/diff";
const isCreate = process.argv[2] === "--create";
const filter = process.argv.length > 2 && !isCreate ? "*" + process.argv[2] + "*.ts" : "**.ts";
glob.sync(filter, { cwd: __dirname + "/parser" }).forEach(filename => {
if (filename.charAt(0) == "_" || filename.endsWith(".fixture.ts"))
return;
console.log(chalk.default.whiteBright("Testing parser/" + filename));
const parser = new Parser();
const sourceText = fs.readFileSync(__dirname + "/parser/" + filename, { encoding: "utf8" }).replace(/\r?\n/g, "\n").replace(/^\/\/.*\r?\n/mg, "");
parser.parseFile(sourceText, filename, true);
var sb: string[] = [];
parser.program.sources[0].serialize(sb);
const actual = sb.join("");
const fixture = filename + ".fixture.ts";
if (isCreate) {
fs.writeFileSync(__dirname + "/parser/" + fixture, actual, { encoding: "utf8" });
console.log("Created\n");
} else {
const expected = fs.readFileSync(__dirname + "/parser/" + fixture, { encoding: "utf8" });
const diffs = diff("parser/" + fixture, expected, actual);
if (diffs !== null) {
process.exitCode = 1;
console.log(diffs);
console.log(chalk.default.red("diff ERROR"));
} else {
console.log(chalk.default.green("diff OK"));
}
}
console.log();
});

View File

@ -1,17 +1,17 @@
import * as JsDiff from "diff";
import * as chalk from "chalk";
var JsDiff = require("diff");
var chalk = require("chalk");
export function diff(filename: string, expected: string, actual: string): string | null {
const diff = JsDiff.structuredPatch(filename, filename, expected, actual, "expected", "actual", { context: 2 });
module.exports = function diff(filename, expected, actual) {
var diff = JsDiff.structuredPatch(filename, filename, expected, actual, "expected", "actual", { context: 2 });
if (!diff.hunks.length)
return null;
const ret = [];
var ret = [];
ret.push('--- ' + diff.oldHeader);
ret.push('+++ ' + diff.newHeader);
for (let i = 0; i < diff.hunks.length; i++) {
const hunk = diff.hunks[i];
for (var i = 0; i < diff.hunks.length; i++) {
var hunk = diff.hunks[i];
ret.push(
'@@ -' + hunk.oldStart + ',' + hunk.oldLines
+ ' +' + hunk.newStart + ',' + hunk.newLines
@ -27,4 +27,4 @@ export function diff(filename: string, expected: string, actual: string): string
}
return ret.join('\n') + '\n';
}
};

11
tsconfig-base.json Normal file
View File

@ -0,0 +1,11 @@
{
"compilerOptions": {
"alwaysStrict": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noEmitOnError": true,
"strictNullChecks": true,
"experimentalDecorators": true
}
}