script parameter closure

This commit is contained in:
Stepan Koltsov
2012-06-08 04:19:24 +04:00
parent 6f78e9e99b
commit 18aa1dc570
4 changed files with 52 additions and 13 deletions
@@ -1126,23 +1126,33 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
StackValue value = context.lookupInContext(descriptor, v, StackValue.local(0, TYPE_OBJECT));
if (value == null) {
throw new UnsupportedOperationException("don't know how to generate reference " + descriptor);
if (value != null) {
if (value instanceof StackValue.Composed) {
StackValue.Composed composed = (StackValue.Composed) value;
composed.prefix.put(TYPE_OBJECT, v);
value = composed.suffix;
}
if (value instanceof StackValue.FieldForSharedVar) {
StackValue.FieldForSharedVar fieldForSharedVar = (StackValue.FieldForSharedVar) value;
Type sharedType = StackValue.sharedTypeForType(value.type);
v.visitFieldInsn(Opcodes.GETFIELD, fieldForSharedVar.owner.getInternalName(), fieldForSharedVar.name, sharedType.getDescriptor());
}
return value;
}
if(value instanceof StackValue.Composed) {
StackValue.Composed composed = (StackValue.Composed) value;
composed.prefix.put(TYPE_OBJECT, v);
value = composed.suffix;
if (descriptor instanceof ValueParameterDescriptor && descriptor.getContainingDeclaration() instanceof ScriptDescriptor) {
ScriptDescriptor scriptDescriptor = (ScriptDescriptor) descriptor.getContainingDeclaration();
JvmClassName scriptClassName = state.getInjector().getClosureAnnotator().classNameForScriptDescriptor(scriptDescriptor);
ValueParameterDescriptor valueParameterDescriptor = (ValueParameterDescriptor) descriptor;
generateThisOrOuter(state.getInjector().getClosureAnnotator().classDescriptorForScrpitDescriptor(scriptDescriptor));
Type fieldType = typeMapper.mapType(valueParameterDescriptor.getType(), MapTypeMode.VALUE);
return StackValue.field(fieldType, scriptClassName, valueParameterDescriptor.getName().getIdentifier(), false);
}
if(value instanceof StackValue.FieldForSharedVar) {
StackValue.FieldForSharedVar fieldForSharedVar = (StackValue.FieldForSharedVar) value;
Type sharedType = StackValue.sharedTypeForType(value.type);
v.visitFieldInsn(Opcodes.GETFIELD, fieldForSharedVar.owner.getInternalName(), fieldForSharedVar.name, sharedType.getDescriptor());
}
return value;
throw new UnsupportedOperationException("don't know how to generate reference " + descriptor);
}
private StackValue stackValueForLocal(DeclarationDescriptor descriptor, int index) {
@@ -109,6 +109,7 @@ public class ScriptCodegen {
new String[0]);
genMembers(scriptDeclaration, context, classBuilder);
genFieldsForParameters(scriptDescriptor, classBuilder);
genConstructor(scriptDeclaration, scriptDescriptor, classDescriptorForScript, classBuilder, context.intoFunction(scriptDescriptor.getScriptCodeDescriptor()));
classBuilder.done();
@@ -159,6 +160,15 @@ public class ScriptCodegen {
bindingContext,
jetTypeMapper);
int offset = 1;
for (ValueParameterDescriptor parameter : scriptDescriptor.getValueParameters()) {
Type parameterType = jetTypeMapper.mapType(parameter.getType(), MapTypeMode.VALUE);
instructionAdapter.load(0, className.getAsmType());
instructionAdapter.load(offset, parameterType);
offset += parameterType.getSize();
instructionAdapter.putfield(className.getInternalName(), parameter.getName().getIdentifier(), parameterType.getDescriptor());
}
StackValue stackValue = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context, state).gen(scriptDeclaration.getBlockExpression());
if (stackValue.type != Type.VOID_TYPE) {
stackValue.put(stackValue.type, instructionAdapter);
@@ -170,6 +180,14 @@ public class ScriptCodegen {
mv.visitEnd();
}
private void genFieldsForParameters(@NotNull ScriptDescriptor script, @NotNull ClassBuilder classBuilder) {
for (ValueParameterDescriptor parameter : script.getValueParameters()) {
Type parameterType = jetTypeMapper.mapType(parameter.getType(), MapTypeMode.VALUE);
int access = Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL;
classBuilder.newField(null, access, parameter.getName().getIdentifier(), parameterType.getDescriptor(), null, null);
}
}
private void genMembers(@NotNull JetScript scriptDeclaration, @NotNull CodegenContext context, @NotNull ClassBuilder classBuilder) {
for (JetDeclaration decl : scriptDeclaration.getDeclarations()) {
memberCodegen.generateFunctionOrProperty((JetTypeParameterListOwner) decl, context, classBuilder);
@@ -0,0 +1,7 @@
// param: x: jet.Int: 10
fun addX(y: Int) = x + y
addX(3)
// expected: rv: 13
@@ -78,4 +78,8 @@ public class ScriptGenTest extends CodegenTestCase {
blackBoxFile("script/parameterArray.ktscript");
}
public void testScriptParameterClosure() {
blackBoxFile("script/parameterClosure.ktscript");
}
}