use of com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor in project es6draft by anba.
the class ExpressionGenerator method expressionMethod.
private OutlinedCall expressionMethod(ExpressionMethod node, CodeVisitor mv) {
MethodTypeDescriptor methodDescriptor = ExpressionMethodVisitor.methodDescriptor(mv);
MethodCode method = codegen.method(mv, "expr", methodDescriptor);
return outlined(new ExpressionMethodVisitor(node, method, mv), body -> {
ValType type = node.getExpression().accept(this, body);
assert type != ValType.Empty;
body.storeCompletionValue(type);
return Completion.Normal;
});
}
use of com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor in project es6draft by anba.
the class ExpressionGenerator method objectMethodDecorators.
private MethodName objectMethodDecorators(ObjectLiteral node, CodeVisitor parent) {
MethodTypeDescriptor descriptor = ObjectMethodDecoratorsVisitor.methodDescriptor();
MethodCode method = codegen.method(parent, "objectdecorators", descriptor);
ObjectMethodDecoratorsVisitor mv = new ObjectMethodDecoratorsVisitor(method);
mv.begin();
Variable<ExecutionContext> cx = mv.getExecutionContext();
Variable<OrdinaryObject> object = mv.getObject();
// List of <1..n callable, property key>.
Variable<Object[]> decorators = mv.getDecorators();
Variable<Object> propertyKey = mv.newVariable("propertyKey", Object.class);
Variable<Object> propertyDesc = mv.newVariable("propertyDesc", Object.class);
Variable<Object> result = mv.newVariable("result", Object.class);
int index = 0;
for (MethodDefinition methodDef : DecoratedMethods(node.getProperties())) {
List<Expression> decoratorsList = methodDef.getDecorators();
assert !decoratorsList.isEmpty();
mv.store(propertyKey, mv.arrayElement(decorators, index + decoratorsList.size(), Object.class));
mv.lineInfo(methodDef);
mv.invoke(Methods.DecoratorOperations_propertyDescriptor, object, propertyKey, cx);
mv.store(propertyDesc);
for (Expression decoratorExpr : decoratorsList) {
Value<Object> decorator = mv.arrayElement(decorators, index++, Object.class);
invokeDynamicCall(mv, decoratorExpr, decorator, cx, mv.undefinedValue(), object, propertyKey, propertyDesc);
mv.store(result);
Jump isObject = new Jump();
mv.invoke(Methods.Type_isObject, result);
mv.ifeq(isObject);
{
mv.store(propertyDesc, result);
}
mv.mark(isObject);
}
Jump isObject = new Jump();
mv.invoke(Methods.Type_isObject, propertyDesc);
mv.ifeq(isObject);
{
mv.lineInfo(methodDef);
mv.invoke(Methods.DecoratorOperations_defineProperty, object, propertyKey, propertyDesc, cx);
}
mv.mark(isObject);
// Skip over property key element.
index += 1;
}
mv._return();
mv.end();
return method.name();
}
use of com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor in project es6draft by anba.
the class SwitchStatementGenerator method caseBlock.
/**
* Generates a case-block method.
*
* @param caseBlock
* the case-block
* @param mv
* the code visitor
* @return the outlined-call object
*/
private OutlinedCall caseBlock(SwitchStatementGenerator.CaseBlock caseBlock, CodeVisitor mv) {
SwitchClause firstClause = caseBlock.clauses.get(0);
MethodTypeDescriptor methodDescriptor = SwitchBlockCodeVisitor.methodDescriptor(mv);
MethodCode method = codegen.method(mv, "case", methodDescriptor);
return outlined(new SwitchBlockCodeVisitor(firstClause, method, mv), body -> {
Variable<Integer> switchTarget = body.getSwitchTargetParameter();
List<SwitchClause> clauses = caseBlock.clauses;
int[] switchTargets = caseBlock.switchTargets;
int numTargets = caseBlock.numTargets();
Completion lastResult = Completion.Normal;
if (numTargets > 1) {
Jump[] labels = new Jump[numTargets];
for (int i = 0; i < labels.length; ++i) {
labels[i] = new Jump();
}
Jump defaultInstr = new Jump();
body.load(switchTarget);
body.tableswitch(1, numTargets, defaultInstr, labels);
body.mark(defaultInstr);
for (int i = 0, lastTarget = 0; i < clauses.size(); ++i) {
if (lastTarget != switchTargets[i]) {
lastTarget = switchTargets[i];
body.mark(labels[lastTarget - 1]);
}
lastResult = clauses.get(i).accept(this, body);
}
} else {
for (SwitchClause clause : clauses) {
lastResult = clause.accept(this, body);
}
}
return lastResult;
});
}
use of com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor in project es6draft by anba.
the class ClassPropertyGenerator method methodDefinitions.
private OutlinedCall methodDefinitions(MethodDefinitionsMethod node, CodeVisitor mv) {
MethodTypeDescriptor methodDescriptor = MethodDefinitionsCodeVisitor.methodDescriptor(mv);
MethodCode method = codegen.method(mv, "mdef", methodDescriptor);
return outlined(new MethodDefinitionsCodeVisitor(node, method, mv), body -> {
Variable<OrdinaryConstructorFunction> function = body.getFunctionParameter();
Variable<OrdinaryObject> proto = body.getPrototypeParameter();
StoreToArray<Object> staticFields = this.staticFields.from(body.getStaticFieldsParameter());
StoreToArray<Object> instanceFields = this.instanceFields.from(body.getInstanceFieldsParameter());
StoreToArray<InstanceMethod> instanceMethods = this.instanceMethods.from(body.getInstanceMethodsParameter());
StoreToArray<Object> decorators = this.decorators.from(body.getDecoratorsParameter());
ClassPropertyEvaluation(codegen, classDefinition, node.getProperties(), function, proto, staticFields, instanceFields, instanceMethods, decorators, body);
return Completion.Normal;
});
}
use of com.github.anba.es6draft.compiler.assembler.MethodTypeDescriptor in project es6draft by anba.
the class CodeGenerator method compile.
private <FUNCTION extends FunctionNode> MethodName compile(FUNCTION node, FunctionCompiler<FUNCTION> compiler) {
CompletableFuture<String> source = getSource(node);
String methodName = newUniqueName(node);
FunctionCode call;
if (node.isInline()) {
// call method
MethodCode callEntry = newMethod(scriptFrame(methodName), compiler.desc.call);
boolean tailCall = compiler.callInline.compile(this, node, callEntry);
call = new FunctionCode(callEntry.name(), null, null, tailCall);
} else {
// instantiation method
MethodCode functionInit = newMethod(scriptFrame(methodName, "_init"), compiler.desc.instantiation);
new FunctionDeclarationInstantiationGenerator(this).generate(node, functionInit);
// runtime method
MethodCode functionBody = newMethod(scriptFrame(methodName), compiler.desc.body);
boolean tailCall = compiler.body.compile(this, node, functionBody);
// call method
MethodCode callEntry = newMethod(hiddenFrame(methodName, "_call"), compiler.desc.call);
call = new FunctionCode(callEntry.name(), functionInit.name(), functionBody.name(), tailCall);
compiler.call.compile(this, node, callEntry, call);
}
FunctionCode construct;
Function<MethodName, MethodName> debugInfo = null;
if (compiler.construct != null) {
// construct method
MethodTypeDescriptor constructDesc;
if (call.tailCall) {
assert node instanceof FunctionDefinition && IsStrict(node);
constructDesc = FunctionDesc.ConstructorFunctionTailCall.construct;
} else {
constructDesc = compiler.desc.construct;
}
if (node.isInline()) {
MethodCode constructEntry = newMethod(scriptFrame(methodName), constructDesc);
boolean tailCall = compiler.constructInline.compile(this, node, constructEntry);
construct = new FunctionCode(constructEntry.name(), null, null, tailCall);
} else {
MethodCode constructEntry = newMethod(hiddenFrame(methodName, "_construct"), constructDesc);
construct = new FunctionCode(constructEntry.name(), call.instantiation, call.body, call.tailCall);
compiler.construct.compile(this, node, constructEntry, construct);
}
// 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, call.instantiation, call.body);
return method.name();
};
}
} else {
construct = null;
// 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);
return method.name();
};
}
}
// runtime-info method
MethodCode runtimeInfo = newMethod(hiddenFrame(methodName, "_rti"), MethodDescriptors.Function_RTI);
new RuntimeInfoGenerator(this).runtimeInfo(node, runtimeInfo, call, construct, source.join(), debugInfo);
return runtimeInfo.name();
}
Aggregations