Interface refs

This commit is contained in:
Michael Bogdanov
2014-11-13 15:47:47 +03:00
parent fe1c6a0ca6
commit c5d8f1faf5
3 changed files with 62 additions and 132 deletions
@@ -1,41 +0,0 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
public interface IStackValue {
void moveToTopOfStack(@NotNull Type type, @NotNull InstructionAdapter v, int depth);
void put(@NotNull Type type, @NotNull InstructionAdapter v, boolean skipReceiver);
void store(@NotNull StackValue value, @NotNull InstructionAdapter v, boolean skipReceiver);
void condJump(@NotNull Label label, boolean jumpIfFalse, @NotNull InstructionAdapter v);
void coerceTo(@NotNull Type toType, @NotNull InstructionAdapter v);
void coerceFrom(@NotNull Type topOfStackType, @NotNull InstructionAdapter v);
void putAsBoolean(InstructionAdapter v);
void dup(@NotNull InstructionAdapter v, boolean withReceiver);
}
@@ -47,15 +47,12 @@ import static org.jetbrains.jet.codegen.AsmUtil.*;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
import static org.jetbrains.org.objectweb.asm.Opcodes.*; import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public abstract class StackValue implements IStackValue { public abstract class StackValue {
private static final String NULLABLE_BYTE_TYPE_NAME = "java/lang/Byte"; private static final String NULLABLE_BYTE_TYPE_NAME = "java/lang/Byte";
private static final String NULLABLE_SHORT_TYPE_NAME = "java/lang/Short"; private static final String NULLABLE_SHORT_TYPE_NAME = "java/lang/Short";
private static final String NULLABLE_LONG_TYPE_NAME = "java/lang/Long"; private static final String NULLABLE_LONG_TYPE_NAME = "java/lang/Long";
public static final int RECEIVER_READ = 0;
public static final int RECEIVER_WRITE = 1;
public static final StackValue.Local LOCAL_0 = local(0, OBJECT_TYPE); public static final StackValue.Local LOCAL_0 = local(0, OBJECT_TYPE);
private static final StackValue UNIT = operation(UNIT_TYPE, new Function1<InstructionAdapter, Unit>() { private static final StackValue UNIT = operation(UNIT_TYPE, new Function1<InstructionAdapter, Unit>() {
@Override @Override
@@ -80,7 +77,6 @@ public abstract class StackValue implements IStackValue {
* @param v the visitor used to genClassOrObject the instructions * @param v the visitor used to genClassOrObject the instructions
* @param depth the number of new values put onto the stack * @param depth the number of new values put onto the stack
*/ */
@Override
public void moveToTopOfStack(@NotNull Type type, @NotNull InstructionAdapter v, int depth) { public void moveToTopOfStack(@NotNull Type type, @NotNull InstructionAdapter v, int depth) {
put(type, v); put(type, v);
} }
@@ -89,12 +85,21 @@ public abstract class StackValue implements IStackValue {
put(type, v, false); put(type, v, false);
} }
@Override
public void put(@NotNull Type type, @NotNull InstructionAdapter v, boolean skipReceiver) { public void put(@NotNull Type type, @NotNull InstructionAdapter v, boolean skipReceiver) {
if (!skipReceiver) {
putReceiver(v, true);
}
putSelector(type, v); putSelector(type, v);
} }
@Override public abstract void putSelector(@NotNull Type type, @NotNull InstructionAdapter v);
public boolean hasReceiver(boolean isRead) {
return false;
}
public void putReceiver(@NotNull InstructionAdapter v, boolean isRead) {}
public void dup(@NotNull InstructionAdapter v, boolean withReceiver) { public void dup(@NotNull InstructionAdapter v, boolean withReceiver) {
switch (type.getSize()) { switch (type.getSize()) {
case 0: break; case 0: break;
@@ -105,23 +110,22 @@ public abstract class StackValue implements IStackValue {
} }
} }
public void storeSelector(@NotNull Type topOfStackType, @NotNull InstructionAdapter v) {
throw new UnsupportedOperationException("cannot store to value " + this);
}
public abstract void putSelector(@NotNull Type type, @NotNull InstructionAdapter v);
@Override
public void store(@NotNull StackValue value, @NotNull InstructionAdapter v, boolean skipReceiver) {
value.put(value.type, v);
storeSelector(value.type, v);
}
public void store(@NotNull StackValue value, @NotNull InstructionAdapter v) { public void store(@NotNull StackValue value, @NotNull InstructionAdapter v) {
store(value, v, false); store(value, v, false);
} }
@Override public void store(@NotNull StackValue value, @NotNull InstructionAdapter v, boolean skipReceiver) {
if (!skipReceiver) {
putReceiver(v, false);
}
value.put(value.type, v);
storeSelector(value.type, v);
}
public void storeSelector(@NotNull Type topOfStackType, @NotNull InstructionAdapter v) {
throw new UnsupportedOperationException("cannot store to value " + this);
}
public void condJump(@NotNull Label label, boolean jumpIfFalse, @NotNull InstructionAdapter v) { public void condJump(@NotNull Label label, boolean jumpIfFalse, @NotNull InstructionAdapter v) {
put(this.type, v); put(this.type, v);
coerceTo(Type.BOOLEAN_TYPE, v); coerceTo(Type.BOOLEAN_TYPE, v);
@@ -284,13 +288,11 @@ public abstract class StackValue implements IStackValue {
} }
} }
@Override protected void coerceTo(@NotNull Type toType, @NotNull InstructionAdapter v) {
public void coerceTo(@NotNull Type toType, @NotNull InstructionAdapter v) {
coerce(this.type, toType, v); coerce(this.type, toType, v);
} }
@Override protected void coerceFrom(@NotNull Type topOfStackType, @NotNull InstructionAdapter v) {
public void coerceFrom(@NotNull Type topOfStackType, @NotNull InstructionAdapter v) {
coerce(topOfStackType, this.type, v); coerce(topOfStackType, this.type, v);
} }
@@ -361,7 +363,6 @@ public abstract class StackValue implements IStackValue {
return UNIT; return UNIT;
} }
@Override
public void putAsBoolean(InstructionAdapter v) { public void putAsBoolean(InstructionAdapter v) {
Label ifTrue = new Label(); Label ifTrue = new Label();
Label end = new Label(); Label end = new Label();
@@ -1321,7 +1322,7 @@ public abstract class StackValue implements IStackValue {
@Override @Override
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) { public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
value = StackValue.complexReceiver(value, RECEIVER_READ, RECEIVER_WRITE, RECEIVER_READ); value = StackValue.complexReceiver(value, true, false, true);
value.put(this.type, v); value.put(this.type, v);
if (callable instanceof CallableMethod) { if (callable instanceof CallableMethod) {
@@ -1444,11 +1445,13 @@ public abstract class StackValue implements IStackValue {
} }
} }
public abstract static class StackValueWithSimpleReceiver extends StackValueWithReceiver { public abstract static class StackValueWithSimpleReceiver extends StackValue {
public final boolean isStaticPut; public final boolean isStaticPut;
public final boolean isStaticStore; public final boolean isStaticStore;
@NotNull
public final StackValue receiver;
public StackValueWithSimpleReceiver( public StackValueWithSimpleReceiver(
@NotNull Type type, @NotNull Type type,
@@ -1456,20 +1459,12 @@ public abstract class StackValue implements IStackValue {
boolean isStaticStore, boolean isStaticStore,
@NotNull StackValue receiver @NotNull StackValue receiver
) { ) {
super(type, receiver); super(type);
this.receiver = receiver;
this.isStaticPut = isStaticPut; this.isStaticPut = isStaticPut;
this.isStaticStore = isStaticStore; this.isStaticStore = isStaticStore;
} }
@Override
public void put(@NotNull Type type, @NotNull InstructionAdapter v, boolean skipReceiver) {
if (!skipReceiver) {
putReceiver(v, true);
}
putSelector(type, v);
}
@Override @Override
public void putReceiver(@NotNull InstructionAdapter v, boolean isRead) { public void putReceiver(@NotNull InstructionAdapter v, boolean isRead) {
if (hasReceiver(isRead)) { if (hasReceiver(isRead)) {
@@ -1481,23 +1476,6 @@ public abstract class StackValue implements IStackValue {
public boolean hasReceiver(boolean isRead) { public boolean hasReceiver(boolean isRead) {
return isRead ? !isStaticPut : !isStaticStore; return isRead ? !isStaticPut : !isStaticStore;
} }
}
public abstract static class StackValueWithReceiver extends StackValue {
@NotNull public final StackValue receiver;
protected StackValueWithReceiver(@NotNull Type type, @NotNull StackValue receiver) {
super(type);
this.receiver = receiver;
}
@Override
public abstract void put(@NotNull Type type, @NotNull InstructionAdapter v, boolean skipReceiver);
public abstract void putReceiver(@NotNull InstructionAdapter v, boolean isRead);
public abstract boolean hasReceiver(boolean isRead);
public int receiverSize() { public int receiverSize() {
return receiver.type.getSize(); return receiver.type.getSize();
@@ -1506,7 +1484,7 @@ public abstract class StackValue implements IStackValue {
@Override @Override
public void dup(@NotNull InstructionAdapter v, boolean withReceiver) { public void dup(@NotNull InstructionAdapter v, boolean withReceiver) {
if (!withReceiver) { if (!withReceiver) {
super.dup(v, false); super.dup(v, withReceiver);
} else { } else {
int receiverSize = hasReceiver(false) && hasReceiver(true) ? receiverSize() : 0; int receiverSize = hasReceiver(false) && hasReceiver(true) ? receiverSize() : 0;
switch (receiverSize) { switch (receiverSize) {
@@ -1552,13 +1530,13 @@ public abstract class StackValue implements IStackValue {
static class ComplexReceiver extends StackValue { static class ComplexReceiver extends StackValue {
private final StackValueWithReceiver originalValueWithReceiver; private final StackValueWithSimpleReceiver originalValueWithReceiver;
private final int[] operations; private final boolean [] isReadOperations;
public ComplexReceiver(StackValueWithReceiver value, int [] operations) { public ComplexReceiver(StackValueWithSimpleReceiver value, boolean [] isReadOperations) {
super(value.type); super(value.type);
this.originalValueWithReceiver = value; this.originalValueWithReceiver = value;
this.operations = operations; this.isReadOperations = isReadOperations;
} }
@Override @Override
@@ -1566,8 +1544,8 @@ public abstract class StackValue implements IStackValue {
@NotNull Type type, @NotNull InstructionAdapter v @NotNull Type type, @NotNull InstructionAdapter v
) { ) {
boolean wasPutted = false; boolean wasPutted = false;
for (int operation : operations) { for (boolean operation : isReadOperations) {
if (originalValueWithReceiver.hasReceiver(operation == RECEIVER_READ)) { if (originalValueWithReceiver.hasReceiver(operation)) {
StackValue receiver = originalValueWithReceiver.receiver; StackValue receiver = originalValueWithReceiver.receiver;
if (!wasPutted) { if (!wasPutted) {
receiver.put(receiver.type, v); receiver.put(receiver.type, v);
@@ -1601,11 +1579,11 @@ public abstract class StackValue implements IStackValue {
public static class Delegated extends StackValueWithSimpleReceiver { public static class Delegated extends StackValueWithSimpleReceiver {
public final StackValueWithReceiver originalValue; public final StackValueWithSimpleReceiver originalValue;
public Delegated( public Delegated(
@NotNull Type type, @NotNull Type type,
@NotNull StackValueWithReceiver originalValue, @NotNull StackValueWithSimpleReceiver originalValue,
@NotNull StackValue receiver @NotNull StackValue receiver
) { ) {
super(type, !originalValue.hasReceiver(true), !originalValue.hasReceiver(false), receiver); super(type, !originalValue.hasReceiver(true), !originalValue.hasReceiver(false), receiver);
@@ -1633,13 +1611,13 @@ public abstract class StackValue implements IStackValue {
} }
public static StackValue complexWriteReadReceiver(StackValue stackValue) { public static StackValue complexWriteReadReceiver(StackValue stackValue) {
return complexReceiver(stackValue, RECEIVER_WRITE, RECEIVER_READ); return complexReceiver(stackValue, false, true);
} }
private static StackValue complexReceiver(StackValue stackValue, int ... operations) { private static StackValue complexReceiver(StackValue stackValue, boolean ... isReadOperations) {
if (stackValue instanceof StackValueWithReceiver) { if (stackValue instanceof StackValueWithSimpleReceiver) {
return new Delegated(stackValue.type, (StackValueWithReceiver) stackValue, return new Delegated(stackValue.type, (StackValueWithSimpleReceiver) stackValue,
new ComplexReceiver((StackValueWithSimpleReceiver) stackValue, operations)); new ComplexReceiver((StackValueWithSimpleReceiver) stackValue, isReadOperations));
} else { } else {
return stackValue; return stackValue;
} }
@@ -19,30 +19,31 @@ package org.jetbrains.jet.codegen
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.jet.codegen.StackValue.StackValueWithReceiver
import org.jetbrains.jet.codegen.StackValue.StackValueWithSimpleReceiver import org.jetbrains.jet.codegen.StackValue.StackValueWithSimpleReceiver
public fun coercion(value: StackValue, castType: Type): StackValue { public fun coercion(value: StackValue, castType: Type): StackValue {
return if (value is StackValueWithReceiver) CoercionValueWithReceiver(value, castType) else CoercionValue(value, castType) return CoercionValue(value, castType)
} }
class CoercionValue(val value: StackValue, val castType: Type) : StackValue(castType), IStackValue by value { class CoercionValue(
val value: StackValue,
val castType: Type
) : StackValue(castType) {
override fun putSelector(type: Type, v: InstructionAdapter) { override fun putSelector(type: Type, v: InstructionAdapter) {
value.putSelector(type, v) value.putSelector(type, v)
} }
}
class CoercionValueWithReceiver( override fun storeSelector(topOfStackType: Type, v: InstructionAdapter) {
val value: StackValueWithReceiver, value.storeSelector(topOfStackType, v)
val castType: Type }
) : StackValueWithSimpleReceiver(castType, !value.hasReceiver(true), !value.hasReceiver(false), value.receiver), IStackValue by value {
override fun putReceiver(v: InstructionAdapter, isRead: Boolean) { override fun putReceiver(v: InstructionAdapter, isRead: Boolean) {
value.putReceiver(v, isRead) value.putReceiver(v, isRead)
} }
override fun putSelector(type: Type, v: InstructionAdapter) { override fun condJump(label: Label, jumpIfFalse: Boolean, v: InstructionAdapter) {
value.putSelector(type, v) value.condJump(label, jumpIfFalse, v)
} }
override fun hasReceiver(isRead: Boolean): Boolean { override fun hasReceiver(isRead: Boolean): Boolean {
@@ -54,34 +55,26 @@ class CoercionValueWithReceiver(
public class StackValueWithLeaveTask( public class StackValueWithLeaveTask(
val stackValue: StackValue, val stackValue: StackValue,
val leaveTasks: StackValueWithLeaveTask.() -> Unit val leaveTasks: StackValueWithLeaveTask.() -> Unit
) : StackValueWithReceiver( ) : StackValue(stackValue.type) {
stackValue.type,
if (stackValue is StackValueWithReceiver) stackValue.receiver else StackValue.none()
), IStackValue by stackValue {
override fun put(type: Type, v: InstructionAdapter) { override fun put(type: Type, v: InstructionAdapter, skipReceiver: Boolean) {
stackValue.put(type, v) stackValue.put(type, v, skipReceiver)
leaveTasks() leaveTasks()
} }
override fun condJump(label: Label, jumpIfFalse: Boolean, v: InstructionAdapter ) { override fun condJump(label: Label, jumpIfFalse: Boolean, v: InstructionAdapter) {
stackValue.condJump(label, jumpIfFalse, v) stackValue.condJump(label, jumpIfFalse, v)
leaveTasks() leaveTasks()
} }
override fun putReceiver(v: InstructionAdapter, isRead: Boolean) { override fun putReceiver(v: InstructionAdapter, isRead: Boolean) {
if (stackValue is StackValueWithReceiver) { stackValue.putReceiver(v, isRead)
stackValue.putReceiver(v, isRead)
}
} }
override fun putSelector(type: Type, v: InstructionAdapter) { override fun putSelector(type: Type, v: InstructionAdapter) {
throw UnsupportedOperationException() throw UnsupportedOperationException()
} }
override fun hasReceiver(isRead: Boolean): Boolean {
throw UnsupportedOperationException()
}
override fun storeSelector(topOfStackType: Type, v: InstructionAdapter) { override fun storeSelector(topOfStackType: Type, v: InstructionAdapter) {
throw UnsupportedOperationException(); throw UnsupportedOperationException();