/** * Constructor. * * @param type a {@code char}, the type of this value. * @param calc a {@link Calculator}. * @throws InvalidTypeException if {@code type} is not primitive. */ Primitive(char type, Calculator calc) throws InvalidTypeException { super(type); if (!Type.isPrimitive(type)) { throw new InvalidTypeException(type + " is not a primitive type"); } this.calc = calc; }
/** * Possibly loads frames on a state for triggers execution. * * @param state a {@link State}. * @param da a {@link DecisionAlternative_XYLOAD_GETX_Loads}. If it is a {@link * DecisionAlternative_XYLOAD_GETX_Unresolved} and has a trigger method, a frame for it will * be pushed on {@code state}. Otherwise, {@code state} remains unchanged. * @param pcOffset an {@code int}, an offset for the program counter of {@code state}. Used as * return offset after the execution of the trigger method. * @return {@code true} iff the method loads at least one trigger frame on {@code state}. * @throws InvalidProgramCounterException when {@code pcOffset} is not a valid return offset. * @throws ThreadStackEmptyException if {@code state}'s thread stack is empty. */ public boolean loadTriggerFrames( State state, DecisionAlternative_XYLOAD_GETX_Loads da, int pcOffset) throws InvalidProgramCounterException, ThreadStackEmptyException { if (!(da instanceof DecisionAlternative_XYLOAD_GETX_Unresolved)) { return false; } // handles triggers by creating a frame for the fresh object; // first, gets data final ReferenceSymbolic ref = ((DecisionAlternative_XYLOAD_GETX_Unresolved) da).getValueToLoad(); final ArrayList<TriggerRule> rules = satisfiedTriggerRules(state, da, this.triggerRulesRepo); // then, pushes all the frames boolean retVal = false; for (TriggerRule rule : rules) { final Signature triggerSig = rule.getTriggerSignature(); if (Type.splitReturnValueDescriptor(triggerSig.getDescriptor()).equals("" + Type.VOID) && Type.splitParametersDescriptors(triggerSig.getDescriptor()).length <= 1) { final ReferenceConcrete triggerArg = getTriggerMethodParameterObject(rule, ref, state); try { // TODO resolution? lookup of implementation? state.pushFrame(triggerSig, false, pcOffset, triggerArg); retVal = true; pcOffset = 0; // the offset of the second, third... frames } catch (MethodNotFoundException | MethodCodeNotFoundException | InvalidSlotException e) { // does nothing, falls through to skip // the nonexistent/nonstatic/native method // TODO should we throw an exception? are we sure that they are all not internal // exceptions? } catch (BadClassFileException | NullMethodReceiverException e) { // this should never happen throw new UnexpectedInternalException(e); } } // TODO should we throw an exception if the signature is not ok? } return retVal; }
private WideningConversion(char type, Calculator calc, Primitive arg) throws InvalidOperandException, InvalidTypeException { super(type, calc); // checks on parameters if (arg == null) { throw new InvalidOperandException("null operand in widening construction"); } if (!Type.widens(type, arg.getType())) { throw new InvalidTypeException("cannot widen type " + arg.getType() + " to type " + type); } this.arg = arg; // calculates hashCode final int prime = 281; int result = 1; result = prime * result + arg.hashCode(); result = prime * result + type; this.hashCode = result; // calculates toString this.toString = "WIDEN-" + this.getType() + "(" + arg.toString() + ")"; }