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;
});
}
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;
});
}
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;
});
}
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);
});
}
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();
}
Aggregations