Search in sources :

Example 1 with MethodTypeDescriptor

use of com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor in project es6draft by anba.

the class SwitchStatementGenerator method caseSelect.

/**
 * Generates a case-select method.
 *
 * @param caseBlock
 *            the case-block
 * @param switchVarType
 *            the switch-var type
 * @param mv
 *            the code visitor
 * @return the outlined-call object
 */
private OutlinedCall caseSelect(SwitchStatementGenerator.CaseBlock caseBlock, Type switchVarType, CodeVisitor mv) {
    SwitchClause firstClause = caseBlock.clauses.get(0);
    MethodTypeDescriptor methodDescriptor = SwitchSelectCodeVisitor.methodDescriptor(switchVarType, mv);
    MethodCode method = codegen.method(mv, "select", methodDescriptor);
    return outlined(new SwitchSelectCodeVisitor(firstClause, method, mv), body -> {
        Variable<?> switchValue = body.getSwitchValueParameter();
        MutableValue<Integer> switchTarget = body.iarrayElement(body.getSwitchTargetParameter(), 0);
        List<SwitchClause> clauses = caseBlock.clauses;
        int[] switchTargets = caseBlock.switchTargets;
        int numTargets = caseBlock.numTargets();
        Jump[] targetLabels = new Jump[numTargets];
        for (int i = 0; i < targetLabels.length; ++i) {
            targetLabels[i] = new Jump();
        }
        Jump lblExit = new Jump();
        Jump[] labels = new Jump[clauses.size()];
        for (int i = 0; i < clauses.size(); ++i) {
            labels[i] = targetLabels[switchTargets[i] - 1];
        }
        caseSelector(SwitchType.of(clauses)).select(clauses, switchValue, labels, lblExit, body);
        Jump setSwitchTarget = new Jump();
        for (int i = 0; i < targetLabels.length; ++i) {
            // targetLabels[i] is not reachable if only used by the default clause.
            if (targetLabels[i].isTarget()) {
                body.mark(targetLabels[i]);
                body.iconst(i + 1);
                body.goTo(setSwitchTarget);
            }
        }
        if (setSwitchTarget.isTarget()) {
            // stack: [newSwitchTarget] -> []
            body.mark(setSwitchTarget);
            body.store(switchTarget);
        }
        body.mark(lblExit);
        return Completion.Normal;
    });
}
Also used : SwitchClause(com.github.anba.es6draft.ast.SwitchClause) MethodCode(com.github.anba.es6draft.compiler.assembler.Code.MethodCode) Jump(com.github.anba.es6draft.compiler.assembler.Jump) MethodTypeDescriptor(com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor)

Example 2 with MethodTypeDescriptor

use of com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor in project es6draft by anba.

the class SwitchStatementGenerator method defaultCaseBlock.

/**
 * Generates a case-block method.
 *
 * @param caseBlock
 *            the case-block
 * @param mv
 *            the code visitor
 * @return the outlined-call object
 */
private OutlinedCall defaultCaseBlock(SwitchStatementGenerator.CaseBlock caseBlock, CodeVisitor mv) {
    SwitchClause firstClause = caseBlock.clauses.get(0);
    MethodTypeDescriptor methodDescriptor = DefaultSwitchBlockCodeVisitor.methodDescriptor(mv);
    MethodCode method = codegen.method(mv, "case", methodDescriptor);
    return outlined(new DefaultSwitchBlockCodeVisitor(firstClause, method, mv), body -> {
        Completion lastResult = Completion.Normal;
        for (SwitchClause clause : caseBlock.clauses) {
            lastResult = clause.accept(this, body);
            if (lastResult.isAbrupt()) {
                break;
            }
        }
        return lastResult;
    });
}
Also used : Completion(com.github.anba.es6draft.compiler.StatementGenerator.Completion) SwitchClause(com.github.anba.es6draft.ast.SwitchClause) MethodCode(com.github.anba.es6draft.compiler.assembler.Code.MethodCode) MethodTypeDescriptor(com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor)

Example 3 with MethodTypeDescriptor

use of com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor in project es6draft by anba.

the class PropertyGenerator method propertyDefinitions.

private OutlinedCall propertyDefinitions(PropertyDefinitionsMethod node, CodeVisitor mv) {
    MethodTypeDescriptor methodDescriptor = PropertyDefinitionsCodeVisitor.methodDescriptor(mv);
    MethodCode method = codegen.method(mv, "propdef", methodDescriptor);
    return outlined(new PropertyDefinitionsCodeVisitor(node, method, mv), body -> {
        Variable<OrdinaryObject> object = body.getObjectParameter();
        StoreToArray<Object> decorators = this.decorators.from(body.getDecoratorsParameter());
        PropertyEvaluation(codegen, node.getProperties(), object, decorators, body);
        return Completion.Normal;
    });
}
Also used : OrdinaryObject(com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject) OrdinaryObject(com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject) MethodCode(com.github.anba.es6draft.compiler.assembler.Code.MethodCode) MethodTypeDescriptor(com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor)

Example 4 with MethodTypeDescriptor

use of com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor in project es6draft by anba.

the class StatementGenerator method statementList.

private OutlinedCall statementList(StatementListMethod node, CodeVisitor mv) {
    MethodTypeDescriptor methodDescriptor = StatementListMethodCodeVisitor.methodDescriptor(mv);
    MethodCode method = codegen.method(mv, "stmt", methodDescriptor);
    return outlined(new StatementListMethodCodeVisitor(node, method, mv), body -> {
        return statements(node.getStatements(), body);
    });
}
Also used : MethodCode(com.github.anba.es6draft.compiler.assembler.Code.MethodCode) MethodTypeDescriptor(com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor)

Example 5 with MethodTypeDescriptor

use of com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor in project es6draft by anba.

the class CodeGenerator method classDefinition.

/**
 * Compiles a class definition node.
 *
 * @param node
 *            the class definition
 * @return the class definition method
 */
MethodName classDefinition(ClassDefinition node) {
    MethodDefinition constructor = node.getConstructor();
    MethodDefinition callConstructor = node.getCallConstructor();
    String methodName = newUniqueName(node);
    CompletableFuture<String> source = getSource(node);
    ClassCompiler compiler;
    if (node.getHeritage() == null) {
        compiler = ClassCompiler.BaseClass;
    } else {
        compiler = ClassCompiler.DerivedClass;
    }
    // instantiation method
    MethodCode constructInit = newMethod(scriptFrame(methodName, "_init"), compiler.desc.instantiation);
    new FunctionDeclarationInstantiationGenerator(this).generate(constructor, constructInit);
    // runtime method
    MethodCode constructBody = newMethod(scriptFrame(methodName), compiler.desc.body);
    boolean tailConstruct = compiler.body.compile(this, constructor, constructBody);
    // construct method
    MethodTypeDescriptor constructDesc;
    if (tailConstruct) {
        constructDesc = FunctionDesc.ConstructorFunctionTailCall.construct;
    } else {
        constructDesc = compiler.desc.construct;
    }
    MethodCode constructEntry = newMethod(hiddenFrame(methodName, "_construct"), constructDesc);
    FunctionCode construct = new FunctionCode(constructEntry.name(), constructInit.name(), constructBody.name(), tailConstruct);
    compiler.construct.compile(this, node, constructEntry, construct);
    FunctionCode call;
    Function<MethodName, MethodName> debugInfo = null;
    if (callConstructor != null) {
        FunctionCompiler<MethodDefinition> callCompiler = FunctionCompiler.CallConstructor;
        String callMethodName = newUniqueName(callConstructor);
        // instantiation method
        MethodCode callInit = newMethod(scriptFrame(callMethodName, "_init"), callCompiler.desc.instantiation);
        new FunctionDeclarationInstantiationGenerator(this).generate(callConstructor, callInit);
        // runtime method
        MethodCode callBody = newMethod(scriptFrame(callMethodName), callCompiler.desc.body);
        boolean tailCall = callCompiler.body.compile(this, callConstructor, callBody);
        // call method
        MethodCode callMethod = newMethod(hiddenFrame(methodName, "_call"), callCompiler.desc.call);
        call = new FunctionCode(callMethod.name(), callInit.name(), callBody.name(), tailCall);
        callCompiler.call.compile(this, callConstructor, callMethod, call);
        // debug-info method
        if (isEnabled(Compiler.Option.DebugInfo)) {
            debugInfo = rt -> {
                MethodCode method = newMethod(hiddenFrame(methodName, "_dbg"), MethodDescriptors.DebugInfo);
                debugInfo(method, rt, call.entry, call.instantiation, call.body, construct.entry, construct.instantiation, construct.body);
                return method.name();
            };
        }
    } else {
        // call method
        MethodCode callMethod = newMethod(hiddenFrame(methodName, "_call"), compiler.desc.call);
        call = new FunctionCode(callMethod.name(), null, null, false);
        compiler.call.compile(this, node, callMethod, call);
        // debug-info method
        if (isEnabled(Compiler.Option.DebugInfo)) {
            debugInfo = rt -> {
                MethodCode method = newMethod(hiddenFrame(methodName, "_dbg"), MethodDescriptors.DebugInfo);
                debugInfo(method, rt, call.entry, construct.entry, construct.instantiation, construct.body);
                return method.name();
            };
        }
    }
    // runtime-info method
    MethodCode runtimeInfo = newMethod(hiddenFrame(methodName, "_rti"), MethodDescriptors.Function_RTI);
    new RuntimeInfoGenerator(this).runtimeInfo(constructor, runtimeInfo, call, construct, source.join(), debugInfo);
    return runtimeInfo.name();
}
Also used : MethodName(com.github.anba.es6draft.compiler.assembler.MethodName) MethodCode(com.github.anba.es6draft.compiler.assembler.Code.MethodCode) MethodTypeDescriptor(com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor)

Aggregations

MethodTypeDescriptor (com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor)13 MethodCode (com.github.anba.es6draft.compiler.assembler.Code.MethodCode)12 SwitchClause (com.github.anba.es6draft.ast.SwitchClause)3 Jump (com.github.anba.es6draft.compiler.assembler.Jump)3 OrdinaryObject (com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject)3 Completion (com.github.anba.es6draft.compiler.StatementGenerator.Completion)2 MethodName (com.github.anba.es6draft.compiler.assembler.MethodName)2 ArrayObject (com.github.anba.es6draft.runtime.types.builtins.ArrayObject)2 ValType (com.github.anba.es6draft.compiler.DefaultCodeGenerator.ValType)1 ExecutionContext (com.github.anba.es6draft.runtime.ExecutionContext)1 InstanceMethod (com.github.anba.es6draft.runtime.language.ClassOperations.InstanceMethod)1 OrdinaryConstructorFunction (com.github.anba.es6draft.runtime.types.builtins.OrdinaryConstructorFunction)1 BigInteger (java.math.BigInteger)1