mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 15:12:12 +00:00
Add 'instantiate<T>' builtin (like 'new' but from a type), see #349
This commit is contained in:
parent
1d93877e7c
commit
1149abf824
@ -2322,6 +2322,25 @@ export function compileCall(
|
||||
// thus must be used with care. it exists because it *might* be useful in specific scenarios.
|
||||
return module.createCallIndirect(arg0, operandExprs, typeName);
|
||||
}
|
||||
case "instantiate": {
|
||||
if (!(typeArguments && typeArguments.length == 1)) {
|
||||
if (typeArguments && typeArguments.length) compiler.currentType = typeArguments[0];
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_type_arguments_but_got_1,
|
||||
reportNode.range, "1", typeArguments ? typeArguments.length.toString(10) : "0"
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
let classInstance = typeArguments[0].classReference;
|
||||
if (!classInstance) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Operation_not_supported,
|
||||
reportNode.range
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
return compiler.compileInstantiate(classInstance, operands, reportNode);
|
||||
}
|
||||
|
||||
// user-defined diagnostic macros
|
||||
|
||||
|
@ -6651,9 +6651,10 @@ export class Compiler extends DiagnosticEmitter {
|
||||
);
|
||||
}
|
||||
if (!classInstance) return module.createUnreachable();
|
||||
return this.compileInstantiate(classInstance, expression.arguments, expression);
|
||||
}
|
||||
|
||||
var expr: ExpressionRef;
|
||||
|
||||
compileInstantiate(classInstance: Class, argumentExpressions: Expression[], reportNode: Node): ExpressionRef {
|
||||
// traverse to the top-most visible constructor
|
||||
var currentClassInstance: Class | null = classInstance;
|
||||
var constructorInstance: Function | null = null;
|
||||
@ -6663,14 +6664,21 @@ export class Compiler extends DiagnosticEmitter {
|
||||
} while (currentClassInstance = currentClassInstance.base);
|
||||
|
||||
// if a constructor is present, call it with a zero `this`
|
||||
var expr: ExpressionRef;
|
||||
if (constructorInstance) {
|
||||
expr = this.compileCallDirect(constructorInstance, expression.arguments, expression,
|
||||
options.usizeType.toNativeZero(module)
|
||||
expr = this.compileCallDirect(constructorInstance, argumentExpressions, reportNode,
|
||||
this.options.usizeType.toNativeZero(this.module)
|
||||
);
|
||||
|
||||
// otherwise simply allocate a new instance and initialize its fields
|
||||
} else {
|
||||
expr = this.makeAllocate(classInstance, expression);
|
||||
if (argumentExpressions.length) {
|
||||
this.error(
|
||||
DiagnosticCode.Expected_0_arguments_but_got_1,
|
||||
reportNode.range, "0", argumentExpressions.length.toString(10)
|
||||
);
|
||||
}
|
||||
expr = this.makeAllocate(classInstance, reportNode);
|
||||
}
|
||||
|
||||
this.currentType = classInstance.type;
|
||||
|
@ -41,6 +41,7 @@
|
||||
@builtin export declare function assert<T>(isTrueish: T, message?: string): T;
|
||||
@builtin export declare function unchecked<T>(expr: T): T;
|
||||
@builtin export declare function call_indirect<T>(target: void, ...args: void[]): T;
|
||||
@builtin export declare function instantiate<T>(...args: void[]): T;
|
||||
|
||||
@builtin export declare function i8(value: void): i8;
|
||||
export namespace i8 {
|
||||
|
2
std/assembly/index.d.ts
vendored
2
std/assembly/index.d.ts
vendored
@ -112,6 +112,8 @@ declare function changetype<T>(value: any): T;
|
||||
declare function unchecked<T>(value: T): T;
|
||||
/** Emits a `call_indirect` instruction, calling the specified function in the function table by index with the specified arguments. Does result in a runtime error if the arguments do not match the called function. */
|
||||
declare function call_indirect<T>(target: Function | u32, ...args: any[]): T;
|
||||
/** Instantiates a new instance of `T` using the specified constructor arguments. */
|
||||
declare function instantiate<T>(...args: any[]): T;
|
||||
/** Tests if a 32-bit or 64-bit float is `NaN`. */
|
||||
declare function isNaN<T = f32 | f64>(value: T): bool;
|
||||
/** Tests if a 32-bit or 64-bit float is finite, that is not `NaN` or +/-`Infinity`. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user