script parameter closure
This commit is contained in:
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user