mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 07:02:13 +00:00
Type limits
This commit is contained in:
parent
8085a02df3
commit
7cf879fb4b
15
README.md
15
README.md
@ -1,16 +1,19 @@
|
||||
AssemblyScript NEXT
|
||||
===================
|
||||
 AssemblyScript NEXT
|
||||
=================
|
||||
|
||||
[](https://travis-ci.org/AssemblyScript/next)
|
||||
[](https://travis-ci.org/AssemblyScript/assemblyscript)
|
||||
|
||||
**AssemblyScript** is a new compiler targeting [WebAssembly](http://webassembly.org) while utilizing [TypeScript](http://www.typescriptlang.org)'s syntax and [node](https://nodejs.org)'s vibrant ecosystem. Instead of requiring complex toolchains to set up, you can simply `npm install` it - or run it in a browser.
|
||||
|
||||
By compiling syntactially (not necessarily semantically) valid TypeScript to [Binaryen](https://github.com/WebAssembly/binaryen) IR, the resulting module can be validated, optimized, emitted in WebAssembly text or binary format and converted to [asm.js](http://asmjs.org) as a polyfill.
|
||||
|
||||
Note, though, that this version of the compiler (0.5.0, NEXT) is relatively new and does not yet support some features a TypeScript programmer might expect, e.g., strings, arrays and classes.
|
||||
|
||||
See [the AssemblyScript wiki](https://github.com/AssemblyScript/assemblyscript/wiki) for additional information and documentation.
|
||||
|
||||
How does it work?
|
||||
-----------------
|
||||
|
||||
By compiling syntactially (not necessarily semantically) valid TypeScript to [Binaryen](https://github.com/WebAssembly/binaryen) IR, the resulting module can be validated, optimized, emitted in WebAssembly text or binary format and converted to [asm.js](http://asmjs.org) as a polyfill.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
@ -22,7 +25,7 @@ A few early examples to get an idea:
|
||||
Getting started
|
||||
---------------
|
||||
|
||||
If you'd like to try it today or even plan to contribute, this is how you do it:
|
||||
This version of the compiler is not on [npm](https://www.npmjs.com/package/assemblyscript), yet, but if you'd like to try it today or even plan to contribute, this is how you do it:
|
||||
|
||||
```
|
||||
$> git clone https://github.com/AssemblyScript/next.git
|
||||
|
@ -3,7 +3,7 @@ import { DiagnosticCode } from "./diagnostics";
|
||||
import { Node, Expression } from "./ast";
|
||||
import { Type } from "./types";
|
||||
import { Module, ExpressionRef, UnaryOp, BinaryOp, HostOp, NativeType, FunctionTypeRef } from "./module";
|
||||
import { Program, ElementFlags, FunctionPrototype, Local } from "./program";
|
||||
import { Program, ElementFlags, Element, Global, FunctionPrototype, Local } from "./program";
|
||||
|
||||
/** Initializes the specified program with built-in functions. */
|
||||
export function initialize(program: Program): void {
|
||||
@ -35,14 +35,67 @@ export function initialize(program: Program): void {
|
||||
addFunction(program, "assert");
|
||||
addFunction(program, "parseInt");
|
||||
addFunction(program, "parseFloat");
|
||||
|
||||
addFunction(program, "i8").members = new Map([
|
||||
[ "MIN_VALUE", new Global(program, "i8.MIN_VALUE", null, Type.i8).withConstantIntegerValue(-128, -1) ],
|
||||
[ "MAX_VALUE", new Global(program, "i8.MAX_VALUE", null, Type.i8).withConstantIntegerValue(127, 0) ]
|
||||
]);
|
||||
addFunction(program, "i16").members = new Map([
|
||||
[ "MIN_VALUE", new Global(program, "i16.MIN_VALUE", null, Type.i16).withConstantIntegerValue(-32768, -1) ],
|
||||
[ "MAX_VALUE", new Global(program, "i16.MAX_VALUE", null, Type.i16).withConstantIntegerValue(32767, 0) ]
|
||||
]);
|
||||
addFunction(program, "i32").members = new Map([
|
||||
[ "MIN_VALUE", new Global(program, "i32.MIN_VALUE", null, Type.i32).withConstantIntegerValue(-2147483648, -1) ],
|
||||
[ "MAX_VALUE", new Global(program, "i32.MAX_VALUE", null, Type.i32).withConstantIntegerValue(2147483647, 0) ]
|
||||
]);
|
||||
addFunction(program, "i64").members = new Map([
|
||||
[ "MIN_VALUE", new Global(program, "i64.MIN_VALUE", null, Type.i64).withConstantIntegerValue(0, -2147483648) ],
|
||||
[ "MAX_VALUE", new Global(program, "i64.MAX_VALUE", null, Type.i64).withConstantIntegerValue(-1, 2147483647) ]
|
||||
]);
|
||||
addFunction(program, "u8").members = new Map([
|
||||
[ "MIN_VALUE", new Global(program, "u8.MIN_VALUE", null, Type.u8).withConstantIntegerValue(0, 0) ],
|
||||
[ "MAX_VALUE", new Global(program, "u8.MAX_VALUE", null, Type.u8).withConstantIntegerValue(255, 0) ]
|
||||
]);
|
||||
addFunction(program, "u16").members = new Map([
|
||||
[ "MIN_VALUE", new Global(program, "u16.MIN_VALUE", null, Type.u16).withConstantIntegerValue(0, 0) ],
|
||||
[ "MAX_VALUE", new Global(program, "u16.MAX_VALUE", null, Type.u16).withConstantIntegerValue(65535, 0) ]
|
||||
]);
|
||||
addFunction(program, "u32").members = new Map([
|
||||
[ "MIN_VALUE", new Global(program, "u32.MIN_VALUE", null, Type.u32).withConstantIntegerValue(0, 0) ],
|
||||
[ "MAX_VALUE", new Global(program, "u32.MAX_VALUE", null, Type.u32).withConstantIntegerValue(-1, 0) ]
|
||||
]);
|
||||
addFunction(program, "u64").members = new Map([
|
||||
[ "MIN_VALUE", new Global(program, "u64.MIN_VALUE", null, Type.u64).withConstantIntegerValue(0, 0) ],
|
||||
[ "MAX_VALUE", new Global(program, "u64.MAX_VALUE", null, Type.i64).withConstantIntegerValue(-1, -1) ]
|
||||
]);
|
||||
addFunction(program, "bool").members = new Map([
|
||||
[ "MIN_VALUE", new Global(program, "bool.MIN_VALUE", null, Type.bool).withConstantIntegerValue(0, 0) ],
|
||||
[ "MAX_VALUE", new Global(program, "bool.MAX_VALUE", null, Type.bool).withConstantIntegerValue(1, 0) ]
|
||||
]);
|
||||
addFunction(program, "f32").members = new Map([
|
||||
[ "MIN_SAFE_INTEGER", new Global(program, "f32.MIN_SAFE_INTEGER", null, Type.f32).withConstantFloatValue(-16777215) ],
|
||||
[ "MAX_SAFE_INTEGER", new Global(program, "f32.MAX_SAFE_INTEGER", null, Type.f32).withConstantFloatValue(16777215) ]
|
||||
]);
|
||||
addFunction(program, "f64").members = new Map([
|
||||
[ "MIN_SAFE_INTEGER", new Global(program, "f64.MIN_SAFE_INTEGER", null, Type.f64).withConstantFloatValue(-9007199254740991) ],
|
||||
[ "MAX_SAFE_INTEGER", new Global(program, "f64.MAX_SAFE_INTEGER", null, Type.f64).withConstantFloatValue(9007199254740991) ]
|
||||
]);
|
||||
if (program.target == Target.WASM64) {
|
||||
program.elements.set("isize", <Element>program.elements.get("i64"));
|
||||
program.elements.set("usize", <Element>program.elements.get("u64"));
|
||||
} else {
|
||||
program.elements.set("isize", <Element>program.elements.get("i32"));
|
||||
program.elements.set("usize", <Element>program.elements.get("u32"));
|
||||
}
|
||||
}
|
||||
|
||||
/** Adds a built-in function to the specified program. */
|
||||
function addFunction(program: Program, name: string, isGeneric: bool = false): void {
|
||||
let prototype: FunctionPrototype = new FunctionPrototype(program, name, null, null);
|
||||
function addFunction(program: Program, name: string, isGeneric: bool = false): FunctionPrototype {
|
||||
let prototype: FunctionPrototype = new FunctionPrototype(program, name, name, null, null);
|
||||
prototype.isBuiltIn = true;
|
||||
if (isGeneric) prototype.isGeneric = true;
|
||||
program.elements.set(name, prototype);
|
||||
return prototype;
|
||||
}
|
||||
|
||||
/** Compiles a call to a built-in function. */
|
||||
|
@ -93,7 +93,8 @@ import {
|
||||
UnaryPrefixExpression,
|
||||
|
||||
// utility
|
||||
hasModifier
|
||||
hasModifier,
|
||||
InterfaceDeclaration
|
||||
|
||||
} from "./ast";
|
||||
import {
|
||||
@ -179,7 +180,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
this.program = program;
|
||||
this.options = options ? options : new Options();
|
||||
this.module = this.options.noEmit ? Module.createStub() : Module.create();
|
||||
const startFunctionTemplate: FunctionPrototype = new FunctionPrototype(program, "start", null);
|
||||
const startFunctionTemplate: FunctionPrototype = new FunctionPrototype(program, "start", "start", null);
|
||||
const startFunctionInstance: Function = new Function(startFunctionTemplate, startFunctionTemplate.internalName, [], [], Type.void, null);
|
||||
this.currentFunction = this.startFunction = startFunctionInstance;
|
||||
this.memoryOffset = new U64(this.options.target == Target.WASM64 ? 8 : 4, 0); // leave space for `null`
|
||||
@ -544,6 +545,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
} else {
|
||||
this.module.addFunction(internalName, typeRef, typesToNativeTypes(instance.additionalLocals), this.module.createBlock(null, <ExpressionRef[]>stmts, NativeType.None));
|
||||
}
|
||||
instance.finalize();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -561,6 +563,11 @@ export class Compiler extends DiagnosticEmitter {
|
||||
this.compileClassDeclaration(<ClassDeclaration>member, []);
|
||||
break;
|
||||
|
||||
case NodeKind.INTERFACE:
|
||||
if ((noTreeShaking || hasModifier(ModifierKind.EXPORT, (<InterfaceDeclaration>member).modifiers)) && !(<InterfaceDeclaration>member).typeParameters.length)
|
||||
this.compileInterfaceDeclaration(<InterfaceDeclaration>member, []);
|
||||
break;
|
||||
|
||||
case NodeKind.ENUM:
|
||||
if (noTreeShaking || hasModifier(ModifierKind.EXPORT, (<EnumDeclaration>member).modifiers))
|
||||
this.compileEnumDeclaration(<EnumDeclaration>member);
|
||||
@ -684,6 +691,10 @@ export class Compiler extends DiagnosticEmitter {
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
|
||||
compileInterfaceDeclaration(declaration: InterfaceDeclaration, typeArguments: TypeNode[], contextualTypeArguments: Map<string,Type> | null = null, alternativeReportNode: Node | null = null): void {
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
|
||||
// memory
|
||||
|
||||
/** Adds a static memory segment with the specified data. */
|
||||
@ -1896,30 +1907,6 @@ export class Compiler extends DiagnosticEmitter {
|
||||
let expr: ExpressionRef;
|
||||
switch (target.kind) {
|
||||
|
||||
case ElementKind.ENUM:
|
||||
case ElementKind.CLASS_PROTOTYPE:
|
||||
case ElementKind.CLASS:
|
||||
case ElementKind.NAMESPACE:
|
||||
if (target.members) {
|
||||
element = target.members.get(propertyName);
|
||||
if (!element) {
|
||||
this.error(DiagnosticCode.Property_0_does_not_exist_on_type_1, propertyAccess.property.range, propertyName);
|
||||
return this.module.createUnreachable();
|
||||
}
|
||||
|
||||
// handle enum values right away
|
||||
if (element.kind == ElementKind.ENUMVALUE) {
|
||||
this.currentType = Type.i32;
|
||||
return (<EnumValue>element).hasConstantValue
|
||||
? this.module.createI32((<EnumValue>element).constantValue)
|
||||
: this.module.createGetGlobal((<EnumValue>element).internalName, NativeType.I32);
|
||||
}
|
||||
} else {
|
||||
this.error(DiagnosticCode.Property_0_does_not_exist_on_type_1, propertyAccess.property.range, propertyName);
|
||||
return this.module.createUnreachable();
|
||||
}
|
||||
break;
|
||||
|
||||
case ElementKind.LOCAL:
|
||||
element = (<Local>target).type.classType;
|
||||
if (!element) {
|
||||
@ -1941,7 +1928,25 @@ export class Compiler extends DiagnosticEmitter {
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error("unexpected target kind");
|
||||
if (target.members) {
|
||||
element = target.members.get(propertyName);
|
||||
if (!element) {
|
||||
this.error(DiagnosticCode.Property_0_does_not_exist_on_type_1, propertyAccess.property.range, propertyName);
|
||||
return this.module.createUnreachable();
|
||||
}
|
||||
|
||||
// handle enum values right away
|
||||
if (element.kind == ElementKind.ENUMVALUE) {
|
||||
this.currentType = Type.i32;
|
||||
return (<EnumValue>element).hasConstantValue
|
||||
? this.module.createI32((<EnumValue>element).constantValue)
|
||||
: this.module.createGetGlobal((<EnumValue>element).internalName, NativeType.I32);
|
||||
}
|
||||
} else {
|
||||
this.error(DiagnosticCode.Property_0_does_not_exist_on_type_1, propertyAccess.property.range, propertyName);
|
||||
return this.module.createUnreachable();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// handle the element
|
||||
@ -1951,8 +1956,18 @@ export class Compiler extends DiagnosticEmitter {
|
||||
return this.module.createGetLocal((<Local>element).index, typeToNativeType(this.currentType = (<Local>element).type));
|
||||
|
||||
case ElementKind.GLOBAL:
|
||||
this.compileGlobal(<Global>element);
|
||||
return this.module.createGetGlobal((<Global>element).internalName, typeToNativeType(this.currentType = <Type>(<Global>element).type));
|
||||
if (!this.compileGlobal(<Global>element))
|
||||
return this.module.createUnreachable();
|
||||
this.currentType = <Type>(<Global>element).type;
|
||||
if ((<Global>element).hasConstantValue)
|
||||
return this.currentType== Type.f32
|
||||
? this.module.createF32((<Global>element).constantFloatValue)
|
||||
: this.currentType == Type.f64
|
||||
? this.module.createF64((<Global>element).constantFloatValue)
|
||||
: this.currentType.isLongInteger
|
||||
? this.module.createI64((<I64>(<Global>element).constantIntegerValue).lo, (<I64>(<Global>element).constantIntegerValue).hi)
|
||||
: this.module.createI32((<I64>(<Global>element).constantIntegerValue).lo);
|
||||
return this.module.createGetGlobal((<Global>element).internalName, typeToNativeType(this.currentType));
|
||||
|
||||
case ElementKind.FUNCTION: // getter
|
||||
if (!(<Function>element).prototype.isGetter) {
|
||||
|
@ -47,7 +47,6 @@ export class Decompiler {
|
||||
this.push("(");
|
||||
let k: Index = _BinaryenFunctionGetNumParams(func);
|
||||
for (let i: Index = 0; i < k; ++i) {
|
||||
console.log("rat");
|
||||
if (i > 0)
|
||||
this.push(", ");
|
||||
this.push("$");
|
||||
|
148
src/program.ts
148
src/program.ts
@ -216,7 +216,7 @@ export class Program extends DiagnosticEmitter {
|
||||
this.error(DiagnosticCode.Duplicate_identifier_0, declaration.identifier.range, internalName);
|
||||
return;
|
||||
}
|
||||
const prototype: ClassPrototype = new ClassPrototype(this, internalName, declaration);
|
||||
const prototype: ClassPrototype = new ClassPrototype(this, declaration.identifier.name, internalName, declaration);
|
||||
this.elements.set(internalName, prototype);
|
||||
|
||||
if (namespace) {
|
||||
@ -306,7 +306,7 @@ export class Program extends DiagnosticEmitter {
|
||||
}
|
||||
} else
|
||||
classPrototype.members = new Map();
|
||||
const staticPrototype: FunctionPrototype = new FunctionPrototype(this, internalName, declaration, null);
|
||||
const staticPrototype: FunctionPrototype = new FunctionPrototype(this, name, internalName, declaration, null);
|
||||
classPrototype.members.set(name, staticPrototype);
|
||||
this.elements.set(internalName, staticPrototype);
|
||||
|
||||
@ -319,7 +319,7 @@ export class Program extends DiagnosticEmitter {
|
||||
}
|
||||
} else
|
||||
classPrototype.instanceMembers = new Map();
|
||||
const instancePrototype: FunctionPrototype = new FunctionPrototype(this, internalName, declaration, classPrototype);
|
||||
const instancePrototype: FunctionPrototype = new FunctionPrototype(this, name, internalName, declaration, classPrototype);
|
||||
classPrototype.instanceMembers.set(name, instancePrototype);
|
||||
}
|
||||
}
|
||||
@ -455,7 +455,7 @@ export class Program extends DiagnosticEmitter {
|
||||
this.error(DiagnosticCode.Duplicate_identifier_0, declaration.identifier.range, internalName);
|
||||
return;
|
||||
}
|
||||
const prototype: FunctionPrototype = new FunctionPrototype(this, internalName, declaration, null);
|
||||
const prototype: FunctionPrototype = new FunctionPrototype(this, declaration.identifier.name, internalName, declaration, null);
|
||||
this.elements.set(internalName, prototype);
|
||||
|
||||
if (namespace) {
|
||||
@ -531,7 +531,7 @@ export class Program extends DiagnosticEmitter {
|
||||
|
||||
private initializeInterface(declaration: InterfaceDeclaration, namespace: Element | null = null): void {
|
||||
const internalName: string = declaration.internalName;
|
||||
const prototype: InterfacePrototype = new InterfacePrototype(this, internalName, declaration);
|
||||
const prototype: InterfacePrototype = new InterfacePrototype(this, declaration.identifier.name, internalName, declaration);
|
||||
|
||||
if (this.elements.has(internalName)) {
|
||||
this.error(DiagnosticCode.Duplicate_identifier_0, declaration.identifier.range, internalName);
|
||||
@ -1024,6 +1024,18 @@ export class Global extends Element {
|
||||
}
|
||||
this.type = type; // resolved later if `null`
|
||||
}
|
||||
|
||||
withConstantIntegerValue(lo: i32, hi: i32): this {
|
||||
this.constantIntegerValue = new I64(lo, hi);
|
||||
this.hasConstantValue = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
withConstantFloatValue(value: f64): this {
|
||||
this.constantFloatValue = value;
|
||||
this.hasConstantValue = true;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/** A function parameter. */
|
||||
@ -1070,14 +1082,17 @@ export class FunctionPrototype extends Element {
|
||||
|
||||
/** Declaration reference. */
|
||||
declaration: FunctionDeclaration | null;
|
||||
/** Class prototype reference. */
|
||||
/** If an instance method, the class prototype reference. */
|
||||
classPrototype: ClassPrototype | null;
|
||||
/** Resolved instances. */
|
||||
instances: Map<string,Function> = new Map();
|
||||
/** Simple name. */
|
||||
simpleName: string;
|
||||
|
||||
/** Constructs a new function prototype. */
|
||||
constructor(program: Program, internalName: string, declaration: FunctionDeclaration | null, classPrototype: ClassPrototype | null = null) {
|
||||
constructor(program: Program, simpleName: string, internalName: string, declaration: FunctionDeclaration | null, classPrototype: ClassPrototype | null = null) {
|
||||
super(program, internalName);
|
||||
this.simpleName = simpleName;
|
||||
if (this.declaration = declaration) {
|
||||
if (this.declaration.modifiers)
|
||||
for (let i: i32 = 0, k: i32 = this.declaration.modifiers.length; i < k; ++i) {
|
||||
@ -1142,7 +1157,7 @@ export class FunctionPrototype extends Element {
|
||||
} else
|
||||
return null;
|
||||
} else
|
||||
return null; // TODO: infer type? (currently reported by parser)
|
||||
return null;
|
||||
}
|
||||
|
||||
// resolve return type
|
||||
@ -1155,7 +1170,7 @@ export class FunctionPrototype extends Element {
|
||||
else
|
||||
return null;
|
||||
} else
|
||||
return null; // TODO: infer type? (currently reported by parser)
|
||||
return null;
|
||||
|
||||
let internalName: string = this.internalName;
|
||||
if (instanceKey.length)
|
||||
@ -1168,17 +1183,20 @@ export class FunctionPrototype extends Element {
|
||||
resolveInclTypeArguments(typeArgumentNodes: TypeNode[] | null, contextualTypeArguments: Map<string,Type> | null, alternativeReportNode: Node | null): Function | null {
|
||||
let resolvedTypeArguments: Type[] | null;
|
||||
if (this.isGeneric) {
|
||||
assert(typeArgumentNodes != null && typeArgumentNodes.length != 0);
|
||||
if (!this.declaration)
|
||||
throw new Error("missing declaration");
|
||||
resolvedTypeArguments = this.program.resolveTypeArguments(this.declaration.typeParameters, typeArgumentNodes, contextualTypeArguments, alternativeReportNode);
|
||||
if (!resolvedTypeArguments)
|
||||
return null;
|
||||
} else {
|
||||
// TODO: check typeArgumentNodes being empty
|
||||
assert(typeArgumentNodes == null || typeArgumentNodes.length == 0);
|
||||
resolvedTypeArguments = [];
|
||||
}
|
||||
return this.resolve(resolvedTypeArguments, contextualTypeArguments);
|
||||
}
|
||||
|
||||
toString(): string { return this.simpleName; }
|
||||
}
|
||||
|
||||
/** A resolved function. */
|
||||
@ -1194,7 +1212,7 @@ export class Function extends Element {
|
||||
parameters: Parameter[];
|
||||
/** Concrete return type. */
|
||||
returnType: Type;
|
||||
/** If a method, the concrete class it is a member of. */
|
||||
/** If an instance method, the concrete class it is a member of. */
|
||||
instanceMethodOf: Class | null;
|
||||
/** Map of locals by name. */
|
||||
locals: Map<string,Local> = new Map();
|
||||
@ -1203,7 +1221,7 @@ export class Function extends Element {
|
||||
/** Current break context label. */
|
||||
breakContext: string | null = null;
|
||||
/** Contextual type arguments. */
|
||||
contextualTypeArguments: Map<string,Type> = new Map();
|
||||
contextualTypeArguments: Map<string,Type> | null;
|
||||
|
||||
private nextBreakId: i32 = 0;
|
||||
private breakStack: i32[] | null = null;
|
||||
@ -1219,19 +1237,21 @@ export class Function extends Element {
|
||||
this.flags = prototype.flags;
|
||||
let localIndex: i32 = 0;
|
||||
if (instanceMethodOf) {
|
||||
assert(this.isInstance);
|
||||
this.locals.set("this", new Local(prototype.program, "this", localIndex++, instanceMethodOf.type));
|
||||
for (let [name, type] of instanceMethodOf.contextualTypeArguments)
|
||||
this.contextualTypeArguments.set(name, type);
|
||||
}
|
||||
if (instanceMethodOf.contextualTypeArguments) {
|
||||
if (!this.contextualTypeArguments) this.contextualTypeArguments = new Map();
|
||||
for (let [name, type] of instanceMethodOf.contextualTypeArguments)
|
||||
this.contextualTypeArguments.set(name, type);
|
||||
}
|
||||
} else
|
||||
assert(!this.isInstance);
|
||||
for (let i: i32 = 0, k: i32 = parameters.length; i < k; ++i) {
|
||||
const parameter: Parameter = parameters[i];
|
||||
this.locals.set(parameter.name, new Local(prototype.program, parameter.name, localIndex++, parameter.type));
|
||||
}
|
||||
}
|
||||
|
||||
/** Tests if this function is an instance method. */
|
||||
get isInstance(): bool { return this.instanceMethodOf != null; }
|
||||
|
||||
/** Adds a local of the specified type, with an optional name. */
|
||||
addLocal(type: Type, name: string | null = null): Local {
|
||||
// if it has a name, check previously as this method will throw otherwise
|
||||
@ -1320,6 +1340,16 @@ export class Function extends Element {
|
||||
this.breakStack = null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Finalizes the function once compiled, releasing no longer needed resources. */
|
||||
finalize(): void {
|
||||
assert(!this.breakStack || !this.breakStack.length, "break stack is not empty");
|
||||
this.breakStack = null;
|
||||
this.breakContext = null;
|
||||
this.tempI32s = this.tempI64s = this.tempF32s = this.tempF64s = null;
|
||||
}
|
||||
|
||||
toString(): string { return this.prototype.simpleName; }
|
||||
}
|
||||
|
||||
/** A yet unresolved instance field prototype. */
|
||||
@ -1380,9 +1410,12 @@ export class ClassPrototype extends Element {
|
||||
instances: Map<string,Class> = new Map();
|
||||
/** Instance member prototypes. */
|
||||
instanceMembers: Map<string,Element> | null = null;
|
||||
/** Simple name. */
|
||||
simpleName: string;
|
||||
|
||||
constructor(program: Program, internalName: string, declaration: ClassDeclaration | null = null) {
|
||||
constructor(program: Program, simpleName: string, internalName: string, declaration: ClassDeclaration | null = null) {
|
||||
super(program, internalName);
|
||||
this.simpleName = simpleName;
|
||||
if (this.declaration = declaration) {
|
||||
if (this.declaration.modifiers) {
|
||||
for (let i: i32 = 0, k: i32 = this.declaration.modifiers.length; i < k; ++i) {
|
||||
@ -1400,29 +1433,62 @@ export class ClassPrototype extends Element {
|
||||
}
|
||||
|
||||
resolve(typeArguments: Type[], contextualTypeArguments: Map<string,Type> | null): Class {
|
||||
const key: string = typesToString(typeArguments, "", "");
|
||||
let instance: Class | null = <Class | null>this.instances.get(key);
|
||||
const instanceKey: string = typesToString(typeArguments, "", "");
|
||||
let instance: Class | null = <Class | null>this.instances.get(instanceKey);
|
||||
if (instance)
|
||||
return instance;
|
||||
if (!this.declaration)
|
||||
const declaration: ClassDeclaration | null = this.declaration;
|
||||
if (!declaration)
|
||||
throw new Error("unexpected instantiation of internal class");
|
||||
throw new Error("not implemented");
|
||||
|
||||
// override call specific contextual type arguments
|
||||
let i: i32, k: i32 = typeArguments.length;
|
||||
if (k) {
|
||||
const inheritedTypeArguments: Map<string,Type> | null = contextualTypeArguments;
|
||||
contextualTypeArguments = new Map();
|
||||
if (inheritedTypeArguments)
|
||||
for (let [name, type] of inheritedTypeArguments)
|
||||
contextualTypeArguments.set(name, type);
|
||||
for (i = 0; i < k; ++i)
|
||||
contextualTypeArguments.set(declaration.typeParameters[i].identifier.name, typeArguments[i]);
|
||||
}
|
||||
|
||||
// TODO: set up instance fields and methods
|
||||
if (this.instanceMembers)
|
||||
for (let [key, member] of this.instanceMembers) {
|
||||
switch (member.kind) {
|
||||
case ElementKind.FIELD_PROTOTYPE: break;
|
||||
case ElementKind.FUNCTION_PROTOTYPE: break;
|
||||
default: throw new Error("unexpected instance member");
|
||||
}
|
||||
}
|
||||
|
||||
let internalName: string = this.internalName;
|
||||
if (instanceKey.length)
|
||||
internalName += "<" + instanceKey + ">";
|
||||
instance = new Class(this, internalName, typeArguments, null); // TODO: base class
|
||||
instance.contextualTypeArguments = contextualTypeArguments;
|
||||
this.instances.set(instanceKey, instance);
|
||||
return instance;
|
||||
}
|
||||
|
||||
resolveInclTypeArguments(typeArgumentNodes: TypeNode[] | null, contextualTypeArguments: Map<string,Type> | null, alternativeReportNode: Node | null): Class | null {
|
||||
let resolvedTypeArguments: Type[] | null;
|
||||
if (this.isGeneric) {
|
||||
assert(typeArgumentNodes != null && typeArgumentNodes.length != 0);
|
||||
if (!this.declaration)
|
||||
throw new Error("not implemented"); // generic built-in
|
||||
throw new Error("missing declaration"); // generic built-in
|
||||
resolvedTypeArguments = this.program.resolveTypeArguments(this.declaration.typeParameters, typeArgumentNodes, contextualTypeArguments, alternativeReportNode);
|
||||
if (!resolvedTypeArguments)
|
||||
return null;
|
||||
} else {
|
||||
// TODO: check typeArgumentNodes being empty
|
||||
assert(typeArgumentNodes == null || !typeArgumentNodes.length);
|
||||
resolvedTypeArguments = [];
|
||||
}
|
||||
return this.resolve(resolvedTypeArguments, contextualTypeArguments);
|
||||
}
|
||||
|
||||
toString(): string { return this.simpleName; }
|
||||
}
|
||||
|
||||
/** A resolved class. */
|
||||
@ -1438,16 +1504,8 @@ export class Class extends Element {
|
||||
type: Type;
|
||||
/** Base class, if applicable. */
|
||||
base: Class | null;
|
||||
/** Contextual type argumentsfor fields and methods. */
|
||||
contextualTypeArguments: Map<string,Type> = new Map();
|
||||
/** Instance fields. */
|
||||
instanceFields: Map<string,Field> | null = null;
|
||||
/** Instance methods. */
|
||||
instanceMethods: Map<string,Function> | null = null;
|
||||
/** Instance getters. */
|
||||
instanceGetters: Map<string,Function> | null = null;
|
||||
/** Instance setters. */
|
||||
instanceSetters: Map<string,Function> | null = null;
|
||||
/** Contextual type arguments for fields and methods. */
|
||||
contextualTypeArguments: Map<string,Type> | null = null;
|
||||
|
||||
/** Constructs a new class. */
|
||||
constructor(prototype: ClassPrototype, internalName: string, typeArguments: Type[] = [], base: Class | null = null) {
|
||||
@ -1459,9 +1517,11 @@ export class Class extends Element {
|
||||
this.base = base;
|
||||
|
||||
// inherit contextual type arguments from base class
|
||||
if (base)
|
||||
if (base && base.contextualTypeArguments) {
|
||||
if (!this.contextualTypeArguments) this.contextualTypeArguments = new Map();
|
||||
for (let [name, type] of base.contextualTypeArguments)
|
||||
this.contextualTypeArguments.set(name, type);
|
||||
}
|
||||
|
||||
// apply instance-specific contextual type arguments
|
||||
const declaration: ClassDeclaration | null = this.prototype.declaration;
|
||||
@ -1469,14 +1529,16 @@ export class Class extends Element {
|
||||
const typeParameters: TypeParameter[] = declaration.typeParameters;
|
||||
if (typeParameters.length != typeArguments.length)
|
||||
throw new Error("unexpected type argument count mismatch");
|
||||
for (let i: i32 = 0, k: i32 = typeArguments.length; i < k; ++i)
|
||||
this.contextualTypeArguments.set(typeParameters[i].identifier.name, typeArguments[i]);
|
||||
const k: i32 = typeArguments.length;
|
||||
if (k) {
|
||||
if (!this.contextualTypeArguments) this.contextualTypeArguments = new Map();
|
||||
for (let i: i32 = 0; i < k; ++i)
|
||||
this.contextualTypeArguments.set(typeParameters[i].identifier.name, typeArguments[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
toString(): string { return this.prototype.simpleName; }
|
||||
}
|
||||
|
||||
/** A yet unresolved interface. */
|
||||
@ -1488,8 +1550,8 @@ export class InterfacePrototype extends ClassPrototype {
|
||||
declaration: InterfaceDeclaration | null; // more specific
|
||||
|
||||
/** Constructs a new interface prototype. */
|
||||
constructor(program: Program, internalName: string, declaration: InterfaceDeclaration | null = null) {
|
||||
super(program, internalName, declaration);
|
||||
constructor(program: Program, simpleName: string, internalName: string, declaration: InterfaceDeclaration | null = null) {
|
||||
super(program, simpleName, internalName, declaration);
|
||||
}
|
||||
}
|
||||
|
||||
|
79
std/assembly.d.ts
vendored
79
std/assembly.d.ts
vendored
@ -29,6 +29,85 @@ declare type f32 = number;
|
||||
/** A 64-bit float. */
|
||||
declare type f64 = number;
|
||||
|
||||
/** Converts any other numeric value to an 8-bit signed integer. */
|
||||
declare function i8(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i8;
|
||||
declare namespace i8 {
|
||||
export const MIN_VALUE: i8;
|
||||
export const MAX_VALUE: i8;
|
||||
}
|
||||
/** Converts any other numeric value to a 16-bit signed integer. */
|
||||
declare function i16(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i8;
|
||||
declare namespace i16 {
|
||||
export const MIN_VALUE: i16;
|
||||
export const MAX_VALUE: i16;
|
||||
}
|
||||
/** Converts any other numeric value to a 32-bit signed integer. */
|
||||
declare function i32(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i32;
|
||||
declare namespace i32 {
|
||||
export const MIN_VALUE: i32;
|
||||
export const MAX_VALUE: i32;
|
||||
}
|
||||
/** Converts any other numeric value to a 64-bit signed integer. */
|
||||
declare function i64(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i64;
|
||||
declare namespace i64 {
|
||||
export const MIN_VALUE: i64;
|
||||
export const MAX_VALUE: i64;
|
||||
}
|
||||
/** Converts any other numeric value to a 32-bit (in WASM32) respectivel 64-bit (in WASM64) signed integer. */
|
||||
declare function isize(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): isize;
|
||||
declare namespace isize {
|
||||
export const MIN_VALUE: isize;
|
||||
export const MAX_VALUE: isize;
|
||||
}
|
||||
/** Converts any other numeric value to an 8-bit unsigned integer. */
|
||||
declare function u8(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i8;
|
||||
declare namespace u8 {
|
||||
export const MIN_VALUE: u8;
|
||||
export const MAX_VALUE: u8;
|
||||
}
|
||||
/** Converts any other numeric value to a 16-bit unsigned integer. */
|
||||
declare function u16(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i8;
|
||||
declare namespace u16 {
|
||||
export const MIN_VALUE: u16;
|
||||
export const MAX_VALUE: u16;
|
||||
}
|
||||
/** Converts any other numeric value to a 32-bit unsigned integer. */
|
||||
declare function u32(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i32;
|
||||
declare namespace u32 {
|
||||
export const MIN_VALUE: u32;
|
||||
export const MAX_VALUE: u32;
|
||||
}
|
||||
/** Converts any other numeric value to a 64-bit unsigned integer. */
|
||||
declare function u64(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i64;
|
||||
declare namespace u64 {
|
||||
export const MIN_VALUE: u64;
|
||||
export const MAX_VALUE: u64;
|
||||
}
|
||||
/** Converts any other numeric value to a 32-bit (in WASM32) respectivel 64-bit (in WASM64) unsigned integer. */
|
||||
declare function usize(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): isize;
|
||||
declare namespace usize {
|
||||
export const MIN_VALUE: usize;
|
||||
export const MAX_VALUE: usize;
|
||||
}
|
||||
/** Converts any other numeric value to a 1-bit unsigned integer. */
|
||||
declare function bool(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): bool;
|
||||
declare namespace bool {
|
||||
export const MIN_VALUE: bool;
|
||||
export const MAX_VALUE: bool;
|
||||
}
|
||||
/** Converts any other numeric value to a 32-bit float. */
|
||||
declare function f32(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): f32;
|
||||
declare namespace f32 {
|
||||
export const MIN_SAFE_INTEGER: f32;
|
||||
export const MAX_SAFE_INTEGER: f32;
|
||||
}
|
||||
/** Converts any other numeric value to a 64-bit float. */
|
||||
declare function f64(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): f64;
|
||||
declare namespace f64 {
|
||||
export const MIN_SAFE_INTEGER: f64;
|
||||
export const MAX_SAFE_INTEGER: f64;
|
||||
}
|
||||
|
||||
// Built-ins
|
||||
|
||||
/** Performs the sign-agnostic count leading zero bits operation on a 32-bit or 64-bit integer. All zero bits are considered leading if the value is zero. */
|
||||
|
75
std/portable.d.ts
vendored
75
std/portable.d.ts
vendored
@ -10,16 +10,83 @@
|
||||
// of 2^53-1) and instead require a compatibility layer to work in JS as well. See: src/util/i64.ts
|
||||
|
||||
declare type i8 = number;
|
||||
declare type u8 = number;
|
||||
declare type i16 = number;
|
||||
declare type u16 = number;
|
||||
declare type i32 = number;
|
||||
declare type u32 = number;
|
||||
declare type isize = number;
|
||||
declare type u8 = number;
|
||||
declare type u16 = number;
|
||||
declare type u32 = number;
|
||||
declare type bool = boolean;
|
||||
declare type usize = number;
|
||||
declare type f32 = number;
|
||||
declare type f64 = number;
|
||||
declare type bool = boolean;
|
||||
|
||||
/** Converts any other numeric value to an 8-bit signed integer. */
|
||||
declare function i8(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): i8;
|
||||
declare namespace i8 {
|
||||
export const MIN_VALUE: i8;
|
||||
export const MAX_VALUE: i8;
|
||||
}
|
||||
/** Converts any other numeric value to a 16-bit signed integer. */
|
||||
declare function i16(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): i8;
|
||||
declare namespace i16 {
|
||||
export const MIN_VALUE: i16;
|
||||
export const MAX_VALUE: i16;
|
||||
}
|
||||
/** Converts any other numeric value to a 32-bit signed integer. */
|
||||
declare function i32(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): i32;
|
||||
declare namespace i32 {
|
||||
export const MIN_VALUE: i32;
|
||||
export const MAX_VALUE: i32;
|
||||
}
|
||||
/** Converts any other numeric value to a 32-bit (in WASM32) respectivel 64-bit (in WASM64) signed integer. */
|
||||
declare function isize(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): isize;
|
||||
declare namespace isize {
|
||||
export const MIN_VALUE: isize;
|
||||
export const MAX_VALUE: isize;
|
||||
}
|
||||
/** Converts any other numeric value to an 8-bit unsigned integer. */
|
||||
declare function u8(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): i8;
|
||||
declare namespace u8 {
|
||||
export const MIN_VALUE: u8;
|
||||
export const MAX_VALUE: u8;
|
||||
}
|
||||
/** Converts any other numeric value to a 16-bit unsigned integer. */
|
||||
declare function u16(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): i8;
|
||||
declare namespace u16 {
|
||||
export const MIN_VALUE: u16;
|
||||
export const MAX_VALUE: u16;
|
||||
}
|
||||
/** Converts any other numeric value to a 32-bit unsigned integer. */
|
||||
declare function u32(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): i32;
|
||||
declare namespace u32 {
|
||||
export const MIN_VALUE: u32;
|
||||
export const MAX_VALUE: u32;
|
||||
}
|
||||
/** Converts any other numeric value to a 32-bit (in WASM32) respectivel 64-bit (in WASM64) unsigned integer. */
|
||||
declare function usize(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): isize;
|
||||
declare namespace usize {
|
||||
export const MIN_VALUE: usize;
|
||||
export const MAX_VALUE: usize;
|
||||
}
|
||||
/** Converts any other numeric value to a 1-bit unsigned integer. */
|
||||
declare function bool(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): bool;
|
||||
declare namespace bool {
|
||||
export const MIN_VALUE: bool;
|
||||
export const MAX_VALUE: bool;
|
||||
}
|
||||
/** Converts any other numeric value to a 32-bit float. */
|
||||
declare function f32(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): f32;
|
||||
declare namespace f32 {
|
||||
export const MIN_SAFE_INTEGER: f32;
|
||||
export const MAX_SAFE_INTEGER: f32;
|
||||
}
|
||||
/** Converts any other numeric value to a 64-bit float. */
|
||||
declare function f64(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): f64;
|
||||
declare namespace f64 {
|
||||
export const MIN_SAFE_INTEGER: f64;
|
||||
export const MAX_SAFE_INTEGER: f64;
|
||||
}
|
||||
|
||||
// Portable built-ins
|
||||
|
||||
|
@ -1,5 +1,60 @@
|
||||
var globalScope = typeof window !== "undefined" && window || typeof global !== "undefined" && global || self;
|
||||
|
||||
Object.defineProperties(
|
||||
globalScope["i8"] = function i8(value) { return value << 24 >> 24; }
|
||||
, {
|
||||
"MIN_VALUE": { value: -128, writable: false },
|
||||
"MAX_VALUE": { value: 127, writable: false }
|
||||
});
|
||||
Object.defineProperties(
|
||||
globalScope["i16"] = function i16(value) { return value << 16 >> 16; }
|
||||
, {
|
||||
"MIN_VALUE": { value: -32768, writable: false },
|
||||
"MAX_VALUE": { value: 32767, writable: false }
|
||||
});
|
||||
Object.defineProperties(
|
||||
globalScope["i32"] = globalScope["isize"] = function i32(value) { return value | 0; }
|
||||
, {
|
||||
"MIN_VALUE": { value: -2147483648, writable: false },
|
||||
"MAX_VALUE": { value: 2147483647, writable: false }
|
||||
});
|
||||
Object.defineProperties(
|
||||
globalScope["u8"] = function u8(value) { return value & 0xff; }
|
||||
, {
|
||||
"MIN_VALUE": { value: 0, writable: false },
|
||||
"MAX_VALUE": { value: 255, writable: false }
|
||||
});
|
||||
Object.defineProperties(
|
||||
globalScope["u16"] = function u16(value) { return value & 0xffff; }
|
||||
, {
|
||||
"MIN_VALUE": { value: 0, writable: false },
|
||||
"MAX_VALUE": { value: 65535, writable: false }
|
||||
});
|
||||
Object.defineProperties(
|
||||
globalScope["u32"] = globalScope["usize"] = function u32(value) { return value >>> 0; }
|
||||
, {
|
||||
"MIN_VALUE": { value: 0, writable: false },
|
||||
"MAX_VALUE": { value: 4294967295, writable: false }
|
||||
});
|
||||
Object.defineProperties(
|
||||
globalScope["bool"] = function bool(value) { return Boolean(value); }
|
||||
, {
|
||||
"MIN_VALUE": { value: 0, writable: false },
|
||||
"MAX_VALUE": { value: 1, writable: false }
|
||||
});
|
||||
Object.defineProperties(
|
||||
globalScope["f32"] = function f32(value) { return Math.fround(value); }
|
||||
, {
|
||||
"MIN_SAFE_INTEGER": { value: -16777215, writable: false },
|
||||
"MAX_SAFE_INTEGER": { value: 16777215, writable: false }
|
||||
});
|
||||
Object.defineProperties(
|
||||
globalScope["f64"] = function f64(value) { return +value; }
|
||||
, {
|
||||
"MIN_SAFE_INTEGER": { value: -9007199254740991, writable: false },
|
||||
"MAX_SAFE_INTEGER": { value: 9007199254740991, writable: false }
|
||||
});
|
||||
|
||||
globalScope["clz"] = Math.clz32;
|
||||
globalScope["abs"] = Math.abs;
|
||||
globalScope["max"] = Math.max;
|
||||
|
3
std/tsconfig.json
Normal file
3
std/tsconfig.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "../tsconfig-base.json"
|
||||
}
|
@ -43,6 +43,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
[program.exports]
|
||||
|
||||
;)
|
||||
|
@ -846,6 +846,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
binary/b
|
||||
binary/i
|
||||
binary/I
|
||||
|
@ -1063,6 +1063,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
builtins/b
|
||||
builtins/i
|
||||
builtins/I
|
||||
|
@ -71,6 +71,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
class/Animal
|
||||
class/Animal.MAX
|
||||
class/Animal.add
|
||||
|
@ -36,6 +36,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
declare/external
|
||||
[program.exports]
|
||||
declare/external
|
||||
|
@ -81,6 +81,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
do/loopDo
|
||||
do/loopDoInDo
|
||||
[program.exports]
|
||||
|
@ -66,6 +66,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
enum/Implicit
|
||||
enum/Explicit
|
||||
enum/Mixed
|
||||
|
@ -60,6 +60,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
export/add
|
||||
export/sub
|
||||
export/a
|
||||
|
@ -177,6 +177,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
for/i
|
||||
[program.exports]
|
||||
|
||||
|
@ -338,6 +338,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
../../examples/game-of-life/assembly/game-of-life/w
|
||||
../../examples/game-of-life/assembly/game-of-life/h
|
||||
../../examples/game-of-life/assembly/game-of-life/s
|
||||
|
@ -1219,6 +1219,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
../../examples/i64-polyfill/assembly/i64/lo
|
||||
../../examples/i64-polyfill/assembly/i64/hi
|
||||
../../examples/i64-polyfill/assembly/i64/getLo
|
||||
|
@ -76,6 +76,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
if/ifThenElse
|
||||
if/ifThen
|
||||
if/ifThenElseBlock
|
||||
|
@ -71,6 +71,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
export/add
|
||||
export/sub
|
||||
export/a
|
||||
|
9
tests/compiler/limits.optimized.wast
Normal file
9
tests/compiler/limits.optimized.wast
Normal file
@ -0,0 +1,9 @@
|
||||
(module
|
||||
(type $v (func))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $start (; 0 ;) (type $v)
|
||||
(nop)
|
||||
)
|
||||
)
|
26
tests/compiler/limits.ts
Normal file
26
tests/compiler/limits.ts
Normal file
@ -0,0 +1,26 @@
|
||||
i8.MIN_VALUE;
|
||||
i8.MAX_VALUE;
|
||||
i16.MIN_VALUE;
|
||||
i16.MAX_VALUE;
|
||||
i32.MIN_VALUE;
|
||||
i32.MAX_VALUE;
|
||||
i64.MIN_VALUE;
|
||||
i64.MAX_VALUE;
|
||||
isize.MIN_VALUE;
|
||||
isize.MAX_VALUE;
|
||||
u8.MIN_VALUE;
|
||||
u8.MAX_VALUE;
|
||||
u16.MIN_VALUE;
|
||||
u16.MAX_VALUE;
|
||||
u32.MIN_VALUE;
|
||||
u32.MAX_VALUE;
|
||||
u64.MIN_VALUE;
|
||||
u64.MAX_VALUE;
|
||||
usize.MIN_VALUE;
|
||||
usize.MAX_VALUE;
|
||||
bool.MIN_VALUE;
|
||||
bool.MAX_VALUE;
|
||||
f32.MIN_SAFE_INTEGER;
|
||||
f32.MAX_SAFE_INTEGER;
|
||||
f64.MIN_SAFE_INTEGER;
|
||||
f64.MAX_SAFE_INTEGER;
|
155
tests/compiler/limits.wast
Normal file
155
tests/compiler/limits.wast
Normal file
@ -0,0 +1,155 @@
|
||||
(module
|
||||
(type $v (func))
|
||||
(global $i8.MIN_VALUE (mut i32) (i32.const -128))
|
||||
(global $i8.MAX_VALUE (mut i32) (i32.const 127))
|
||||
(global $i16.MIN_VALUE (mut i32) (i32.const -32768))
|
||||
(global $i16.MAX_VALUE (mut i32) (i32.const 32767))
|
||||
(global $i32.MIN_VALUE (mut i32) (i32.const -2147483648))
|
||||
(global $i32.MAX_VALUE (mut i32) (i32.const 2147483647))
|
||||
(global $i64.MIN_VALUE (mut i64) (i64.const -9223372036854775808))
|
||||
(global $i64.MAX_VALUE (mut i64) (i64.const 9223372036854775807))
|
||||
(global $u8.MIN_VALUE (mut i32) (i32.const 0))
|
||||
(global $u8.MAX_VALUE (mut i32) (i32.const 255))
|
||||
(global $u16.MIN_VALUE (mut i32) (i32.const 0))
|
||||
(global $u16.MAX_VALUE (mut i32) (i32.const 65535))
|
||||
(global $u32.MIN_VALUE (mut i32) (i32.const 0))
|
||||
(global $u32.MAX_VALUE (mut i32) (i32.const -1))
|
||||
(global $u64.MIN_VALUE (mut i64) (i64.const 0))
|
||||
(global $u64.MAX_VALUE (mut i64) (i64.const -1))
|
||||
(global $bool.MIN_VALUE (mut i32) (i32.const 0))
|
||||
(global $bool.MAX_VALUE (mut i32) (i32.const 1))
|
||||
(global $f32.MIN_SAFE_INTEGER (mut f32) (f32.const -16777215))
|
||||
(global $f32.MAX_SAFE_INTEGER (mut f32) (f32.const 16777215))
|
||||
(global $f64.MIN_SAFE_INTEGER (mut f64) (f64.const -9007199254740991))
|
||||
(global $f64.MAX_SAFE_INTEGER (mut f64) (f64.const 9007199254740991))
|
||||
(global $HEAP_START i32 (i32.const 4))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $start (; 0 ;) (type $v)
|
||||
(drop
|
||||
(i32.const -128)
|
||||
)
|
||||
(drop
|
||||
(i32.const 127)
|
||||
)
|
||||
(drop
|
||||
(i32.const -32768)
|
||||
)
|
||||
(drop
|
||||
(i32.const 32767)
|
||||
)
|
||||
(drop
|
||||
(i32.const -2147483648)
|
||||
)
|
||||
(drop
|
||||
(i32.const 2147483647)
|
||||
)
|
||||
(drop
|
||||
(i64.const -9223372036854775808)
|
||||
)
|
||||
(drop
|
||||
(i64.const 9223372036854775807)
|
||||
)
|
||||
(drop
|
||||
(i32.const -2147483648)
|
||||
)
|
||||
(drop
|
||||
(i32.const 2147483647)
|
||||
)
|
||||
(drop
|
||||
(i32.const 0)
|
||||
)
|
||||
(drop
|
||||
(i32.const 255)
|
||||
)
|
||||
(drop
|
||||
(i32.const 0)
|
||||
)
|
||||
(drop
|
||||
(i32.const 65535)
|
||||
)
|
||||
(drop
|
||||
(i32.const 0)
|
||||
)
|
||||
(drop
|
||||
(i32.const -1)
|
||||
)
|
||||
(drop
|
||||
(i64.const 0)
|
||||
)
|
||||
(drop
|
||||
(i64.const -1)
|
||||
)
|
||||
(drop
|
||||
(i32.const 0)
|
||||
)
|
||||
(drop
|
||||
(i32.const -1)
|
||||
)
|
||||
(drop
|
||||
(i32.const 0)
|
||||
)
|
||||
(drop
|
||||
(i32.const 1)
|
||||
)
|
||||
(drop
|
||||
(f32.const -16777215)
|
||||
)
|
||||
(drop
|
||||
(f32.const 16777215)
|
||||
)
|
||||
(drop
|
||||
(f64.const -9007199254740991)
|
||||
)
|
||||
(drop
|
||||
(f64.const 9007199254740991)
|
||||
)
|
||||
)
|
||||
)
|
||||
(;
|
||||
[program.elements]
|
||||
clz
|
||||
ctz
|
||||
popcnt
|
||||
rotl
|
||||
rotr
|
||||
abs
|
||||
ceil
|
||||
copysign
|
||||
floor
|
||||
max
|
||||
min
|
||||
nearest
|
||||
sqrt
|
||||
trunc
|
||||
current_memory
|
||||
grow_memory
|
||||
unreachable
|
||||
load
|
||||
store
|
||||
reinterpret
|
||||
select
|
||||
sizeof
|
||||
changetype
|
||||
isNaN
|
||||
isFinite
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
[program.exports]
|
||||
|
||||
;)
|
@ -169,6 +169,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
[program.exports]
|
||||
|
||||
;)
|
||||
|
@ -285,6 +285,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
logical/i
|
||||
logical/I
|
||||
logical/f
|
||||
|
@ -2083,6 +2083,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
memcpy/memcpy
|
||||
memcpy/base
|
||||
memcpy/dest
|
||||
|
@ -47,6 +47,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
namespace/Outer
|
||||
namespace/Outer.Inner
|
||||
namespace/Outer.Inner.aVar
|
||||
|
@ -76,6 +76,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
export/add
|
||||
export/sub
|
||||
export/a
|
||||
|
@ -175,6 +175,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
switch/doSwitch
|
||||
switch/doSwitchDefaultFirst
|
||||
switch/doSwitchDefaultOmitted
|
||||
|
@ -63,6 +63,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
ternary/a
|
||||
[program.exports]
|
||||
|
||||
|
@ -358,6 +358,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
tlsf/fls
|
||||
tlsf/ffs
|
||||
tlsf/ALIGN_SIZE_LOG2
|
||||
|
@ -651,6 +651,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
unary/i
|
||||
unary/I
|
||||
unary/f
|
||||
|
@ -90,6 +90,19 @@
|
||||
assert
|
||||
parseInt
|
||||
parseFloat
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
bool
|
||||
f32
|
||||
f64
|
||||
isize
|
||||
usize
|
||||
while/loopWhile
|
||||
while/loopWhileInWhile
|
||||
[program.exports]
|
||||
|
Loading…
x
Reference in New Issue
Block a user