mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-21 02:31:41 +00:00
Make sure all roots are iterated by delaying builtin generation; Cleanup
This commit is contained in:
@ -2629,8 +2629,7 @@ export function compileCall(
|
||||
|
||||
// gc
|
||||
|
||||
case "gc.iterateRoots": {
|
||||
// TOOD: make it so that this can only be called from a library file?
|
||||
case "iterateRoots": {
|
||||
if (typeArguments) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Type_0_is_not_generic,
|
||||
@ -2661,49 +2660,10 @@ export function compileCall(
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
let exprs = new Array<ExpressionRef>();
|
||||
for (let element of compiler.program.elementsLookup.values()) {
|
||||
if (element.kind != ElementKind.GLOBAL) continue;
|
||||
let global = <Global>element;
|
||||
let classReference = global.type.classReference;
|
||||
if (
|
||||
global.is(CommonFlags.COMPILED) &&
|
||||
classReference !== null &&
|
||||
!classReference.hasDecorator(DecoratorFlags.UNMANAGED)
|
||||
) {
|
||||
if (global.is(CommonFlags.INLINED)) {
|
||||
let value = global.constantIntegerValue;
|
||||
exprs.push(
|
||||
module.createCallIndirect(
|
||||
expr,
|
||||
[
|
||||
compiler.options.isWasm64
|
||||
? module.createI64(i64_low(value), i64_high(value))
|
||||
: module.createI32(i64_low(value))
|
||||
],
|
||||
signatureReference.toSignatureString()
|
||||
)
|
||||
);
|
||||
} else {
|
||||
exprs.push(
|
||||
module.createCallIndirect(
|
||||
expr,
|
||||
[
|
||||
module.createGetGlobal(
|
||||
global.internalName,
|
||||
compiler.options.nativeSizeType
|
||||
)
|
||||
],
|
||||
signatureReference.toSignatureString()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
compiler.currentType = Type.void;
|
||||
return exprs.length
|
||||
? module.createBlock(null, exprs)
|
||||
: module.createNop();
|
||||
// just emit a call even if the function doesn't yet exist
|
||||
compiler.needsIterateRoots = true;
|
||||
return module.createCall("~iterateRoots", [ expr ], NativeType.None);
|
||||
}
|
||||
}
|
||||
var expr = deferASMCall(compiler, prototype, operands, contextualType, reportNode);
|
||||
@ -2977,3 +2937,54 @@ export function compileAbort(
|
||||
module.createUnreachable()
|
||||
]);
|
||||
}
|
||||
|
||||
/** Compiles the iterateRoots function if requires. */
|
||||
export function compileIterateRoots(compiler: Compiler): void {
|
||||
var module = compiler.module;
|
||||
var exprs = new Array<ExpressionRef>();
|
||||
|
||||
for (let element of compiler.program.elementsLookup.values()) {
|
||||
if (element.kind != ElementKind.GLOBAL) continue;
|
||||
let global = <Global>element;
|
||||
let classReference = global.type.classReference;
|
||||
if (
|
||||
global.is(CommonFlags.COMPILED) &&
|
||||
classReference !== null &&
|
||||
!classReference.hasDecorator(DecoratorFlags.UNMANAGED)
|
||||
) {
|
||||
if (global.is(CommonFlags.INLINED)) {
|
||||
let value = global.constantIntegerValue;
|
||||
exprs.push(
|
||||
module.createCallIndirect(
|
||||
module.createGetLocal(0, NativeType.I32),
|
||||
[
|
||||
compiler.options.isWasm64
|
||||
? module.createI64(i64_low(value), i64_high(value))
|
||||
: module.createI32(i64_low(value))
|
||||
],
|
||||
"iv"
|
||||
)
|
||||
);
|
||||
} else {
|
||||
exprs.push(
|
||||
module.createCallIndirect(
|
||||
module.createGetLocal(0, NativeType.I32),
|
||||
[
|
||||
module.createGetGlobal(
|
||||
global.internalName,
|
||||
compiler.options.nativeSizeType
|
||||
)
|
||||
],
|
||||
"iv"
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
var typeRef = compiler.ensureFunctionType([ Type.i32 ], Type.void);
|
||||
module.addFunction("~iterateRoots", typeRef, [],
|
||||
exprs.length
|
||||
? module.createBlock(null, exprs)
|
||||
: module.createNop()
|
||||
);
|
||||
}
|
||||
|
@ -5,8 +5,9 @@
|
||||
|
||||
import {
|
||||
compileCall as compileBuiltinCall,
|
||||
compileAllocate as compileBuiltinAllocate,
|
||||
compileAbort as compileBuiltinAbort
|
||||
compileAllocate,
|
||||
compileAbort,
|
||||
compileIterateRoots
|
||||
} from "./builtins";
|
||||
|
||||
import {
|
||||
@ -286,6 +287,8 @@ export class Compiler extends DiagnosticEmitter {
|
||||
argcVar: GlobalRef = 0;
|
||||
/** Argument count helper setter. */
|
||||
argcSet: FunctionRef = 0;
|
||||
/** Indicates whether the iterateRoots function must be generated. */
|
||||
needsIterateRoots: bool = false;
|
||||
|
||||
/** Compiles a {@link Program} to a {@link Module} using the specified options. */
|
||||
static compile(program: Program, options: Options | null = null): Module {
|
||||
@ -408,6 +411,9 @@ export class Compiler extends DiagnosticEmitter {
|
||||
this.makeModuleExport(name, moduleExport.element);
|
||||
}
|
||||
|
||||
// set up gc
|
||||
if (this.needsIterateRoots) compileIterateRoots(this);
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
@ -974,7 +980,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
}
|
||||
|
||||
/** Either reuses or creates the function type matching the specified signature. */
|
||||
private ensureFunctionType(
|
||||
ensureFunctionType(
|
||||
parameterTypes: Type[] | null,
|
||||
returnType: Type,
|
||||
thisType: Type | null = null
|
||||
@ -2022,7 +2028,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
flow.set(FlowFlags.RETURNS);
|
||||
|
||||
// TODO: requires exception-handling spec.
|
||||
return compileBuiltinAbort(this, null, statement);
|
||||
return compileAbort(this, null, statement);
|
||||
}
|
||||
|
||||
compileTryStatement(statement: TryStatement): ExpressionRef {
|
||||
@ -6524,7 +6530,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
// allocate a new instance first and assign 'this' to the temp. local
|
||||
exprs[0] = module.createSetLocal(
|
||||
tempLocal.index,
|
||||
compileBuiltinAllocate(this, classReference, expression)
|
||||
compileAllocate(this, classReference, expression)
|
||||
);
|
||||
|
||||
// once all field values have been set, return 'this'
|
||||
@ -7497,7 +7503,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
var initializers = new Array<ExpressionRef>();
|
||||
initializers.push(
|
||||
module.createSetLocal(tempLocal.index,
|
||||
compileBuiltinAllocate(this, classInstance, reportNode)
|
||||
compileAllocate(this, classInstance, reportNode)
|
||||
)
|
||||
);
|
||||
|
||||
|
Reference in New Issue
Block a user