package edu.mit.streamjit.impl.compiler.insts;

import static com.google.common.base.Preconditions.*;
import edu.mit.streamjit.impl.compiler.Field;
import edu.mit.streamjit.impl.compiler.Value;
import edu.mit.streamjit.impl.compiler.types.InstanceFieldType;

/**
 * Loads a static or instance field.  (Does not load array elements.)
 * @author Jeffrey Bosboom <jeffreybosboom@gmail.com>
 * @since 4/14/2013
 */
public class LoadInst extends Instruction {
	public LoadInst(Field f) {
		super(f.getType().getFieldType(), f.isStatic() ? 1 : 2);
		setOperand(0, f);
	}
	public LoadInst(Field f, Value v) {
		this(f);
		setOperand(1, v);
	}

	public Field getField() {
		return (Field)getOperand(0);
	}
	public void setField(Field f) {
		setOperand(0, f);
	}
	public Value getInstance() {
		return getOperand(1);
	}
	public void setInstance(Value v) {
		setOperand(1, v);
	}

	@Override
	protected void checkOperand(int i, Value v) {
		checkElementIndex(i, 2);
		if (i == 0)
			checkArgument(v instanceof Field && ((Field)v).isStatic() == getField().isStatic());
		else if (i == 1) {
			checkState(!getField().isStatic());
			checkArgument(v.getType().isSubtypeOf(((InstanceFieldType)getField().getType()).getInstanceType()));
		}
		super.checkOperand(i, v);
	}
}

@@ -250,16 +250,78 @@
 eldType;
+%0Aimport edu.mit.streamjit.impl.compiler.types.StaticFieldType;
 %0A%0A/**%0A *
@@ -546,17 +546,31 @@
 %09%09super(
-f
+checkNotNull(f)
 .getType
@@ -1038,16 +1038,18 @@
 (i == 0)
+ %7B
 %0A%09%09%09chec
@@ -1080,12 +1080,28 @@
 ield
- && 
+);%0A%09%09%09checkArgument(
 ((Fi
@@ -1124,39 +1124,56 @@
 ) == get
-Field().isStatic()
+Type() instanceof StaticFieldType
 );%0A%09%09
+%7D 
 else if 
@@ -1201,30 +1201,46 @@
 ate(
-!
 get
-Field().isStatic()
+Type() instanceof InstanceFieldType
 );%0A%09

check against type, not current field