예제 #1
0
 @Override
 public void translate(
     boolean isStatic,
     int scriptIndex,
     int classIndex,
     HashMap<Integer, GraphTargetItem> localRegs,
     TranslateStack stack,
     ScopeStack scopeStack,
     AVM2ConstantPool constants,
     AVM2Instruction ins,
     List<MethodInfo> method_info,
     List<GraphTargetItem> output,
     MethodBody body,
     ABC abc,
     HashMap<Integer, String> localRegNames,
     List<DottedChain> fullyQualifiedNames,
     String path,
     HashMap<Integer, Integer> localRegsAssignmentIps,
     int ip,
     HashMap<Integer, List<Integer>> refs,
     AVM2Code code) {
   int multinameIndex = ins.operands[0];
   FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins);
   GraphTargetItem obj = stack.pop();
   stack.push(new GetPropertyAVM2Item(ins, obj, multiname));
 }
 @Override
 public void translateInverted(
     HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, AVM2Instruction ins) {
   GraphTargetItem v2 = stack.pop();
   GraphTargetItem v1 = stack.pop();
   stack.push(new StrictEqAVM2Item(ins, v1, v2));
 }
예제 #3
0
 @Override
 public void translate(
     boolean isStatic,
     int scriptIndex,
     int classIndex,
     HashMap<Integer, GraphTargetItem> localRegs,
     TranslateStack stack,
     ScopeStack scopeStack,
     AVM2ConstantPool constants,
     AVM2Instruction ins,
     List<MethodInfo> method_info,
     List<GraphTargetItem> output,
     MethodBody body,
     ABC abc,
     HashMap<Integer, String> localRegNames,
     List<String> fullyQualifiedNames,
     String path,
     HashMap<Integer, Integer> localRegsAssignmentIps,
     int ip,
     HashMap<Integer, List<Integer>> refs,
     AVM2Code code) {
   GraphTargetItem v2 = stack.pop();
   GraphTargetItem v1 = stack.pop();
   stack.push(new EqAVM2Item(ins, v1, v2));
 }
예제 #4
0
 @Override
 public void translate(
     AVM2LocalData localData,
     TranslateStack stack,
     AVM2Instruction ins,
     List<GraphTargetItem> output,
     String path) {
   stack.push(new ConvertAVM2Item(ins, stack.pop(), getTargetType(localData.getConstants(), ins)));
 }
  @Override
  public int getStackPopCount(BaseLocalData localData, TranslateStack stack) {
    int result = 3;
    if (stack.size() >= 3) {
      result += stack.peek(3).getAsLong();
    }

    return result;
  }
예제 #6
0
 @Override
 public void translate(
     AVM2LocalData localData,
     TranslateStack stack,
     AVM2Instruction ins,
     List<GraphTargetItem> output,
     String path) {
   GraphTargetItem obj = stack.pop();
   stack.push(new FilteredCheckAVM2Item(ins, localData.lineStartInstruction, obj));
 }
예제 #7
0
  @Override
  public void translate(
      AVM2LocalData localData,
      TranslateStack stack,
      AVM2Instruction ins,
      List<GraphTargetItem> output,
      String path)
      throws InterruptedException {
    int argCount = ins.operands[0];
    List<GraphTargetItem> args = new ArrayList<>();
    for (int a = 0; a < argCount; a++) {
      args.add(0, stack.pop());
    }
    GraphTargetItem obj = stack.pop();

    boolean isXML = false;
    if (obj instanceof GetPropertyAVM2Item) {
      GetPropertyAVM2Item gpt = (GetPropertyAVM2Item) obj;
      if (gpt.object instanceof FindPropertyAVM2Item) {
        FindPropertyAVM2Item fpt = (FindPropertyAVM2Item) gpt.object;
        FullMultinameAVM2Item fptXmlMult = (FullMultinameAVM2Item) fpt.propertyName;
        FullMultinameAVM2Item gptXmlMult = (FullMultinameAVM2Item) gpt.propertyName;

        isXML =
            fptXmlMult.isXML(
                    localData.getConstants(),
                    localData.localRegNames,
                    localData.fullyQualifiedNames)
                && gptXmlMult.isXML(
                    localData.getConstants(),
                    localData.localRegNames,
                    localData.fullyQualifiedNames);
      }
    }
    if (obj instanceof GetLexAVM2Item) {
      GetLexAVM2Item glt = (GetLexAVM2Item) obj;
      isXML =
          glt.propertyName
              .getName(localData.getConstants(), localData.fullyQualifiedNames, true)
              .equals("XML");
    }

    if (isXML) {
      if (args.size() == 1) {
        GraphTargetItem arg = args.get(0);
        List<GraphTargetItem> xmlLines = new ArrayList<>();
        if (walkXML(arg, xmlLines)) {
          stack.push(new XMLAVM2Item(ins, xmlLines));
          return;
        }
      }
    }

    stack.push(new ConstructAVM2Item(ins, obj, args));
  }
예제 #8
0
 @Override
 public void translate(
     AVM2LocalData localData,
     TranslateStack stack,
     AVM2Instruction ins,
     List<GraphTargetItem> output,
     String path) {
   GraphTargetItem v2 = stack.pop();
   GraphTargetItem v1 = stack.pop();
   stack.push(new LtAVM2Item(ins, localData.lineStartInstruction, v1, v2));
 }
예제 #9
0
 @Override
 public void translate(
     AVM2LocalData localData,
     TranslateStack stack,
     AVM2Instruction ins,
     List<GraphTargetItem> output,
     String path) {
   GraphTargetItem ofs = stack.pop();
   GraphTargetItem value = stack.pop();
   output.add(new AlchemyStoreAVM2Item(ins, value, ofs, 'i', 8));
 }
 @Override
 public void translate(
     TranslateStack stack,
     List<GraphTargetItem> output,
     HashMap<Integer, String> regNames,
     HashMap<String, GraphTargetItem> variables,
     HashMap<String, GraphTargetItem> functions,
     int staticOperation,
     String path) {
   GraphTargetItem a = stack.pop();
   stack.push(new MBCharToAsciiActionItem(this, a));
 }
 @Override
 public void translate(
     TranslateStack stack,
     List<GraphTargetItem> output,
     HashMap<Integer, String> regNames,
     HashMap<String, GraphTargetItem> variables,
     HashMap<String, GraphTargetItem> functions,
     int staticOperation,
     String path) {
   GraphTargetItem value = stack.peek();
   stack.push(new DuplicateItem(this, value));
   value.getMoreSrc().add(new GraphSourceItemPos(this, 0));
 }
 @Override
 public void translate(
     GraphSourceItem lineStartAction,
     TranslateStack stack,
     List<GraphTargetItem> output,
     HashMap<Integer, String> regNames,
     HashMap<String, GraphTargetItem> variables,
     HashMap<String, GraphTargetItem> functions,
     int staticOperation,
     String path) {
   GraphTargetItem object = stack.pop();
   stack.push(new TargetPathActionItem(this, lineStartAction, object));
 }
 protected FullMultinameAVM2Item resolveMultiname(
     TranslateStack stack, AVM2ConstantPool constants, int multinameIndex, AVM2Instruction ins) {
   GraphTargetItem ns = null;
   GraphTargetItem name = null;
   if (multinameIndex > 0 && multinameIndex < constants.constant_multiname.size()) {
     if (constants.getMultiname(multinameIndex).needsName()) {
       name = stack.pop();
     }
     if (constants.getMultiname(multinameIndex).needsNs()) {
       ns = stack.pop();
     }
   }
   return new FullMultinameAVM2Item(ins, multinameIndex, name, ns);
 }
 @Override
 public void translateContainer(
     List<List<GraphTargetItem>> content,
     GraphSourceItem lineStartItem,
     TranslateStack stack,
     List<GraphTargetItem> output,
     HashMap<Integer, String> regNames,
     HashMap<String, GraphTargetItem> variables,
     HashMap<String, GraphTargetItem> functions) {
   List<FunctionActionItem> funcList = new ArrayList<>();
   for (String key : functions.keySet()) {
     GraphTargetItem val = functions.get(key);
     if (val instanceof FunctionActionItem) {
       funcList.add((FunctionActionItem) val);
     }
   }
   FunctionActionItem fti =
       new FunctionActionItem(
           this,
           lineStartItem,
           functionName,
           paramNames,
           getRegNames(),
           content.get(0),
           constantPool,
           getFirstRegister(),
           new ArrayList<>(),
           funcList);
   functions.put(functionName, fti);
   stack.push(fti);
 }
예제 #15
0
 @Override
 public void translate(
     AVM2LocalData localData,
     TranslateStack stack,
     AVM2Instruction ins,
     List<GraphTargetItem> output,
     String path) {
   int argCount = ins.operands[0];
   List<GraphTargetItem> args = new ArrayList<>();
   for (int a = 0; a < argCount; a++) {
     args.add(0, stack.pop());
   }
   GraphTargetItem receiver = stack.pop();
   GraphTargetItem function = stack.pop();
   stack.push(new CallAVM2Item(ins, localData.lineStartInstruction, receiver, function, args));
 }
 @Override
 public void translate(
     TranslateStack stack,
     List<GraphTargetItem> output,
     HashMap<Integer, String> regNames,
     HashMap<String, GraphTargetItem> variables,
     HashMap<String, GraphTargetItem> functions,
     int staticOperation,
     String path) {
   GraphTargetItem subclass = stack.pop();
   long inCount = popLong(stack);
   List<GraphTargetItem> superclasses = new ArrayList<>();
   for (long l = 0; l < inCount; l++) {
     superclasses.add(stack.pop());
   }
   output.add(new ImplementsOpActionItem(this, subclass, superclasses));
 }
 @Override
 public void translate(
     AVM2LocalData localData,
     TranslateStack stack,
     AVM2Instruction ins,
     List<GraphTargetItem> output,
     String path) {
   stack.push(new NewActivationAVM2Item(ins, localData.lineStartInstruction));
 }
예제 #18
0
 @Override
 public void translate(
     TranslateStack stack,
     List<GraphTargetItem> output,
     HashMap<Integer, String> regNames,
     HashMap<String, GraphTargetItem> variables,
     HashMap<String, GraphTargetItem> functions,
     int staticOperation,
     String path) {
   GraphTargetItem methodName = stack.pop();
   GraphTargetItem scriptObject = stack.pop();
   long numArgs = popLong(stack);
   List<GraphTargetItem> args = new ArrayList<>();
   for (long l = 0; l < numArgs; l++) {
     args.add(stack.pop());
   }
   stack.push(new NewMethodActionItem(this, scriptObject, methodName, args));
 }
예제 #19
0
 @Override
 public void translate(
     AVM2LocalData localData,
     TranslateStack stack,
     AVM2Instruction ins,
     List<GraphTargetItem> output,
     String path) {
   output.add(new ThrowAVM2Item(ins, localData.lineStartInstruction, stack.pop()));
 }
 @Override
 public void translate(
     AVM2LocalData localData,
     TranslateStack stack,
     AVM2Instruction ins,
     List<GraphTargetItem> output,
     String path) {
   stack.push(new UndefinedAVM2Item(ins));
 }
예제 #21
0
 @Override
 public void translateContainer(
     List<List<GraphTargetItem>> content,
     TranslateStack stack,
     List<GraphTargetItem> output,
     HashMap<Integer, String> regNames,
     HashMap<String, GraphTargetItem> variables,
     HashMap<String, GraphTargetItem> functions) {
   output.add(new WithActionItem(this, stack.pop(), content.get(0)));
 }
예제 #22
0
 @Override
 public void translate(
     AVM2LocalData localData,
     TranslateStack stack,
     AVM2Instruction ins,
     List<GraphTargetItem> output,
     String path) {
   int multinameIndex = ins.operands[0];
   Multiname multiname = localData.getConstants().getMultiname(multinameIndex);
   stack.push(new GetLexAVM2Item(ins, multiname));
 }
예제 #23
0
 @Override
 public void translate(
     AVM2LocalData localData,
     TranslateStack stack,
     AVM2Instruction ins,
     List<GraphTargetItem> output,
     String path) {
   GraphTargetItem top = stack.pop();
   if ((!(top instanceof MarkItem))) {
     output.add(top);
   }
 }
예제 #24
0
 @Override
 public void translate(
     GraphSourceItem lineStartAction,
     TranslateStack stack,
     List<GraphTargetItem> output,
     HashMap<Integer, String> regNames,
     HashMap<String, GraphTargetItem> variables,
     HashMap<String, GraphTargetItem> functions,
     int staticOperation,
     String path) {
   output.add(new CallActionItem(this, lineStartAction, stack.pop()));
 }
 @Override
 public void translate(
     TranslateStack stack,
     List<GraphTargetItem> output,
     HashMap<Integer, String> regNames,
     HashMap<String, GraphTargetItem> variables,
     HashMap<String, GraphTargetItem> functions,
     int staticOperation,
     String path) {
   GraphTargetItem object = stack.pop();
   output.add(new EnumerateActionItem(this, object));
 }
 @Override
 public void translateContainer(
     List<List<GraphTargetItem>> content,
     TranslateStack stack,
     List<GraphTargetItem> output,
     HashMap<Integer, String> regNames,
     HashMap<String, GraphTargetItem> variables,
     HashMap<String, GraphTargetItem> functions) {
   FunctionActionItem fti =
       new FunctionActionItem(
           this, functionName, paramNames, content.get(0), constantPool, 1, new ArrayList<>());
   // ActionGraph.translateViaGraph(regNames, variables, functions, code, version)
   stack.push(fti);
   functions.put(functionName, fti);
 }
 @Override
 public void translate(
     TranslateStack stack,
     List<GraphTargetItem> output,
     HashMap<Integer, String> regNames,
     HashMap<String, GraphTargetItem> variables,
     HashMap<String, GraphTargetItem> functions,
     int staticOperation,
     String path)
     throws InterruptedException {
   GraphTargetItem frame = stack.pop();
   List<GraphTargetItem> body =
       ActionGraph.translateViaGraph(
           regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path);
   output.add(new IfFrameLoadedActionItem(frame, body, this));
 }
예제 #28
0
 @Override
 public void translate(
     boolean isStatic,
     int scriptIndex,
     int classIndex,
     HashMap<Integer, GraphTargetItem> localRegs,
     TranslateStack stack,
     ScopeStack scopeStack,
     AVM2ConstantPool constants,
     AVM2Instruction ins,
     List<MethodInfo> method_info,
     List<GraphTargetItem> output,
     MethodBody body,
     ABC abc,
     HashMap<Integer, String> localRegNames,
     List<DottedChain> fullyQualifiedNames,
     String path,
     HashMap<Integer, Integer> localRegsAssignmentIps,
     int ip,
     HashMap<Integer, List<Integer>> refs,
     AVM2Code code) {
   stack.push(new IntegerValueAVM2Item(ins, constants.getUInt(ins.operands[0])));
 }
  private int visitCode(
      Reference<AVM2Instruction> assignment,
      Set<Integer> visited,
      TranslateStack stack,
      int classIndex,
      boolean isStatic,
      MethodBody body,
      int scriptIndex,
      ABC abc,
      AVM2Code code,
      int idx,
      int endIdx,
      Set<Integer> ignored,
      Set<Integer> ignoredGets)
      throws InterruptedException {
    List<GraphTargetItem> output = new ArrayList<>();
    AVM2LocalData localData =
        newLocalData(scriptIndex, abc, abc.constants, body, isStatic, classIndex);
    initLocalRegs(localData, body.getLocalReservedCount(), body.max_regs);
    localData.localRegs.put(0, new NullAVM2Item(null, null)); // this

    List<Integer> toVisit = new ArrayList<>();
    toVisit.add(idx);
    List<TranslateStack> toVisitStacks = new ArrayList<>();
    toVisitStacks.add(stack);
    outer:
    while (!toVisit.isEmpty()) {
      if (Thread.currentThread().isInterrupted()) {
        throw new InterruptedException();
      }

      idx = toVisit.remove(0);
      stack = toVisitStacks.remove(0);

      while (true) {
        if (idx > endIdx) {
          break;
        }
        if (visited.contains(idx)) {
          break;
        }
        visited.add(idx);

        AVM2Instruction ins = code.code.get(idx);
        InstructionDefinition def = ins.definition;
        // System.err.println("" + idx + ": " + ins + " stack:" + stack.size());

        // do not throw EmptyStackException, much faster
        int requiredStackSize = ins.getStackPopCount(localData);
        if (stack.size() < requiredStackSize) {
          continue outer;
        }

        ins.translate(localData, stack, output, Graph.SOP_USE_STATIC, "");
        if (def instanceof SetLocalTypeIns) {
          int regId = ((SetLocalTypeIns) def).getRegisterId(ins);
          if (!ignored.contains(regId)) {
            assignment.setVal(ins);
            return regId;
          }
        } else if (def instanceof GetLocalTypeIns) {
          int regId = ((GetLocalTypeIns) def).getRegisterId(ins);
          if (!ignored.contains(regId) && !ignoredGets.contains(regId)) {
            assignment.setVal(ins);
            return regId;
          }
        } else if (!(def instanceof KillIns) && !(def instanceof DebugIns)) {
          // can be inclocal, declocal, hasnext...
          for (int p = 0; p < ins.definition.operands.length; p++) {
            int op = ins.definition.operands[p];
            if (op == AVM2Code.DAT_LOCAL_REG_INDEX) {
              int regId = ins.operands[p];
              if (!ignored.contains(regId)) {
                assignment.setVal(ins);
                return regId;
              }
            }
          }
        }

        idx++;

        if (ins.definition instanceof JumpIns) {

          long address = ins.offset + ins.getBytesLength() + ins.operands[0];
          idx = code.adr2pos(address); // code.indexOf(code.getByAddress(address));
          if (idx == -1) {
            throw new TranslateException("Jump target not found: " + address);
          }
        }

        if (ins.isBranch()) {
          List<Integer> branches =
              ins.getBranches(
                  new GraphSource() {

                    @Override
                    public int size() {
                      throw new UnsupportedOperationException(
                          "Not supported yet."); // To change body of generated methods, choose
                      // Tools | Templates.
                    }

                    @Override
                    public GraphSourceItem get(int pos) {
                      throw new UnsupportedOperationException(
                          "Not supported yet."); // To change body of generated methods, choose
                      // Tools | Templates.
                    }

                    @Override
                    public boolean isEmpty() {
                      throw new UnsupportedOperationException(
                          "Not supported yet."); // To change body of generated methods, choose
                      // Tools | Templates.
                    }

                    @Override
                    public List<GraphTargetItem> translatePart(
                        GraphPart part,
                        BaseLocalData localData,
                        TranslateStack stack,
                        int start,
                        int end,
                        int staticOperation,
                        String path)
                        throws InterruptedException {
                      throw new UnsupportedOperationException(
                          "Not supported yet."); // To change body of generated methods, choose
                      // Tools | Templates.
                    }

                    @Override
                    public int adr2pos(long adr) {
                      return code.adr2pos(adr);
                    }

                    @Override
                    public long pos2adr(int pos) {
                      return code.pos2adr(pos);
                    }
                  });
          idx = branches.get(0);
          for (int n = 1; n < branches.size(); n++) {
            // visitCode(visited, (TranslateStack) stack.clone(), classIndex, isStatic, body,
            // scriptIndex, abc, code, branches.get(n), endIdx, result);
            int nidx = branches.get(n);
            if (visited.contains(nidx)) {
              continue;
            }
            toVisit.add(nidx);
            toVisitStacks.add((TranslateStack) stack.clone());
          }
        }
        /*if (ins.definition instanceof IfTypeIns) {
        long address = ins.offset + ins.getBytes().length + ins.operands[0];
        int newIdx = code.adr2pos(address);
        if (newIdx == -1) {
        throw new TranslateException("If target not found: " + address);
        }
        visitCode(visited, (TranslateStack) stack.clone(), classIndex, isStatic, body, scriptIndex, abc, code, newIdx, endIdx, result);
        }*/

        if (ins.definition instanceof ReturnValueIns) {
          break;
        }

        if (ins.definition instanceof ThrowIns) {
          break;
        }

        if (ins.definition instanceof ReturnVoidIns) {
          break;
        }
      }
    }
    return -1;
  }
예제 #30
0
  @Override
  public void translate(
      boolean isStatic,
      int scriptIndex,
      int classIndex,
      HashMap<Integer, GraphTargetItem> localRegs,
      TranslateStack stack,
      ScopeStack scopeStack,
      AVM2ConstantPool constants,
      AVM2Instruction ins,
      List<MethodInfo> method_info,
      List<GraphTargetItem> output,
      MethodBody body,
      ABC abc,
      HashMap<Integer, String> localRegNames,
      List<DottedChain> fullyQualifiedNames,
      String path,
      HashMap<Integer, Integer> localRegsAssignmentIps,
      int ip,
      HashMap<Integer, List<Integer>> refs,
      AVM2Code code) {
    int slotIndex = ins.operands[0];
    GraphTargetItem value = stack.pop();
    GraphTargetItem obj = stack.pop(); // scopeId
    GraphTargetItem objnoreg = obj;
    obj = obj.getThroughRegister();
    Multiname slotname = null;
    if (obj instanceof NewActivationAVM2Item) {
      ((NewActivationAVM2Item) obj).slots.put(slotIndex, value);
    }

    if (obj instanceof ExceptionAVM2Item) {
      slotname = constants.getMultiname(((ExceptionAVM2Item) obj).exception.name_index);
    } else if (obj instanceof ClassAVM2Item) {
      slotname = ((ClassAVM2Item) obj).className;
    } else if (obj instanceof ThisAVM2Item) {
      slotname = ((ThisAVM2Item) obj).className;
    } else if (obj instanceof ScriptAVM2Item) {
      for (int t = 0;
          t < abc.script_info.get(((ScriptAVM2Item) obj).scriptIndex).traits.traits.size();
          t++) {
        Trait tr = abc.script_info.get(((ScriptAVM2Item) obj).scriptIndex).traits.traits.get(t);
        if (tr instanceof TraitWithSlot) {
          if (((TraitWithSlot) tr).getSlotIndex() == slotIndex) {
            slotname = tr.getName(abc);
          }
        }
      }
    } else if (obj instanceof NewActivationAVM2Item) {

      for (int t = 0; t < body.traits.traits.size(); t++) {
        if (body.traits.traits.get(t) instanceof TraitWithSlot) {
          if (((TraitWithSlot) body.traits.traits.get(t)).getSlotIndex() == slotIndex) {
            slotname = body.traits.traits.get(t).getName(abc);
          }
        }
      }
    }

    if (slotname != null) {
      if (value instanceof LocalRegAVM2Item) {
        LocalRegAVM2Item lr = (LocalRegAVM2Item) value;
        String slotNameStr = slotname.getName(constants, fullyQualifiedNames, true);
        if (localRegNames.containsKey(lr.regIndex)) {
          if (localRegNames.get(lr.regIndex).equals(slotNameStr)) {
            return; // Register with same name to slot
          }
        }
      }
    }

    if (value.getNotCoerced().getThroughDuplicate() instanceof IncrementAVM2Item) {
      GraphTargetItem inside =
          ((IncrementAVM2Item) value.getNotCoerced())
              .value
              .getThroughRegister()
              .getNotCoerced()
              .getThroughDuplicate();
      if (inside instanceof GetSlotAVM2Item) {
        GetSlotAVM2Item slotItem = (GetSlotAVM2Item) inside;
        if ((slotItem.scope.getThroughRegister() == obj.getThroughRegister())
            && (slotItem.slotName == slotname)) {
          if (stack.size() > 0) {
            GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate();
            if (top == inside) {
              stack.pop();
              stack.push(new PostIncrementAVM2Item(ins, inside));
            } else if ((top instanceof IncrementAVM2Item)
                && (((IncrementAVM2Item) top).value == inside)) {
              stack.pop();
              stack.push(new PreIncrementAVM2Item(ins, inside));
            } else {
              output.add(new PostIncrementAVM2Item(ins, inside));
            }
          } else {
            output.add(new PostIncrementAVM2Item(ins, inside));
          }
          return;
        }
      }
    }

    if (value.getNotCoerced().getThroughDuplicate() instanceof DecrementAVM2Item) {
      GraphTargetItem inside =
          ((DecrementAVM2Item) value.getNotCoerced())
              .value
              .getThroughRegister()
              .getNotCoerced()
              .getThroughDuplicate();
      if (inside instanceof GetSlotAVM2Item) {
        GetSlotAVM2Item slotItem = (GetSlotAVM2Item) inside;
        if ((slotItem.scope.getThroughRegister() == obj.getThroughRegister())
            && (slotItem.slotName == slotname)) {
          if (stack.size() > 0) {
            GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate();
            if (top == inside) {
              stack.pop();
              stack.push(new PostDecrementAVM2Item(ins, inside));
            } else if ((top instanceof DecrementAVM2Item)
                && (((DecrementAVM2Item) top).value == inside)) {
              stack.pop();
              stack.push(new PreDecrementAVM2Item(ins, inside));
            } else {
              output.add(new PostDecrementAVM2Item(ins, inside));
            }
          } else {
            output.add(new PostDecrementAVM2Item(ins, inside));
          }
          return;
        }
      }
    }

    output.add(new SetSlotAVM2Item(ins, obj, slotname, value));
  }