closure shared vars
This commit is contained in:
@@ -146,7 +146,15 @@ public class ClassContext {
|
||||
if (answer != null) return answer;
|
||||
|
||||
final StackValue thisContext = getThisExpression();
|
||||
thisContext.put(thisContext.type, v);
|
||||
if(thisContext instanceof StackValue.Local) {
|
||||
}
|
||||
else if(thisContext instanceof StackValue.InstanceField) {
|
||||
StackValue.InstanceField instanceField = (StackValue.InstanceField) thisContext;
|
||||
v.getfield(instanceField.owner, instanceField.name, instanceField.type.getDescriptor());
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
return parentContext != null ? parentContext.lookupInContext(d, v) : null;
|
||||
|
||||
@@ -67,11 +67,13 @@ public class ClosureCodegen {
|
||||
final int idx = exprContext.lookupLocal(vd);
|
||||
if (idx < 0) return null;
|
||||
|
||||
final Type type = state.getTypeMapper().mapType(vd.getOutType());
|
||||
final Type sharedVarType = exprContext.getSharedVarType(vd);
|
||||
Type localType = state.getTypeMapper().mapType(vd.getOutType());
|
||||
final Type type = sharedVarType != null ? sharedVarType : localType;
|
||||
|
||||
StackValue outerValue = StackValue.local(idx, type);
|
||||
final String fieldName = "$" + (closure.size() + 1);
|
||||
StackValue innerValue = StackValue.field(type, name, fieldName, false);
|
||||
final String fieldName = "$" + (closure.size() + 1); // + "$" + vd.getName();
|
||||
StackValue innerValue = sharedVarType != null ? StackValue.fieldForSharedVar(localType, name, fieldName) : StackValue.field(type, name, fieldName, false);
|
||||
cv.visitField(Opcodes.ACC_PUBLIC, fieldName, type.getDescriptor(), null, null);
|
||||
answer = new EnclosedValueDescriptor(d, innerValue, outerValue);
|
||||
closure.put(d, answer);
|
||||
@@ -120,7 +122,7 @@ public class ClosureCodegen {
|
||||
final Method constructor = generateConstructor(funClass, captureThis, funDescriptor.getReturnType());
|
||||
|
||||
if (captureThis) {
|
||||
cv.visitField(Opcodes.ACC_PRIVATE, "this$0", enclosingType.getDescriptor(), null, null);
|
||||
cv.visitField(0, "this$0", enclosingType.getDescriptor(), null, null);
|
||||
}
|
||||
|
||||
cv.visitEnd();
|
||||
@@ -192,7 +194,9 @@ public class ClosureCodegen {
|
||||
}
|
||||
|
||||
for (DeclarationDescriptor descriptor : closure.keySet()) {
|
||||
argTypes[i++] = state.getTypeMapper().mapType(((VariableDescriptor) descriptor).getOutType());
|
||||
final Type sharedVarType = exprContext.getSharedVarType(descriptor);
|
||||
final Type type = sharedVarType != null ? sharedVarType : state.getTypeMapper().mapType(((VariableDescriptor) descriptor).getOutType());
|
||||
argTypes[i++] = type;
|
||||
}
|
||||
|
||||
final Method constructor = new Method("<init>", Type.VOID_TYPE, argTypes);
|
||||
|
||||
@@ -551,7 +551,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
final Method cons = closure.getConstructor();
|
||||
|
||||
if (closure.isCaptureThis()) {
|
||||
thisToStack();
|
||||
v.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
}
|
||||
|
||||
for (int i = 0; i < closure.getArgs().size(); i++) {
|
||||
@@ -576,6 +576,20 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
return StackValue.onStack(type);
|
||||
}
|
||||
|
||||
Type getSharedVarType(DeclarationDescriptor variableDescriptor) {
|
||||
if(!(variableDescriptor instanceof VariableDescriptor))
|
||||
return null;
|
||||
|
||||
Boolean aBoolean = bindingContext.get(BindingContext.MUST_BE_WRAPPED_IN_A_REF, (VariableDescriptor) variableDescriptor);
|
||||
if (aBoolean != null && aBoolean) {
|
||||
JetType outType = ((VariableDescriptor) variableDescriptor).getOutType();
|
||||
return StackValue.sharedTypeForType(typeMapper.mapType(outType));
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private StackValue generateBlock(List<JetElement> statements) {
|
||||
Label blockStart = new Label();
|
||||
v.mark(blockStart);
|
||||
@@ -584,7 +598,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
if (statement instanceof JetProperty) {
|
||||
final VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, statement);
|
||||
assert variableDescriptor != null;
|
||||
final Type type = typeMapper.mapType(variableDescriptor.getOutType());
|
||||
|
||||
final Type sharedVarType = getSharedVarType(variableDescriptor);
|
||||
final Type type = sharedVarType != null ? sharedVarType : typeMapper.mapType(variableDescriptor.getOutType());
|
||||
myMap.enter(variableDescriptor, type.getSize());
|
||||
}
|
||||
}
|
||||
@@ -608,10 +624,17 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
JetProperty var = (JetProperty) statement;
|
||||
VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, var);
|
||||
assert variableDescriptor != null;
|
||||
Type outType = typeMapper.mapType(variableDescriptor.getOutType());
|
||||
|
||||
int index = myMap.leave(variableDescriptor);
|
||||
v.visitLocalVariable(var.getName(), outType.getDescriptor(), null, blockStart, blockEnd, index);
|
||||
|
||||
final Type sharedVarType = getSharedVarType(variableDescriptor);
|
||||
final Type type = sharedVarType != null ? sharedVarType : typeMapper.mapType(variableDescriptor.getOutType());
|
||||
if(sharedVarType != null) {
|
||||
v.aconst(null);
|
||||
v.store(index, JetTypeMapper.TYPE_OBJECT);
|
||||
}
|
||||
|
||||
v.visitLocalVariable(var.getName(), type.getDescriptor(), null, blockStart, blockEnd, index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -699,8 +722,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
else {
|
||||
int index = lookupLocal(descriptor);
|
||||
if (index >= 0) {
|
||||
Type sharedVarType = getSharedVarType(descriptor);
|
||||
final JetType outType = ((VariableDescriptor) descriptor).getOutType();
|
||||
return StackValue.local(index, typeMapper.mapType(outType));
|
||||
if(sharedVarType != null) {
|
||||
return StackValue.shared(index, typeMapper.mapType(outType));
|
||||
}
|
||||
else {
|
||||
return StackValue.local(index, typeMapper.mapType(outType));
|
||||
}
|
||||
}
|
||||
else if (descriptor instanceof PropertyDescriptor) {
|
||||
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||
@@ -785,6 +814,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
if (value == null) {
|
||||
throw new UnsupportedOperationException("don't know how to generate reference " + descriptor);
|
||||
}
|
||||
|
||||
if(value instanceof StackValue.FieldForSharedVar) {
|
||||
StackValue.FieldForSharedVar fieldForSharedVar = (StackValue.FieldForSharedVar) value;
|
||||
Type sharedType = StackValue.sharedTypeForType(value.type);
|
||||
v.visitFieldInsn(Opcodes.GETFIELD, fieldForSharedVar.owner, fieldForSharedVar.name, sharedType.getDescriptor());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -1617,12 +1652,27 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
|
||||
assert index >= 0;
|
||||
|
||||
final Type sharedVarType = getSharedVarType(variableDescriptor);
|
||||
assert variableDescriptor != null;
|
||||
Type varType = typeMapper.mapType(variableDescriptor.getOutType());
|
||||
if(sharedVarType != null) {
|
||||
v.anew(sharedVarType);
|
||||
v.dup();
|
||||
v.invokespecial(sharedVarType.getInternalName(), "<init>", "()V");
|
||||
v.store(index, JetTypeMapper.TYPE_OBJECT);
|
||||
}
|
||||
|
||||
JetExpression initializer = property.getInitializer();
|
||||
if (initializer != null) {
|
||||
assert variableDescriptor != null;
|
||||
Type type = typeMapper.mapType(variableDescriptor.getOutType());
|
||||
gen(initializer, type);
|
||||
v.store(index, type);
|
||||
if(sharedVarType == null) {
|
||||
gen(initializer, varType);
|
||||
v.store(index, varType);
|
||||
}
|
||||
else {
|
||||
v.load(index, JetTypeMapper.TYPE_OBJECT);
|
||||
gen(initializer, varType);
|
||||
v.putfield(sharedVarType.getInternalName(), "ref", sharedVarType == JetTypeMapper.TYPE_SHARED_VAR ? "Ljava/lang/Object;" : varType.getDescriptor());
|
||||
}
|
||||
}
|
||||
return StackValue.none();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.jetbrains.jet.codegen;
|
||||
import gnu.trove.TObjectIntHashMap;
|
||||
import gnu.trove.TObjectIntIterator;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -98,6 +98,23 @@ public class FunctionCodegen {
|
||||
iv.areturn(jvmSignature.getReturnType());
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < paramDescrs.size(); i++) {
|
||||
ValueParameterDescriptor parameter = paramDescrs.get(i);
|
||||
|
||||
Type sharedVarType = codegen.getSharedVarType(parameter);
|
||||
Type localVarType = state.getTypeMapper().mapType(parameter.getOutType());
|
||||
if(sharedVarType != null) {
|
||||
int index = frameMap.getIndex(parameter);
|
||||
mv.visitTypeInsn(Opcodes.NEW, sharedVarType.getInternalName());
|
||||
mv.visitInsn(Opcodes.DUP);
|
||||
mv.visitInsn(Opcodes.DUP);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, sharedVarType.getInternalName(), "<init>", "()V");
|
||||
mv.visitVarInsn(localVarType.getOpcode(Opcodes.ILOAD), index);
|
||||
mv.visitFieldInsn(Opcodes.PUTFIELD, sharedVarType.getInternalName(), "ref", StackValue.refType(localVarType).getDescriptor());
|
||||
mv.visitVarInsn(sharedVarType.getOpcode(Opcodes.ISTORE), index);
|
||||
}
|
||||
}
|
||||
|
||||
codegen.returnExpression(bodyExpressions);
|
||||
}
|
||||
mv.visitMaxs(0, 0);
|
||||
|
||||
@@ -59,6 +59,15 @@ public class JetTypeMapper {
|
||||
public static final Type TYPE_FUNCTION1 = Type.getObjectType("jet/Function1");
|
||||
public static final Type TYPE_ITERATOR = Type.getObjectType("jet/Iterator");
|
||||
public static final Type TYPE_INT_RANGE = Type.getObjectType("jet/IntRange");
|
||||
public static final Type TYPE_SHARED_VAR = Type.getObjectType("jet/refs/SharedVar$Object");
|
||||
public static final Type TYPE_SHARED_INT = Type.getObjectType("jet/refs/SharedVar$Int");
|
||||
public static final Type TYPE_SHARED_DOUBLE = Type.getObjectType("jet/refs/SharedVar$Double");
|
||||
public static final Type TYPE_SHARED_FLOAT = Type.getObjectType("jet/refs/SharedVar$Float");
|
||||
public static final Type TYPE_SHARED_BYTE = Type.getObjectType("jet/refs/SharedVar$Byte");
|
||||
public static final Type TYPE_SHARED_SHORT = Type.getObjectType("jet/refs/SharedVar$Short");
|
||||
public static final Type TYPE_SHARED_CHAR = Type.getObjectType("jet/refs/SharedVar$Char");
|
||||
public static final Type TYPE_SHARED_LONG = Type.getObjectType("jet/refs/SharedVar$Long");
|
||||
public static final Type TYPE_SHARED_BOOLEAN = Type.getObjectType("jet/refs/SharedVar$Boolean");
|
||||
|
||||
public JetTypeMapper(JetStandardLibrary standardLibrary, BindingContext bindingContext) {
|
||||
this.standardLibrary = standardLibrary;
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.objectweb.asm.commons.Method;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
public abstract class StackValue {
|
||||
public final Type type;
|
||||
@@ -59,6 +60,10 @@ public abstract class StackValue {
|
||||
return new Local(index, type);
|
||||
}
|
||||
|
||||
public static StackValue shared(int index, Type type) {
|
||||
return new Shared(index, type);
|
||||
}
|
||||
|
||||
public static StackValue onStack(Type type) {
|
||||
return type == Type.VOID_TYPE ? none() : new OnStack(type);
|
||||
}
|
||||
@@ -225,7 +230,11 @@ public abstract class StackValue {
|
||||
public static StackValue none() {
|
||||
return None.INSTANCE;
|
||||
}
|
||||
|
||||
|
||||
public static StackValue fieldForSharedVar(Type type, String name, String fieldName) {
|
||||
return new FieldForSharedVar(type, name, fieldName);
|
||||
}
|
||||
|
||||
private static class None extends StackValue {
|
||||
public static None INSTANCE = new None();
|
||||
private None() {
|
||||
@@ -496,9 +505,9 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
|
||||
private static class Field extends StackValue {
|
||||
private final String owner;
|
||||
private final String name;
|
||||
static class Field extends StackValue {
|
||||
final String owner;
|
||||
final String name;
|
||||
private final boolean isStatic;
|
||||
|
||||
public Field(Type type, String owner, String name, boolean isStatic) {
|
||||
@@ -531,9 +540,9 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
private static class InstanceField extends StackValue {
|
||||
private final String owner;
|
||||
private final String name;
|
||||
static class InstanceField extends StackValue {
|
||||
final String owner;
|
||||
final String name;
|
||||
|
||||
public InstanceField(Type type, String owner, String name) {
|
||||
super(type);
|
||||
@@ -625,4 +634,106 @@ public abstract class StackValue {
|
||||
generator.gen(expression, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Shared extends StackValue {
|
||||
private final int index;
|
||||
|
||||
public Shared(int index, Type type) {
|
||||
super(type);
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(Type type, InstructionAdapter v) {
|
||||
v.load(index, JetTypeMapper.TYPE_OBJECT);
|
||||
Type refType = refType(this.type);
|
||||
Type sharedType = sharedTypeForType(this.type);
|
||||
v.visitFieldInsn(Opcodes.GETFIELD, sharedType.getInternalName(), "ref", refType.getDescriptor());
|
||||
StackValue.onStack(refType).coerce(this.type, v);
|
||||
StackValue.onStack(this.type).coerce(type, v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(InstructionAdapter v) {
|
||||
v.load(index, JetTypeMapper.TYPE_OBJECT);
|
||||
v.swap();
|
||||
Type refType = refType(this.type);
|
||||
Type sharedType = sharedTypeForType(this.type);
|
||||
v.visitFieldInsn(Opcodes.PUTFIELD, sharedType.getInternalName(), "ref", refType.getDescriptor());
|
||||
}
|
||||
}
|
||||
|
||||
public static Type sharedTypeForType(Type type) {
|
||||
switch(type.getSort()) {
|
||||
case Type.OBJECT:
|
||||
case Type.ARRAY:
|
||||
return JetTypeMapper.TYPE_SHARED_VAR;
|
||||
|
||||
case Type.BYTE:
|
||||
return JetTypeMapper.TYPE_SHARED_BYTE;
|
||||
|
||||
case Type.SHORT:
|
||||
return JetTypeMapper.TYPE_SHARED_SHORT;
|
||||
|
||||
case Type.CHAR:
|
||||
return JetTypeMapper.TYPE_SHARED_CHAR;
|
||||
|
||||
case Type.INT:
|
||||
return JetTypeMapper.TYPE_SHARED_INT;
|
||||
|
||||
case Type.BOOLEAN:
|
||||
return JetTypeMapper.TYPE_SHARED_BOOLEAN;
|
||||
|
||||
case Type.FLOAT:
|
||||
return JetTypeMapper.TYPE_SHARED_FLOAT;
|
||||
|
||||
case Type.DOUBLE:
|
||||
return JetTypeMapper.TYPE_SHARED_DOUBLE;
|
||||
|
||||
default:
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
public static Type refType(Type type) {
|
||||
if(type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY)
|
||||
return JetTypeMapper.TYPE_OBJECT;
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
static class FieldForSharedVar extends StackValue {
|
||||
final String owner;
|
||||
final String name;
|
||||
|
||||
public FieldForSharedVar(Type type, String owner, String name) {
|
||||
super(type);
|
||||
this.owner = owner;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dupReceiver(InstructionAdapter v, int below) {
|
||||
if (below == 1) {
|
||||
v.dupX1();
|
||||
}
|
||||
else {
|
||||
v.dup();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(Type type, InstructionAdapter v) {
|
||||
Type sharedType = sharedTypeForType(this.type);
|
||||
Type refType = refType(this.type);
|
||||
v.visitFieldInsn(Opcodes.GETFIELD, sharedType.getInternalName(), "ref", refType.getDescriptor());
|
||||
StackValue.onStack(refType).coerce(this.type, v);
|
||||
StackValue.onStack(this.type).coerce(type, v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(InstructionAdapter v) {
|
||||
v.visitFieldInsn(Opcodes.PUTFIELD, sharedTypeForType(type).getInternalName(), "ref", refType(type).getDescriptor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
fun box() : String {
|
||||
val cl = 39
|
||||
return if (sum(200, { cl }) == 239) "OK" else "FAIL"
|
||||
return if (sum(200, { val m = { val r = { cl }; r() }; m() }) == 239) "OK" else "FAIL"
|
||||
}
|
||||
|
||||
fun sum(arg:Int, f : fun () : Int) : Int {
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
fun s0() : Boolean {
|
||||
val y = "222"
|
||||
val foo = {
|
||||
val bar = { y }
|
||||
bar ()
|
||||
}
|
||||
return foo() == "222"
|
||||
}
|
||||
|
||||
fun s1() : Boolean {
|
||||
var x = "222"
|
||||
val foo = {
|
||||
val bar = {
|
||||
x = "aaa"
|
||||
}
|
||||
bar ()
|
||||
}
|
||||
foo()
|
||||
return x == "aaa"
|
||||
}
|
||||
|
||||
fun t1() : Boolean {
|
||||
var x = "111"
|
||||
|
||||
val y = x + "22"
|
||||
val foo = {
|
||||
x = x + "45" + y
|
||||
x = x.substring(3)
|
||||
x += "aaa"
|
||||
()
|
||||
}
|
||||
foo()
|
||||
|
||||
x += "bbb"
|
||||
System.out?.println(x)
|
||||
return x == "4511122aaabbb"
|
||||
}
|
||||
|
||||
fun t2() : Boolean {
|
||||
var x = 111
|
||||
val y = x + 22
|
||||
val foo = {
|
||||
x = x + 5 + y
|
||||
x += 5
|
||||
x++
|
||||
()
|
||||
}
|
||||
foo()
|
||||
x -= 55
|
||||
System.out?.println(x)
|
||||
return x == 200
|
||||
}
|
||||
|
||||
fun t3() : Boolean {
|
||||
var x = true
|
||||
val foo = {
|
||||
x = false
|
||||
()
|
||||
}
|
||||
foo()
|
||||
return !x
|
||||
}
|
||||
|
||||
fun t4() : Boolean {
|
||||
var x = 100.flt
|
||||
val y = x + 22
|
||||
val foo = {
|
||||
x = x + 200.flt + y
|
||||
x += 18
|
||||
()
|
||||
}
|
||||
foo()
|
||||
System.out?.println(x)
|
||||
return x == 440.flt
|
||||
}
|
||||
|
||||
fun t5() : Boolean {
|
||||
var x = 100.dbl
|
||||
val y = x + 22
|
||||
val foo = {
|
||||
x = x + 200.dbl + y
|
||||
x -= 22
|
||||
()
|
||||
}
|
||||
foo()
|
||||
System.out?.println(x)
|
||||
return x == 400.dbl
|
||||
}
|
||||
|
||||
fun t6() : Boolean {
|
||||
var x = 20.byt
|
||||
val y = x + 22
|
||||
val foo = {
|
||||
x = (x + 20.byt + y).byt
|
||||
x += 2
|
||||
x--
|
||||
()
|
||||
}
|
||||
foo()
|
||||
System.out?.println(x)
|
||||
return x == 83.byt
|
||||
}
|
||||
|
||||
fun t7() : Boolean {
|
||||
var x : Char = 'a'
|
||||
val foo = {
|
||||
x = 'b'
|
||||
()
|
||||
}
|
||||
foo()
|
||||
System.out?.println(x)
|
||||
return x == 'b'
|
||||
}
|
||||
|
||||
fun t8() : Boolean {
|
||||
var x = 20.sht
|
||||
val foo = {
|
||||
val bar = {
|
||||
x = 30.sht
|
||||
()
|
||||
}
|
||||
bar()
|
||||
()
|
||||
}
|
||||
foo()
|
||||
return x == 30.sht
|
||||
}
|
||||
|
||||
fun t9(x: Int) : Boolean {
|
||||
while(x < 100) {
|
||||
x++
|
||||
}
|
||||
return x == 100
|
||||
}
|
||||
|
||||
fun t10() : Boolean {
|
||||
var y = 1
|
||||
val foo = {
|
||||
val bar = {
|
||||
y = y + 1
|
||||
}
|
||||
bar()
|
||||
}
|
||||
foo()
|
||||
return y == 2
|
||||
}
|
||||
|
||||
fun t11(x: Int) : Int {
|
||||
val foo = {
|
||||
x = x + 1
|
||||
val bar = {
|
||||
x = x + 1
|
||||
x += 3
|
||||
}
|
||||
bar()
|
||||
}
|
||||
while(x < 100) {
|
||||
foo()
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (!s0()) return "fail"
|
||||
if (!s1()) return "fail"
|
||||
if (!t1()) return "fail"
|
||||
if (!t2()) return "fail"
|
||||
if (!t3()) return "fail"
|
||||
if (!t4()) return "fail"
|
||||
if (!t5()) return "fail"
|
||||
if (!t6()) return "fail"
|
||||
if (!t7()) return "fail"
|
||||
if (!t8()) return "fail"
|
||||
if (!t9(0)) return "fail"
|
||||
if (!t10()) return "fail"
|
||||
if (t11(1) != 104) return "fail"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -190,4 +190,10 @@ public class ClassGenTest extends CodegenTestCase {
|
||||
blackBoxFile("regressions/kt343.jet");
|
||||
System.out.println(generateToText());
|
||||
}
|
||||
|
||||
public void testKt344 () throws Exception {
|
||||
loadFile("regressions/kt344.jet");
|
||||
System.out.println(generateToText());
|
||||
blackBox();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ public class ClosuresGenTest extends CodegenTestCase {
|
||||
|
||||
public void testEnclosingLocalVariable() throws Exception {
|
||||
blackBoxFile("classes/enclosingLocalVariable.jet");
|
||||
System.out.println(generateToText());
|
||||
}
|
||||
|
||||
public void testDoubleEnclosedLocalVariable() throws Exception {
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package jet.refs;
|
||||
|
||||
public final class SharedVar {
|
||||
public static final class Object<T> {
|
||||
public T ref;
|
||||
}
|
||||
|
||||
public static final class Byte {
|
||||
public byte ref;
|
||||
}
|
||||
|
||||
public static final class Short {
|
||||
public short ref;
|
||||
}
|
||||
|
||||
public static final class Int {
|
||||
public int ref;
|
||||
}
|
||||
|
||||
public static final class Long {
|
||||
public long ref;
|
||||
}
|
||||
|
||||
public static final class Float {
|
||||
public float ref;
|
||||
}
|
||||
|
||||
public static final class Double {
|
||||
public double ref;
|
||||
}
|
||||
|
||||
public static final class Char {
|
||||
public char ref;
|
||||
}
|
||||
|
||||
public static final class Boolean {
|
||||
public boolean ref;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user