/** * Awaits the lock on {@code monitor}, and acquires it. */ public void monitorEnter(Local<?> monitor) { addInstruction(new ThrowingInsn(Rops.MONITOR_ENTER, sourcePosition, RegisterSpecList.make(monitor.spec()), catches)); }
/** * Releases the held lock on {@code monitor}. */ public void monitorExit(Local<?> monitor) { addInstruction(new ThrowingInsn(Rops.MONITOR_EXIT, sourcePosition, RegisterSpecList.make(monitor.spec()), catches)); }
/** * Throws the throwable in {@code toThrow}. */ public void throwValue(Local<? extends Throwable> toThrow) { addInstruction(new ThrowingInsn(Rops.THROW, sourcePosition, RegisterSpecList.make(toThrow.spec()), catches)); }
/** * Tests if the value in {@code source} is assignable to {@code type}. If it * is, {@code target} is assigned to 1; otherwise {@code target} is assigned * to 0. */ public void instanceOfType(Local<?> target, Local<?> source, TypeId<?> type) { addInstruction(new ThrowingCstInsn(Rops.INSTANCE_OF, sourcePosition, RegisterSpecList.make(source.spec()), catches, type.constant)); moveResult(target, true); }
/** * Copies the value in {@code source} to the static field {@code fieldId}. */ public <V> void sput(FieldId<?, V> fieldId, Local<? extends V> source) { addInstruction(new ThrowingCstInsn(Rops.opPutStatic(source.type.ropType), sourcePosition, RegisterSpecList.make(source.spec()), catches, fieldId.constant)); }
/** * Sets {@code target} to the length of the array in {@code array}. */ public <T> void arrayLength(Local<Integer> target, Local<T> array) { addInstruction(new ThrowingInsn(Rops.ARRAY_LENGTH, sourcePosition, RegisterSpecList.make(array.spec()), catches)); moveResult(target, true); }
/** * Returns the value in {@code result} to the calling method. After a return * it is an error to define further instructions after a return without * first {@link #mark marking} an existing unmarked label. */ public void returnValue(Local<?> result) { if (!result.type.equals(method.returnType)) { // TODO: this is probably too strict. throw new IllegalArgumentException("declared " + method.returnType + " but returned " + result.type); } addInstruction(new PlainInsn(Rops.opReturn(result.type.ropType), sourcePosition, null, RegisterSpecList.make(result.spec()))); }
/** * Compare longs. This stores -1 in {@code target} if {@code * a < b}, 0 in {@code target} if {@code a == b} and 1 in target if {@code * a > b}. */ public void compareLongs(Local<Integer> target, Local<Long> a, Local<Long> b) { addInstruction(new PlainInsn(Rops.CMPL_LONG, sourcePosition, target.spec(), RegisterSpecList.make(a.spec(), b.spec()))); }
/** * Copies the value in instance field {@code fieldId} of {@code instance} to * {@code target}. */ public <D, V> void iget(FieldId<D, ? extends V> fieldId, Local<V> target, Local<D> instance) { addInstruction(new ThrowingCstInsn(Rops.opGetField(target.type.ropType), sourcePosition, RegisterSpecList.make(instance.spec()), catches, fieldId.constant)); moveResult(target, true); }
/** * Copies the value in {@code source} to the instance field {@code fieldId} * of {@code instance}. */ public <D, V> void iput(FieldId<D, V> fieldId, Local<? extends D> instance, Local<? extends V> source) { addInstruction(new ThrowingCstInsn(Rops.opPutField(source.type.ropType), sourcePosition, RegisterSpecList.make(source.spec(), instance.spec()), catches, fieldId.constant)); }
/** * Assigns {@code target} to a newly allocated array of length {@code * length}. The array's type is the same as {@code target}'s type. */ public <T> void newArray(Local<T> target, Local<Integer> length) { addInstruction(new ThrowingCstInsn(Rops.opNewArray(target.type.ropType), sourcePosition, RegisterSpecList.make(length.spec()), catches, target.type.constant)); moveResult(target, true); }
/** * Check if an int or reference equals to zero. If the comparison is true, * execution jumps to {@code trueLabel}. If it is false, execution continues to * the next instruction. */ public <T> void compareZ(Comparison comparison, Label trueLabel, Local<?> a) { adopt(trueLabel); Rop rop = comparison.rop(StdTypeList.make(a.type.ropType)); addInstruction(new PlainInsn(rop, sourcePosition, null, RegisterSpecList.make(a.spec())), trueLabel); }
/** * Assigns the element at {@code index} in {@code array} to {@code target}. */ public void aget(Local<?> target, Local<?> array, Local<Integer> index) { addInstruction(new ThrowingInsn(Rops.opAget(target.type.ropType), sourcePosition, RegisterSpecList.make(array.spec(), index.spec()), catches)); moveResult(target, true); }
/** * Assigns {@code source} to the element at {@code index} in {@code array}. */ public void aput(Local<?> array, Local<Integer> index, Local<?> source) { addInstruction(new ThrowingInsn(Rops.opAput(source.type.ropType), sourcePosition, RegisterSpecList.make(source.spec(), array.spec(), index.spec()), catches)); }
/** * Compare floats or doubles. This stores -1 in {@code target} if {@code * a < b}, 0 in {@code target} if {@code a == b} and 1 in target if {@code * a > b}. This stores {@code nanValue} in {@code target} if either value * is {@code NaN}. */ public <T extends Number> void compareFloatingPoint( Local<Integer> target, Local<T> a, Local<T> b, int nanValue) { Rop rop; if (nanValue == 1) { rop = Rops.opCmpg(a.type.ropType); } else if (nanValue == -1) { rop = Rops.opCmpl(a.type.ropType); } else { throw new IllegalArgumentException("expected 1 or -1 but was " + nanValue); } addInstruction(new PlainInsn(rop, sourcePosition, target.spec(), RegisterSpecList.make(a.spec(), b.spec()))); }
/** * Compare ints or references. If the comparison is true, execution jumps to * {@code trueLabel}. If it is false, execution continues to the next * instruction. */ public <T> void compare(Comparison comparison, Label trueLabel, Local<T> a, Local<T> b) { adopt(trueLabel); Rop rop = comparison.rop(StdTypeList.make(a.type.ropType, b.type.ropType)); addInstruction(new PlainInsn(rop, sourcePosition, null, RegisterSpecList.make(a.spec(), b.spec())), trueLabel); }
/** * Executes {@code op} and sets {@code target} to the result. For most * binary operations, the types of {@code a} and {@code b} must be the same. * Shift operations (like {@link BinaryOp#SHIFT_LEFT}) require {@code b} to * be an {@code int}, even when {@code a} is a {@code long}. */ public <T1, T2> void op(BinaryOp op, Local<T1> target, Local<T1> a, Local<T2> b) { Rop rop = op.rop(StdTypeList.make(a.type.ropType, b.type.ropType)); RegisterSpecList sources = RegisterSpecList.make(a.spec(), b.spec()); if (rop.getBranchingness() == BRANCH_NONE) { addInstruction(new PlainInsn(rop, sourcePosition, target.spec(), sources)); } else { addInstruction(new ThrowingInsn(rop, sourcePosition, sources, catches)); moveResult(target, true); } }
if (source.getType().ropType.isReference()) { addInstruction(new ThrowingCstInsn(Rops.CHECK_CAST, sourcePosition, RegisterSpecList.make(source.spec()), catches, target.type.constant)); moveResult(target, true); } else {
/** * Throws the throwable in {@code toThrow}. */ public void throwValue(Local<? extends Throwable> toThrow) { addInstruction(new ThrowingInsn(Rops.THROW, sourcePosition, RegisterSpecList.make(toThrow.spec()), catches)); }
/** * Copies the value in instance field {@code fieldId} of {@code instance} to * {@code target}. */ public <D, V> void iget(FieldId<D, ? extends V> fieldId, Local<V> target, Local<D> instance) { addInstruction(new ThrowingCstInsn(Rops.opGetField(target.type.ropType), sourcePosition, RegisterSpecList.make(instance.spec()), catches, fieldId.constant)); moveResult(target, true); }