MichaReiser/speedy.js

View on GitHub
packages/compiler/src/code-generation/value/resolved-function-reference.ts

Summary

Maintainability
A
0 mins
Test Coverage
import * as assert from "assert";
import * as llvm from "llvm-node";
import * as ts from "typescript";
import {CodeGenerationContext} from "../code-generation-context";
import {RuntimeSystemNameMangler} from "../runtime-system-name-mangler";
import {AbstractFunctionReference} from "./abstract-function-reference";
import {FunctionFactory, FunctionProperties} from "./function-factory";
import {FunctionPointer} from "./function-reference";
import {createResolvedFunctionFromSignature, ResolvedFunction} from "./resolved-function";

const DEFAULT_RUNTIME_FUNCTION_PROPERTIES = { linkage: llvm.LinkageTypes.ExternalLinkage, alwaysInline: true } as Partial<FunctionProperties>;

/**
 * Reference to a specific overload of a function.
 */
export class ResolvedFunctionReference extends AbstractFunctionReference {

    private fn: FunctionPointer;

    /**
     * Creates a new reference to the specified runtime function
     * @param resolvedFunction the resolved overload of the runtime function
     * @param context the context
     * @param functionProperties the function properties
     * @return {ResolvedFunctionReference} the reference to the specified runtime function overload
     */
    static createRuntimeFunction(resolvedFunction: ResolvedFunction, context: CodeGenerationContext, functionProperties?: Partial<FunctionProperties>) {
        functionProperties = Object.assign({}, DEFAULT_RUNTIME_FUNCTION_PROPERTIES, functionProperties);
        const llvmFunctionFactory = new FunctionFactory(new RuntimeSystemNameMangler(context.compilationContext), context.runtimeTypeConverter);
        const fn = llvmFunctionFactory.getOrCreate(resolvedFunction, resolvedFunction.parameters.length, context, functionProperties);
        return new ResolvedFunctionReference(fn, resolvedFunction);
    }

    /**
     * Creates a new reference to the overload defined by the passed in signature
     * @param fn the llvm function that implements the given signature
     * @param signature the signature of the function
     * @param context the context
     * @return {ResolvedFunctionReference} a reference to the given llvm function with the given signature
     */
    static createForSignature(fn: FunctionPointer, signature: ts.Signature, context: CodeGenerationContext) {
        const resolvedFunction = createResolvedFunctionFromSignature(signature, context.compilationContext);
        return new ResolvedFunctionReference(fn, resolvedFunction);
    }

    static create(fn: FunctionPointer, resolvedFunction: ResolvedFunction) {
        return new ResolvedFunctionReference(fn, resolvedFunction);
    }

    protected constructor(fn: llvm.Value, public resolvedFunction: ResolvedFunction) {
        super();
        assert(fn, "Function is missing");
        assert(fn.type.isPointerTy && (fn.type as llvm.PointerType).elementType.isFunctionTy(), "Expected value to be a pointer to a function");

        this.fn = fn as FunctionPointer;
    }

    getResolvedFunction(): ResolvedFunction {
        return this.resolvedFunction;
    }

    protected getLLVMFunction(): FunctionPointer {
        return this.fn;
    }
}