Java Code Examples for com.android.dx.rop.code.SourcePosition#NO_INFO
The following examples show how to use
com.android.dx.rop.code.SourcePosition#NO_INFO .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SsaMethod.java From buck with Apache License 2.0 | 5 votes |
/** * Deletes all insns in the set from this method. * * @param deletedInsns {@code non-null;} insns to delete */ public void deleteInsns(Set<SsaInsn> deletedInsns) { for (SsaBasicBlock block : getBlocks()) { ArrayList<SsaInsn> insns = block.getInsns(); for (int i = insns.size() - 1; i >= 0; i--) { SsaInsn insn = insns.get(i); if (deletedInsns.contains(insn)) { onInsnRemoved(insn); insns.remove(i); } } // Check to see if we need to add a GOTO int insnsSz = insns.size(); SsaInsn lastInsn = (insnsSz == 0) ? null : insns.get(insnsSz - 1); if (block != getExitBlock() && (insnsSz == 0 || lastInsn.getOriginalRopInsn() == null || lastInsn.getOriginalRopInsn().getOpcode() .getBranchingness() == Rop.BRANCH_NONE)) { // We managed to eat a throwable insn Insn gotoInsn = new PlainInsn(Rops.GOTO, SourcePosition.NO_INFO, null, RegisterSpecList.EMPTY); insns.add(SsaInsn.makeFromRop(gotoInsn, block)); // Remove secondary successors from this block BitSet succs = block.getSuccessors(); for (int i = succs.nextSetBit(0); i >= 0; i = succs.nextSetBit(i + 1)) { if (i != block.getPrimarySuccessorIndex()) { block.removeSuccessor(i); } } } } }
Example 2
Source File: SsaBasicBlock.java From Box with Apache License 2.0 | 5 votes |
/** * Adds a move instruction after the phi insn block. * * @param result move destination * @param source move source */ public void addMoveToBeginning (RegisterSpec result, RegisterSpec source) { if (result.getReg() == source.getReg()) { // Sometimes we end up with no-op moves. Ignore them here. return; } RegisterSpecList sources = RegisterSpecList.make(source); NormalSsaInsn toAdd = new NormalSsaInsn( new PlainInsn(Rops.opMove(result.getType()), SourcePosition.NO_INFO, result, sources), this); insns.add(getCountPhiInsns(), toAdd); movesFromPhisAtBeginning++; }
Example 3
Source File: SsaBasicBlock.java From buck with Apache License 2.0 | 5 votes |
/** * Adds a move instruction after the phi insn block. * * @param result move destination * @param source move source */ public void addMoveToBeginning (RegisterSpec result, RegisterSpec source) { if (result.getReg() == source.getReg()) { // Sometimes we end up with no-op moves. Ignore them here. return; } RegisterSpecList sources = RegisterSpecList.make(source); NormalSsaInsn toAdd = new NormalSsaInsn( new PlainInsn(Rops.opMove(result.getType()), SourcePosition.NO_INFO, result, sources), this); insns.add(getCountPhiInsns(), toAdd); movesFromPhisAtBeginning++; }
Example 4
Source File: SsaMethod.java From J2ME-Loader with Apache License 2.0 | 5 votes |
/** * Deletes all insns in the set from this method. * * @param deletedInsns {@code non-null;} insns to delete */ public void deleteInsns(Set<SsaInsn> deletedInsns) { for (SsaBasicBlock block : getBlocks()) { ArrayList<SsaInsn> insns = block.getInsns(); for (int i = insns.size() - 1; i >= 0; i--) { SsaInsn insn = insns.get(i); if (deletedInsns.contains(insn)) { onInsnRemoved(insn); insns.remove(i); } } // Check to see if we need to add a GOTO int insnsSz = insns.size(); SsaInsn lastInsn = (insnsSz == 0) ? null : insns.get(insnsSz - 1); if (block != getExitBlock() && (insnsSz == 0 || lastInsn.getOriginalRopInsn() == null || lastInsn.getOriginalRopInsn().getOpcode() .getBranchingness() == Rop.BRANCH_NONE)) { // We managed to eat a throwable insn Insn gotoInsn = new PlainInsn(Rops.GOTO, SourcePosition.NO_INFO, null, RegisterSpecList.EMPTY); insns.add(SsaInsn.makeFromRop(gotoInsn, block)); // Remove secondary successors from this block BitSet succs = block.getSuccessors(); for (int i = succs.nextSetBit(0); i >= 0; i = succs.nextSetBit(i + 1)) { if (i != block.getPrimarySuccessorIndex()) { block.removeSuccessor(i); } } } } }
Example 5
Source File: SsaBasicBlock.java From J2ME-Loader with Apache License 2.0 | 5 votes |
/** * Adds a move instruction after the phi insn block. * * @param result move destination * @param source move source */ public void addMoveToBeginning (RegisterSpec result, RegisterSpec source) { if (result.getReg() == source.getReg()) { // Sometimes we end up with no-op moves. Ignore them here. return; } RegisterSpecList sources = RegisterSpecList.make(source); NormalSsaInsn toAdd = new NormalSsaInsn( new PlainInsn(Rops.opMove(result.getType()), SourcePosition.NO_INFO, result, sources), this); insns.add(getCountPhiInsns(), toAdd); movesFromPhisAtBeginning++; }
Example 6
Source File: SsaBasicBlock.java From Box with Apache License 2.0 | 5 votes |
/** * Adds a move instruction after the phi insn block. * * @param result move destination * @param source move source */ public void addMoveToBeginning (RegisterSpec result, RegisterSpec source) { if (result.getReg() == source.getReg()) { // Sometimes we end up with no-op moves. Ignore them here. return; } RegisterSpecList sources = RegisterSpecList.make(source); NormalSsaInsn toAdd = new NormalSsaInsn( new PlainInsn(Rops.opMove(result.getType()), SourcePosition.NO_INFO, result, sources), this); insns.add(getCountPhiInsns(), toAdd); movesFromPhisAtBeginning++; }
Example 7
Source File: ConstCollector.java From Box with Apache License 2.0 | 4 votes |
/** * Applies the optimization. */ private void run() { int regSz = ssaMeth.getRegCount(); ArrayList<TypedConstant> constantList = getConstsSortedByCountUse(); int toCollect = Math.min(constantList.size(), MAX_COLLECTED_CONSTANTS); SsaBasicBlock start = ssaMeth.getEntryBlock(); // Constant to new register containing the constant HashMap<TypedConstant, RegisterSpec> newRegs = new HashMap<TypedConstant, RegisterSpec> (toCollect); for (int i = 0; i < toCollect; i++) { TypedConstant cst = constantList.get(i); RegisterSpec result = RegisterSpec.make(ssaMeth.makeNewSsaReg(), cst); Rop constRop = Rops.opConst(cst); if (constRop.getBranchingness() == Rop.BRANCH_NONE) { start.addInsnToHead( new PlainCstInsn(Rops.opConst(cst), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY, cst)); } else { // We need two new basic blocks along with the new insn SsaBasicBlock entryBlock = ssaMeth.getEntryBlock(); SsaBasicBlock successorBlock = entryBlock.getPrimarySuccessor(); // Insert a block containing the const insn. SsaBasicBlock constBlock = entryBlock.insertNewSuccessor(successorBlock); constBlock.replaceLastInsn( new ThrowingCstInsn(constRop, SourcePosition.NO_INFO, RegisterSpecList.EMPTY, StdTypeList.EMPTY, cst)); // Insert a block containing the move-result-pseudo insn. SsaBasicBlock resultBlock = constBlock.insertNewSuccessor(successorBlock); PlainInsn insn = new PlainInsn( Rops.opMoveResultPseudo(result.getTypeBearer()), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY); resultBlock.addInsnToHead(insn); } newRegs.put(cst, result); } updateConstUses(newRegs, regSz); }
Example 8
Source File: ConstCollector.java From buck with Apache License 2.0 | 4 votes |
/** * Applies the optimization. */ private void run() { int regSz = ssaMeth.getRegCount(); ArrayList<TypedConstant> constantList = getConstsSortedByCountUse(); int toCollect = Math.min(constantList.size(), MAX_COLLECTED_CONSTANTS); SsaBasicBlock start = ssaMeth.getEntryBlock(); // Constant to new register containing the constant HashMap<TypedConstant, RegisterSpec> newRegs = new HashMap<TypedConstant, RegisterSpec> (toCollect); for (int i = 0; i < toCollect; i++) { TypedConstant cst = constantList.get(i); RegisterSpec result = RegisterSpec.make(ssaMeth.makeNewSsaReg(), cst); Rop constRop = Rops.opConst(cst); if (constRop.getBranchingness() == Rop.BRANCH_NONE) { start.addInsnToHead( new PlainCstInsn(Rops.opConst(cst), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY, cst)); } else { // We need two new basic blocks along with the new insn SsaBasicBlock entryBlock = ssaMeth.getEntryBlock(); SsaBasicBlock successorBlock = entryBlock.getPrimarySuccessor(); // Insert a block containing the const insn. SsaBasicBlock constBlock = entryBlock.insertNewSuccessor(successorBlock); constBlock.replaceLastInsn( new ThrowingCstInsn(constRop, SourcePosition.NO_INFO, RegisterSpecList.EMPTY, StdTypeList.EMPTY, cst)); // Insert a block containing the move-result-pseudo insn. SsaBasicBlock resultBlock = constBlock.insertNewSuccessor(successorBlock); PlainInsn insn = new PlainInsn( Rops.opMoveResultPseudo(result.getTypeBearer()), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY); resultBlock.addInsnToHead(insn); } newRegs.put(cst, result); } updateConstUses(newRegs, regSz); }
Example 9
Source File: PositionList.java From buck with Apache License 2.0 | 4 votes |
/** * Extracts and returns the source position information out of an * instruction list. * * @param insns {@code non-null;} instructions to convert * @param howMuch how much information should be included; one of the * static constants defined by this class * @return {@code non-null;} the positions list */ public static PositionList make(DalvInsnList insns, int howMuch) { switch (howMuch) { case NONE: { return EMPTY; } case LINES: case IMPORTANT: { // Valid. break; } default: { throw new IllegalArgumentException("bogus howMuch"); } } SourcePosition noInfo = SourcePosition.NO_INFO; SourcePosition cur = noInfo; int sz = insns.size(); PositionList.Entry[] arr = new PositionList.Entry[sz]; boolean lastWasTarget = false; int at = 0; for (int i = 0; i < sz; i++) { DalvInsn insn = insns.get(i); if (insn instanceof CodeAddress) { lastWasTarget = true;; continue; } SourcePosition pos = insn.getPosition(); if (pos.equals(noInfo) || pos.sameLine(cur)) { continue; } if ((howMuch == IMPORTANT) && !lastWasTarget) { continue; } cur = pos; arr[at] = new PositionList.Entry(insn.getAddress(), pos); at++; lastWasTarget = false; } PositionList result = new PositionList(at); for (int i = 0; i < at; i++) { result.set(i, arr[i]); } result.setImmutable(); return result; }
Example 10
Source File: SsaBasicBlock.java From J2ME-Loader with Apache License 2.0 | 4 votes |
/** * Adds a move instruction to the end of this basic block, just * before the last instruction. If the result of the final instruction * is the source in question, then the move is placed at the beginning of * the primary successor block. This is for unversioned registers. * * @param result move destination * @param source move source */ public void addMoveToEnd(RegisterSpec result, RegisterSpec source) { if (result.getReg() == source.getReg()) { // Sometimes we end up with no-op moves. Ignore them here. return; } /* * The last Insn has to be a normal SSA insn: a phi can't branch * or return or cause an exception, etc. */ NormalSsaInsn lastInsn; lastInsn = (NormalSsaInsn)insns.get(insns.size()-1); if (lastInsn.getResult() != null || lastInsn.getSources().size() > 0) { /* * The final insn in this block has a source or result * register, and the moves we may need to place and * schedule may interfere. We need to insert this * instruction at the beginning of the primary successor * block instead. We know this is safe, because when we * edge-split earlier, we ensured that each successor has * only us as a predecessor. */ for (int i = successors.nextSetBit(0) ; i >= 0 ; i = successors.nextSetBit(i + 1)) { SsaBasicBlock succ; succ = parent.getBlocks().get(i); succ.addMoveToBeginning(result, source); } } else { /* * We can safely add a move to the end of the block just * before the last instruction, because the final insn does * not assign to anything. */ RegisterSpecList sources = RegisterSpecList.make(source); NormalSsaInsn toAdd = new NormalSsaInsn( new PlainInsn(Rops.opMove(result.getType()), SourcePosition.NO_INFO, result, sources), this); insns.add(insns.size() - 1, toAdd); movesFromPhisAtEnd++; } }
Example 11
Source File: ConstCollector.java From J2ME-Loader with Apache License 2.0 | 4 votes |
/** * Applies the optimization. */ private void run() { int regSz = ssaMeth.getRegCount(); ArrayList<TypedConstant> constantList = getConstsSortedByCountUse(); int toCollect = Math.min(constantList.size(), MAX_COLLECTED_CONSTANTS); SsaBasicBlock start = ssaMeth.getEntryBlock(); // Constant to new register containing the constant HashMap<TypedConstant, RegisterSpec> newRegs = new HashMap<TypedConstant, RegisterSpec> (toCollect); for (int i = 0; i < toCollect; i++) { TypedConstant cst = constantList.get(i); RegisterSpec result = RegisterSpec.make(ssaMeth.makeNewSsaReg(), cst); Rop constRop = Rops.opConst(cst); if (constRop.getBranchingness() == Rop.BRANCH_NONE) { start.addInsnToHead( new PlainCstInsn(Rops.opConst(cst), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY, cst)); } else { // We need two new basic blocks along with the new insn SsaBasicBlock entryBlock = ssaMeth.getEntryBlock(); SsaBasicBlock successorBlock = entryBlock.getPrimarySuccessor(); // Insert a block containing the const insn. SsaBasicBlock constBlock = entryBlock.insertNewSuccessor(successorBlock); constBlock.replaceLastInsn( new ThrowingCstInsn(constRop, SourcePosition.NO_INFO, RegisterSpecList.EMPTY, StdTypeList.EMPTY, cst)); // Insert a block containing the move-result-pseudo insn. SsaBasicBlock resultBlock = constBlock.insertNewSuccessor(successorBlock); PlainInsn insn = new PlainInsn( Rops.opMoveResultPseudo(result.getTypeBearer()), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY); resultBlock.addInsnToHead(insn); } newRegs.put(cst, result); } updateConstUses(newRegs, regSz); }
Example 12
Source File: PositionList.java From J2ME-Loader with Apache License 2.0 | 4 votes |
/** * Extracts and returns the source position information out of an * instruction list. * * @param insns {@code non-null;} instructions to convert * @param howMuch how much information should be included; one of the * static constants defined by this class * @return {@code non-null;} the positions list */ public static PositionList make(DalvInsnList insns, int howMuch) { switch (howMuch) { case NONE: { return EMPTY; } case LINES: case IMPORTANT: { // Valid. break; } default: { throw new IllegalArgumentException("bogus howMuch"); } } SourcePosition noInfo = SourcePosition.NO_INFO; SourcePosition cur = noInfo; int sz = insns.size(); PositionList.Entry[] arr = new PositionList.Entry[sz]; boolean lastWasTarget = false; int at = 0; for (int i = 0; i < sz; i++) { DalvInsn insn = insns.get(i); if (insn instanceof CodeAddress) { lastWasTarget = true;; continue; } SourcePosition pos = insn.getPosition(); if (pos.equals(noInfo) || pos.sameLine(cur)) { continue; } if ((howMuch == IMPORTANT) && !lastWasTarget) { continue; } cur = pos; arr[at] = new PositionList.Entry(insn.getAddress(), pos); at++; lastWasTarget = false; } PositionList result = new PositionList(at); for (int i = 0; i < at; i++) { result.set(i, arr[i]); } result.setImmutable(); return result; }
Example 13
Source File: SsaMethod.java From Box with Apache License 2.0 | 4 votes |
/** * Deletes all insns in the set from this method. * * @param deletedInsns {@code non-null;} insns to delete */ public void deleteInsns(Set<SsaInsn> deletedInsns) { for (SsaInsn deletedInsn : deletedInsns) { SsaBasicBlock block = deletedInsn.getBlock(); ArrayList<SsaInsn> insns = block.getInsns(); for (int i = insns.size() - 1; i >= 0; i--) { SsaInsn insn = insns.get(i); if (deletedInsn == insn) { onInsnRemoved(insn); insns.remove(i); break; } } // Check to see if we need to add a GOTO int insnsSz = insns.size(); SsaInsn lastInsn = (insnsSz == 0) ? null : insns.get(insnsSz - 1); if (block != getExitBlock() && (insnsSz == 0 || lastInsn.getOriginalRopInsn() == null || lastInsn.getOriginalRopInsn().getOpcode() .getBranchingness() == Rop.BRANCH_NONE)) { // We managed to eat a throwable insn Insn gotoInsn = new PlainInsn(Rops.GOTO, SourcePosition.NO_INFO, null, RegisterSpecList.EMPTY); insns.add(SsaInsn.makeFromRop(gotoInsn, block)); // Remove secondary successors from this block BitSet succs = block.getSuccessors(); for (int i = succs.nextSetBit(0); i >= 0; i = succs.nextSetBit(i + 1)) { if (i != block.getPrimarySuccessorIndex()) { block.removeSuccessor(i); } } } } }
Example 14
Source File: SsaBasicBlock.java From Box with Apache License 2.0 | 4 votes |
/** * Adds a move instruction to the end of this basic block, just * before the last instruction. If the result of the final instruction * is the source in question, then the move is placed at the beginning of * the primary successor block. This is for unversioned registers. * * @param result move destination * @param source move source */ public void addMoveToEnd(RegisterSpec result, RegisterSpec source) { /* * Check that there are no other successors otherwise we may * insert a move that affects those (b/69128828). */ if (successors.cardinality() > 1) { throw new IllegalStateException("Inserting a move to a block with multiple successors"); } if (result.getReg() == source.getReg()) { // Sometimes we end up with no-op moves. Ignore them here. return; } /* * The last Insn has to be a normal SSA insn: a phi can't branch * or return or cause an exception, etc. */ NormalSsaInsn lastInsn; lastInsn = (NormalSsaInsn)insns.get(insns.size()-1); if (lastInsn.getResult() != null || lastInsn.getSources().size() > 0) { /* * The final insn in this block has a source or result * register, and the moves we may need to place and * schedule may interfere. We need to insert this * instruction at the beginning of the primary successor * block instead. We know this is safe, because when we * edge-split earlier, we ensured that each successor has * only us as a predecessor. */ for (int i = successors.nextSetBit(0) ; i >= 0 ; i = successors.nextSetBit(i + 1)) { SsaBasicBlock succ; succ = parent.getBlocks().get(i); succ.addMoveToBeginning(result, source); } } else { /* * We can safely add a move to the end of the block just * before the last instruction, because the final insn does * not assign to anything. */ RegisterSpecList sources = RegisterSpecList.make(source); NormalSsaInsn toAdd = new NormalSsaInsn( new PlainInsn(Rops.opMove(result.getType()), SourcePosition.NO_INFO, result, sources), this); insns.add(insns.size() - 1, toAdd); movesFromPhisAtEnd++; } }
Example 15
Source File: ConstCollector.java From Box with Apache License 2.0 | 4 votes |
/** * Applies the optimization. */ private void run() { int regSz = ssaMeth.getRegCount(); ArrayList<TypedConstant> constantList = getConstsSortedByCountUse(); int toCollect = Math.min(constantList.size(), MAX_COLLECTED_CONSTANTS); SsaBasicBlock start = ssaMeth.getEntryBlock(); // Constant to new register containing the constant HashMap<TypedConstant, RegisterSpec> newRegs = new HashMap<TypedConstant, RegisterSpec> (toCollect); for (int i = 0; i < toCollect; i++) { TypedConstant cst = constantList.get(i); RegisterSpec result = RegisterSpec.make(ssaMeth.makeNewSsaReg(), cst); Rop constRop = Rops.opConst(cst); if (constRop.getBranchingness() == Rop.BRANCH_NONE) { start.addInsnToHead( new PlainCstInsn(Rops.opConst(cst), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY, cst)); } else { // We need two new basic blocks along with the new insn SsaBasicBlock entryBlock = ssaMeth.getEntryBlock(); SsaBasicBlock successorBlock = entryBlock.getPrimarySuccessor(); // Insert a block containing the const insn. SsaBasicBlock constBlock = entryBlock.insertNewSuccessor(successorBlock); constBlock.replaceLastInsn( new ThrowingCstInsn(constRop, SourcePosition.NO_INFO, RegisterSpecList.EMPTY, StdTypeList.EMPTY, cst)); // Insert a block containing the move-result-pseudo insn. SsaBasicBlock resultBlock = constBlock.insertNewSuccessor(successorBlock); PlainInsn insn = new PlainInsn( Rops.opMoveResultPseudo(result.getTypeBearer()), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY); resultBlock.addInsnToHead(insn); } newRegs.put(cst, result); } updateConstUses(newRegs, regSz); }
Example 16
Source File: PositionList.java From Box with Apache License 2.0 | 4 votes |
/** * Extracts and returns the source position information out of an * instruction list. * * @param insns {@code non-null;} instructions to convert * @param howMuch how much information should be included; one of the * static constants defined by this class * @return {@code non-null;} the positions list */ public static PositionList make(DalvInsnList insns, int howMuch) { switch (howMuch) { case NONE: { return EMPTY; } case LINES: case IMPORTANT: { // Valid. break; } default: { throw new IllegalArgumentException("bogus howMuch"); } } SourcePosition noInfo = SourcePosition.NO_INFO; SourcePosition cur = noInfo; int sz = insns.size(); Entry[] arr = new Entry[sz]; boolean lastWasTarget = false; int at = 0; for (int i = 0; i < sz; i++) { DalvInsn insn = insns.get(i); if (insn instanceof CodeAddress) { lastWasTarget = true;; continue; } SourcePosition pos = insn.getPosition(); if (pos.equals(noInfo) || pos.sameLine(cur)) { continue; } if ((howMuch == IMPORTANT) && !lastWasTarget) { continue; } cur = pos; arr[at] = new Entry(insn.getAddress(), pos); at++; lastWasTarget = false; } PositionList result = new PositionList(at); for (int i = 0; i < at; i++) { result.set(i, arr[i]); } result.setImmutable(); return result; }
Example 17
Source File: SsaMethod.java From Box with Apache License 2.0 | 2 votes |
/** * Gets a new {@code GOTO} insn. * * @param block block to which this GOTO will be added * (not it's destination!) * @return an appropriately-constructed instance. */ private static SsaInsn getGoto(SsaBasicBlock block) { return new NormalSsaInsn ( new PlainInsn(Rops.GOTO, SourcePosition.NO_INFO, null, RegisterSpecList.EMPTY), block); }
Example 18
Source File: SsaMethod.java From J2ME-Loader with Apache License 2.0 | 2 votes |
/** * Gets a new {@code GOTO} insn. * * @param block block to which this GOTO will be added * (not it's destination!) * @return an appropriately-constructed instance. */ private static SsaInsn getGoto(SsaBasicBlock block) { return new NormalSsaInsn ( new PlainInsn(Rops.GOTO, SourcePosition.NO_INFO, null, RegisterSpecList.EMPTY), block); }
Example 19
Source File: SsaMethod.java From Box with Apache License 2.0 | 2 votes |
/** * Gets a new {@code GOTO} insn. * * @param block block to which this GOTO will be added * (not it's destination!) * @return an appropriately-constructed instance. */ private static SsaInsn getGoto(SsaBasicBlock block) { return new NormalSsaInsn ( new PlainInsn(Rops.GOTO, SourcePosition.NO_INFO, null, RegisterSpecList.EMPTY), block); }
Example 20
Source File: SsaMethod.java From buck with Apache License 2.0 | 2 votes |
/** * Gets a new {@code GOTO} insn. * * @param block block to which this GOTO will be added * (not it's destination!) * @return an appropriately-constructed instance. */ private static SsaInsn getGoto(SsaBasicBlock block) { return new NormalSsaInsn ( new PlainInsn(Rops.GOTO, SourcePosition.NO_INFO, null, RegisterSpecList.EMPTY), block); }