mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-19 09:51:33 +00:00
Initial implementation of 'new'
This doesn't yet call the constructor or use provided parameters and just allocates raw memory
This commit is contained in:
22
src/ast.ts
22
src/ast.ts
@ -2,7 +2,7 @@ import {
|
|||||||
PATH_DELIMITER,
|
PATH_DELIMITER,
|
||||||
STATIC_DELIMITER,
|
STATIC_DELIMITER,
|
||||||
INSTANCE_DELIMITER
|
INSTANCE_DELIMITER
|
||||||
} from "./constants";
|
} from "./program";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Token,
|
Token,
|
||||||
@ -1508,16 +1508,6 @@ export function hasDecorator(name: string, decorators: Decorator[] | null): bool
|
|||||||
return getFirstDecorator(name, decorators) != null;
|
return getFirstDecorator(name, decorators) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Mangles a path to an internal path. */
|
|
||||||
export function mangleInternalPath(path: string): string {
|
|
||||||
// not necessary with current config
|
|
||||||
// if (PATH_DELIMITER.charCodeAt(0) != CharCode.SLASH)
|
|
||||||
// path = path.replace("/", PATH_DELIMITER);
|
|
||||||
// if (PARENT_SUBST != "..")
|
|
||||||
// path = path.replace("..", PARENT_SUBST);
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Mangles a declaration's name to an internal name. */
|
/** Mangles a declaration's name to an internal name. */
|
||||||
export function mangleInternalName(declaration: DeclarationStatement, asGlobal: bool = false): string {
|
export function mangleInternalName(declaration: DeclarationStatement, asGlobal: bool = false): string {
|
||||||
var name = declaration.name.name;
|
var name = declaration.name.name;
|
||||||
@ -1535,3 +1525,13 @@ export function mangleInternalName(declaration: DeclarationStatement, asGlobal:
|
|||||||
return name;
|
return name;
|
||||||
return declaration.range.source.internalPath + PATH_DELIMITER + name;
|
return declaration.range.source.internalPath + PATH_DELIMITER + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Mangles an external to an internal path. */
|
||||||
|
export function mangleInternalPath(path: string): string {
|
||||||
|
// not necessary with current config
|
||||||
|
// if (PATH_DELIMITER.charCodeAt(0) != CharCode.SLASH)
|
||||||
|
// path = path.replace("/", PATH_DELIMITER);
|
||||||
|
// if (PARENT_SUBST != "..")
|
||||||
|
// path = path.replace("..", PARENT_SUBST);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
@ -37,7 +37,8 @@ import {
|
|||||||
Global,
|
Global,
|
||||||
FunctionPrototype,
|
FunctionPrototype,
|
||||||
Local,
|
Local,
|
||||||
ElementFlags
|
ElementFlags,
|
||||||
|
Class
|
||||||
} from "./program";
|
} from "./program";
|
||||||
|
|
||||||
/** Initializes the specified program with built-in constants and functions. */
|
/** Initializes the specified program with built-in constants and functions. */
|
||||||
@ -1824,3 +1825,26 @@ export function compileCall(compiler: Compiler, prototype: FunctionPrototype, ty
|
|||||||
compiler.error(DiagnosticCode.Operation_not_supported, reportNode.range);
|
compiler.error(DiagnosticCode.Operation_not_supported, reportNode.range);
|
||||||
return module.createUnreachable();
|
return module.createUnreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Compiles an allocation of the specified class. */
|
||||||
|
export function compileAllocate(compiler: Compiler, cls: Class, reportNode: Node): ExpressionRef {
|
||||||
|
var program = cls.program;
|
||||||
|
var prototype = program.elements.get(compiler.options.allocateImpl);
|
||||||
|
if (prototype) {
|
||||||
|
var instance = (<FunctionPrototype>prototype).resolve(); // reports
|
||||||
|
if (instance) {
|
||||||
|
var usizeType = program.target == Target.WASM64 ? Type.usize64 : Type.usize32;
|
||||||
|
if (!instance.is(ElementFlags.GENERIC) && instance.returnType == usizeType && instance.parameters.length == 1 && instance.parameters[0].type == usizeType) {
|
||||||
|
if (compiler.compileFunction(instance)) // reports
|
||||||
|
return compiler.makeCall(instance, [
|
||||||
|
program.target == Target.WASM64
|
||||||
|
? compiler.module.createI64(cls.currentMemoryOffset)
|
||||||
|
: compiler.module.createI32(cls.currentMemoryOffset)
|
||||||
|
]);
|
||||||
|
} else
|
||||||
|
program.error(DiagnosticCode.Implementation_0_must_match_the_signature_1, reportNode.range, compiler.options.allocateImpl, "(size: usize): usize");
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
program.error(DiagnosticCode.Cannot_find_name_0, reportNode.range, compiler.options.allocateImpl);
|
||||||
|
return compiler.module.createUnreachable();
|
||||||
|
}
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
import {
|
import {
|
||||||
compileCall as compileBuiltinCall,
|
compileCall as compileBuiltinCall,
|
||||||
compileGetConstant as compileBuiltinGetConstant
|
compileGetConstant as compileBuiltinGetConstant,
|
||||||
|
compileAllocate as compileBuiltinAllocate
|
||||||
} from "./builtins";
|
} from "./builtins";
|
||||||
|
|
||||||
import {
|
|
||||||
PATH_DELIMITER
|
|
||||||
} from "./constants";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DiagnosticCode,
|
DiagnosticCode,
|
||||||
DiagnosticEmitter
|
DiagnosticEmitter
|
||||||
@ -45,7 +42,8 @@ import {
|
|||||||
VariableLikeElement,
|
VariableLikeElement,
|
||||||
Flow,
|
Flow,
|
||||||
FlowFlags,
|
FlowFlags,
|
||||||
ElementFlags
|
ElementFlags,
|
||||||
|
PATH_DELIMITER
|
||||||
} from "./program";
|
} from "./program";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -146,6 +144,10 @@ export class Options {
|
|||||||
noAssert: bool = false;
|
noAssert: bool = false;
|
||||||
/** If true, does not set up a memory. */
|
/** If true, does not set up a memory. */
|
||||||
noMemory: bool = false;
|
noMemory: bool = false;
|
||||||
|
/** Memory allocation implementation to use. */
|
||||||
|
allocateImpl: string = "allocate_memory";
|
||||||
|
/** Memory freeing implementation to use. */
|
||||||
|
freeImpl: string = "free_memory";
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Indicates the desired kind of a conversion. */
|
/** Indicates the desired kind of a conversion. */
|
||||||
@ -545,15 +547,15 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
var declaration = instance.prototype.declaration;
|
var declaration = instance.prototype.declaration;
|
||||||
if (!declaration)
|
|
||||||
throw new Error("declaration expected"); // built-ins are not compiled here
|
|
||||||
|
|
||||||
if (instance.is(ElementFlags.DECLARED)) {
|
if (instance.is(ElementFlags.DECLARED)) {
|
||||||
if (declaration.statements) {
|
if (declaration && declaration.statements) {
|
||||||
this.error(DiagnosticCode.An_implementation_cannot_be_declared_in_ambient_contexts, declaration.name.range);
|
this.error(DiagnosticCode.An_implementation_cannot_be_declared_in_ambient_contexts, declaration.name.range);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (!declaration)
|
||||||
|
throw new Error("declaration expected"); // built-ins are not compiled here
|
||||||
if (!declaration.statements) {
|
if (!declaration.statements) {
|
||||||
this.error(DiagnosticCode.Function_implementation_is_missing_or_not_immediately_following_the_declaration, declaration.name.range);
|
this.error(DiagnosticCode.Function_implementation_is_missing_or_not_immediately_following_the_declaration, declaration.name.range);
|
||||||
return false;
|
return false;
|
||||||
@ -566,6 +568,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
// compile statements
|
// compile statements
|
||||||
var stmts: ExpressionRef[] | null = null;
|
var stmts: ExpressionRef[] | null = null;
|
||||||
if (!instance.is(ElementFlags.DECLARED)) {
|
if (!instance.is(ElementFlags.DECLARED)) {
|
||||||
|
declaration = assert(declaration);
|
||||||
var previousFunction = this.currentFunction;
|
var previousFunction = this.currentFunction;
|
||||||
this.currentFunction = instance;
|
this.currentFunction = instance;
|
||||||
var statements = assert(declaration.statements);
|
var statements = assert(declaration.statements);
|
||||||
@ -601,12 +604,12 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
|
|
||||||
// create the function
|
// create the function
|
||||||
if (instance.is(ElementFlags.DECLARED)) {
|
if (instance.is(ElementFlags.DECLARED)) {
|
||||||
this.module.addFunctionImport(instance.internalName, instance.prototype.namespace ? instance.prototype.namespace.simpleName : "env", declaration.name.name, typeRef);
|
this.module.addFunctionImport(instance.internalName, instance.prototype.namespace ? instance.prototype.namespace.simpleName : "env", instance.simpleName, typeRef);
|
||||||
} else {
|
} else {
|
||||||
this.module.addFunction(instance.internalName, typeRef, typesToNativeTypes(instance.additionalLocals), this.module.createBlock(null, <ExpressionRef[]>stmts, NativeType.None));
|
this.module.addFunction(instance.internalName, typeRef, typesToNativeTypes(instance.additionalLocals), this.module.createBlock(null, <ExpressionRef[]>stmts, NativeType.None));
|
||||||
}
|
}
|
||||||
instance.finalize();
|
instance.finalize();
|
||||||
if (declaration.range.source.isEntry && declaration.isTopLevelExport) {
|
if (declaration && declaration.range.source.isEntry && declaration.isTopLevelExport) {
|
||||||
this.module.addFunctionExport(instance.internalName, declaration.name.name);
|
this.module.addFunctionExport(instance.internalName, declaration.name.name);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -2637,7 +2640,8 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
return this.makeCall(functionInstance, operands);
|
return this.makeCall(functionInstance, operands);
|
||||||
}
|
}
|
||||||
|
|
||||||
private makeCall(functionInstance: Function, operands: ExpressionRef[] | null = null): ExpressionRef {
|
/** Makes a call operation as is. */
|
||||||
|
makeCall(functionInstance: Function, operands: ExpressionRef[] | null = null): ExpressionRef {
|
||||||
if (!(functionInstance.is(ElementFlags.COMPILED) || this.compileFunction(functionInstance)))
|
if (!(functionInstance.is(ElementFlags.COMPILED) || this.compileFunction(functionInstance)))
|
||||||
return this.module.createUnreachable();
|
return this.module.createUnreachable();
|
||||||
|
|
||||||
@ -2791,7 +2795,20 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
compileNewExpression(expression: NewExpression, contextualType: Type): ExpressionRef {
|
compileNewExpression(expression: NewExpression, contextualType: Type): ExpressionRef {
|
||||||
throw new Error("not implemented");
|
var resolved = this.program.resolveExpression(expression.expression, this.currentFunction); // reports
|
||||||
|
if (resolved) {
|
||||||
|
if (resolved.element.kind == ElementKind.CLASS_PROTOTYPE) {
|
||||||
|
var prototype = <ClassPrototype>resolved.element;
|
||||||
|
var instance = prototype.resolveInclTypeArguments(expression.typeArguments, null, expression); // reports
|
||||||
|
if (instance) {
|
||||||
|
// TODO: call constructor
|
||||||
|
this.currentType = instance.type;
|
||||||
|
return compileBuiltinAllocate(this, instance, expression);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
this.error(DiagnosticCode.Cannot_use_new_with_an_expression_whose_type_lacks_a_construct_signature, expression.expression.range);
|
||||||
|
}
|
||||||
|
return this.module.createUnreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
compileParenthesizedExpression(expression: ParenthesizedExpression, contextualType: Type): ExpressionRef {
|
compileParenthesizedExpression(expression: ParenthesizedExpression, contextualType: Type): ExpressionRef {
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
// internal naming scheme
|
|
||||||
|
|
||||||
/** Path delimited inserted between file system levels. */
|
|
||||||
export const PATH_DELIMITER = "/";
|
|
||||||
/** Substitution used to indicate the parent directory. */
|
|
||||||
export const PARENT_SUBST = "..";
|
|
||||||
/** Function name prefix used for getters. */
|
|
||||||
export const GETTER_PREFIX = "get:";
|
|
||||||
/** Function name prefix used for setters. */
|
|
||||||
export const SETTER_PREFIX = "set:";
|
|
||||||
/** Delimiter used between class names and instance members. */
|
|
||||||
export const INSTANCE_DELIMITER = "#";
|
|
||||||
/** Delimiter used between class and namespace names and static members. */
|
|
||||||
export const STATIC_DELIMITER = ".";
|
|
@ -12,6 +12,7 @@ export enum DiagnosticCode {
|
|||||||
Structs_cannot_implement_interfaces = 108,
|
Structs_cannot_implement_interfaces = 108,
|
||||||
Invalid_regular_expression_flags = 109,
|
Invalid_regular_expression_flags = 109,
|
||||||
Type_0_cannot_be_reinterpreted_as_type_1 = 110,
|
Type_0_cannot_be_reinterpreted_as_type_1 = 110,
|
||||||
|
Implementation_0_must_match_the_signature_1 = 111,
|
||||||
Unterminated_string_literal = 1002,
|
Unterminated_string_literal = 1002,
|
||||||
Identifier_expected = 1003,
|
Identifier_expected = 1003,
|
||||||
_0_expected = 1005,
|
_0_expected = 1005,
|
||||||
@ -70,6 +71,7 @@ export enum DiagnosticCode {
|
|||||||
_super_can_only_be_referenced_in_a_derived_class = 2335,
|
_super_can_only_be_referenced_in_a_derived_class = 2335,
|
||||||
Property_0_does_not_exist_on_type_1 = 2339,
|
Property_0_does_not_exist_on_type_1 = 2339,
|
||||||
Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures = 2349,
|
Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures = 2349,
|
||||||
|
Cannot_use_new_with_an_expression_whose_type_lacks_a_construct_signature = 2351,
|
||||||
A_function_whose_declared_type_is_not_void_must_return_a_value = 2355,
|
A_function_whose_declared_type_is_not_void_must_return_a_value = 2355,
|
||||||
The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access = 2357,
|
The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access = 2357,
|
||||||
The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access = 2364,
|
The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access = 2364,
|
||||||
@ -101,6 +103,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
|
|||||||
case 108: return "Structs cannot implement interfaces.";
|
case 108: return "Structs cannot implement interfaces.";
|
||||||
case 109: return "Invalid regular expression flags.";
|
case 109: return "Invalid regular expression flags.";
|
||||||
case 110: return "Type '{0}' cannot be reinterpreted as type '{1}'.";
|
case 110: return "Type '{0}' cannot be reinterpreted as type '{1}'.";
|
||||||
|
case 111: return "Implementation '{0}' must match the signature '{1}'.";
|
||||||
case 1002: return "Unterminated string literal.";
|
case 1002: return "Unterminated string literal.";
|
||||||
case 1003: return "Identifier expected.";
|
case 1003: return "Identifier expected.";
|
||||||
case 1005: return "'{0}' expected.";
|
case 1005: return "'{0}' expected.";
|
||||||
@ -159,6 +162,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
|
|||||||
case 2335: return "'super' can only be referenced in a derived class.";
|
case 2335: return "'super' can only be referenced in a derived class.";
|
||||||
case 2339: return "Property '{0}' does not exist on type '{1}'.";
|
case 2339: return "Property '{0}' does not exist on type '{1}'.";
|
||||||
case 2349: return "Cannot invoke an expression whose type lacks a call signature. Type '{0}' has no compatible call signatures.";
|
case 2349: return "Cannot invoke an expression whose type lacks a call signature. Type '{0}' has no compatible call signatures.";
|
||||||
|
case 2351: return "Cannot use 'new' with an expression whose type lacks a construct signature.";
|
||||||
case 2355: return "A function whose declared type is not 'void' must return a value.";
|
case 2355: return "A function whose declared type is not 'void' must return a value.";
|
||||||
case 2357: return "The operand of an increment or decrement operator must be a variable or a property access.";
|
case 2357: return "The operand of an increment or decrement operator must be a variable or a property access.";
|
||||||
case 2364: return "The left-hand side of an assignment expression must be a variable or a property access.";
|
case 2364: return "The left-hand side of an assignment expression must be a variable or a property access.";
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
"Structs cannot implement interfaces.": 108,
|
"Structs cannot implement interfaces.": 108,
|
||||||
"Invalid regular expression flags.": 109,
|
"Invalid regular expression flags.": 109,
|
||||||
"Type '{0}' cannot be reinterpreted as type '{1}'.": 110,
|
"Type '{0}' cannot be reinterpreted as type '{1}'.": 110,
|
||||||
|
"Implementation '{0}' must match the signature '{1}'.": 111,
|
||||||
|
|
||||||
"Unterminated string literal.": 1002,
|
"Unterminated string literal.": 1002,
|
||||||
"Identifier expected.": 1003,
|
"Identifier expected.": 1003,
|
||||||
@ -70,6 +71,7 @@
|
|||||||
"'super' can only be referenced in a derived class.": 2335,
|
"'super' can only be referenced in a derived class.": 2335,
|
||||||
"Property '{0}' does not exist on type '{1}'.": 2339,
|
"Property '{0}' does not exist on type '{1}'.": 2339,
|
||||||
"Cannot invoke an expression whose type lacks a call signature. Type '{0}' has no compatible call signatures.": 2349,
|
"Cannot invoke an expression whose type lacks a call signature. Type '{0}' has no compatible call signatures.": 2349,
|
||||||
|
"Cannot use 'new' with an expression whose type lacks a construct signature.": 2351,
|
||||||
"A function whose declared type is not 'void' must return a value.": 2355,
|
"A function whose declared type is not 'void' must return a value.": 2355,
|
||||||
"The operand of an increment or decrement operator must be a variable or a property access.": 2357,
|
"The operand of an increment or decrement operator must be a variable or a property access.": 2357,
|
||||||
"The left-hand side of an assignment expression must be a variable or a property access.": 2364,
|
"The left-hand side of an assignment expression must be a variable or a property access.": 2364,
|
||||||
|
@ -6,14 +6,6 @@ import {
|
|||||||
Target
|
Target
|
||||||
} from "./compiler";
|
} from "./compiler";
|
||||||
|
|
||||||
import {
|
|
||||||
PATH_DELIMITER,
|
|
||||||
GETTER_PREFIX,
|
|
||||||
SETTER_PREFIX,
|
|
||||||
STATIC_DELIMITER,
|
|
||||||
INSTANCE_DELIMITER
|
|
||||||
} from "./constants";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DiagnosticCode,
|
DiagnosticCode,
|
||||||
DiagnosticMessage,
|
DiagnosticMessage,
|
||||||
@ -81,6 +73,19 @@ import {
|
|||||||
NativeType
|
NativeType
|
||||||
} from "./module";
|
} from "./module";
|
||||||
|
|
||||||
|
/** Path delimiter inserted between file system levels. */
|
||||||
|
export const PATH_DELIMITER = "/";
|
||||||
|
/** Substitution used to indicate the parent directory. */
|
||||||
|
export const PARENT_SUBST = "..";
|
||||||
|
/** Function name prefix used for getters. */
|
||||||
|
export const GETTER_PREFIX = "get:";
|
||||||
|
/** Function name prefix used for setters. */
|
||||||
|
export const SETTER_PREFIX = "set:";
|
||||||
|
/** Delimiter used between class names and instance members. */
|
||||||
|
export const INSTANCE_DELIMITER = "#";
|
||||||
|
/** Delimiter used between class and namespace names and static members. */
|
||||||
|
export const STATIC_DELIMITER = ".";
|
||||||
|
|
||||||
class QueuedExport {
|
class QueuedExport {
|
||||||
isReExport: bool;
|
isReExport: bool;
|
||||||
referencedName: string;
|
referencedName: string;
|
||||||
|
@ -84,7 +84,14 @@ glob.sync(filter, { cwd: __dirname + "/compiler" }).forEach(filename => {
|
|||||||
externalFunc: function(arg0, arg1, arg2) {
|
externalFunc: function(arg0, arg1, arg2) {
|
||||||
console.log("env.externalFunc called with: " + arg0 + ", " + arg1 + ", " + arg2);
|
console.log("env.externalFunc called with: " + arg0 + ", " + arg1 + ", " + arg2);
|
||||||
},
|
},
|
||||||
externalConst: 1
|
externalConst: 1,
|
||||||
|
allocate_memory: function(size) {
|
||||||
|
console.log("env.allocate_memory called with: " + size);
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
free_memory: function(ptr) {
|
||||||
|
console.log("env.free_memory called with: " + ptr);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
external: {
|
external: {
|
||||||
externalFunc: function(arg0, arg1, arg2) {
|
externalFunc: function(arg0, arg1, arg2) {
|
||||||
|
@ -24,6 +24,6 @@ function getZero(): i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export enum NonConstant {
|
export enum NonConstant {
|
||||||
ZERO = getZero(),
|
ZERO = getZero(), // cannot export a mutable global
|
||||||
ONE
|
ONE // cannot export a mutable global (tsc doesn't allow this)
|
||||||
}
|
}
|
||||||
|
20
tests/compiler/new.optimized.wast
Normal file
20
tests/compiler/new.optimized.wast
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
(module
|
||||||
|
(type $ii (func (param i32) (result i32)))
|
||||||
|
(type $v (func))
|
||||||
|
(import "env" "allocate_memory" (func $new/allocate_memory (param i32) (result i32)))
|
||||||
|
(memory $0 1)
|
||||||
|
(export "test" (func $new/test))
|
||||||
|
(export "memory" (memory $0))
|
||||||
|
(func $new/test (; 1 ;) (type $v)
|
||||||
|
(drop
|
||||||
|
(call $new/allocate_memory
|
||||||
|
(i32.const 4)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(call $new/allocate_memory
|
||||||
|
(i32.const 8)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
15
tests/compiler/new.ts
Normal file
15
tests/compiler/new.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
class Simple {
|
||||||
|
field: i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Generic<T> {
|
||||||
|
field: T;
|
||||||
|
}
|
||||||
|
|
||||||
|
@global
|
||||||
|
declare function allocate_memory(size: usize): usize;
|
||||||
|
|
||||||
|
export function test(): void {
|
||||||
|
var simple = new Simple();
|
||||||
|
var generic = new Generic<f64>();
|
||||||
|
}
|
76
tests/compiler/new.wast
Normal file
76
tests/compiler/new.wast
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
(module
|
||||||
|
(type $ii (func (param i32) (result i32)))
|
||||||
|
(type $v (func))
|
||||||
|
(import "env" "allocate_memory" (func $new/allocate_memory (param i32) (result i32)))
|
||||||
|
(global $HEAP_BASE i32 (i32.const 4))
|
||||||
|
(memory $0 1)
|
||||||
|
(export "test" (func $new/test))
|
||||||
|
(export "memory" (memory $0))
|
||||||
|
(func $new/test (; 1 ;) (type $v)
|
||||||
|
(local $0 i32)
|
||||||
|
(local $1 i32)
|
||||||
|
(set_local $0
|
||||||
|
(call $new/allocate_memory
|
||||||
|
(i32.const 4)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_local $1
|
||||||
|
(call $new/allocate_memory
|
||||||
|
(i32.const 8)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(;
|
||||||
|
[program.elements]
|
||||||
|
GLOBAL: NaN
|
||||||
|
GLOBAL: Infinity
|
||||||
|
FUNCTION_PROTOTYPE: isNaN
|
||||||
|
FUNCTION_PROTOTYPE: isFinite
|
||||||
|
FUNCTION_PROTOTYPE: clz
|
||||||
|
FUNCTION_PROTOTYPE: ctz
|
||||||
|
FUNCTION_PROTOTYPE: popcnt
|
||||||
|
FUNCTION_PROTOTYPE: rotl
|
||||||
|
FUNCTION_PROTOTYPE: rotr
|
||||||
|
FUNCTION_PROTOTYPE: abs
|
||||||
|
FUNCTION_PROTOTYPE: max
|
||||||
|
FUNCTION_PROTOTYPE: min
|
||||||
|
FUNCTION_PROTOTYPE: ceil
|
||||||
|
FUNCTION_PROTOTYPE: floor
|
||||||
|
FUNCTION_PROTOTYPE: copysign
|
||||||
|
FUNCTION_PROTOTYPE: nearest
|
||||||
|
FUNCTION_PROTOTYPE: reinterpret
|
||||||
|
FUNCTION_PROTOTYPE: sqrt
|
||||||
|
FUNCTION_PROTOTYPE: trunc
|
||||||
|
FUNCTION_PROTOTYPE: load
|
||||||
|
FUNCTION_PROTOTYPE: store
|
||||||
|
FUNCTION_PROTOTYPE: sizeof
|
||||||
|
FUNCTION_PROTOTYPE: select
|
||||||
|
FUNCTION_PROTOTYPE: unreachable
|
||||||
|
FUNCTION_PROTOTYPE: current_memory
|
||||||
|
FUNCTION_PROTOTYPE: grow_memory
|
||||||
|
FUNCTION_PROTOTYPE: changetype
|
||||||
|
FUNCTION_PROTOTYPE: assert
|
||||||
|
FUNCTION_PROTOTYPE: i8
|
||||||
|
FUNCTION_PROTOTYPE: i16
|
||||||
|
FUNCTION_PROTOTYPE: i32
|
||||||
|
FUNCTION_PROTOTYPE: i64
|
||||||
|
FUNCTION_PROTOTYPE: u8
|
||||||
|
FUNCTION_PROTOTYPE: u16
|
||||||
|
FUNCTION_PROTOTYPE: u32
|
||||||
|
FUNCTION_PROTOTYPE: u64
|
||||||
|
FUNCTION_PROTOTYPE: bool
|
||||||
|
FUNCTION_PROTOTYPE: f32
|
||||||
|
FUNCTION_PROTOTYPE: f64
|
||||||
|
FUNCTION_PROTOTYPE: isize
|
||||||
|
FUNCTION_PROTOTYPE: usize
|
||||||
|
GLOBAL: HEAP_BASE
|
||||||
|
CLASS_PROTOTYPE: new/Simple
|
||||||
|
CLASS_PROTOTYPE: new/Generic
|
||||||
|
FUNCTION_PROTOTYPE: new/allocate_memory
|
||||||
|
FUNCTION_PROTOTYPE: allocate_memory
|
||||||
|
FUNCTION_PROTOTYPE: new/test
|
||||||
|
[program.exports]
|
||||||
|
FUNCTION_PROTOTYPE: allocate_memory
|
||||||
|
FUNCTION_PROTOTYPE: new/test
|
||||||
|
;)
|
Reference in New Issue
Block a user