1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/* 2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Copyright (C) 2007 The Android Open Source Project 3579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 4579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * you may not use this file except in compliance with the License. 6579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * You may obtain a copy of the License at 7579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 8579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 10579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * See the License for the specific language governing permissions and 14579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * limitations under the License. 15579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 16579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 17579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpackage com.android.dx.ssa; 18579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 19579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.code.*; 20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/** 22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * A "normal" (non-phi) instruction in SSA form. Always wraps a rop insn. 23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic final class NormalSsaInsn extends SsaInsn implements Cloneable { 25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} rop insn that we're wrapping */ 26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private Insn insn; 27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Creates an instance. 30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param insn Rop insn to wrap 32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param block block that contains this insn 33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson NormalSsaInsn(final Insn insn, final SsaBasicBlock block) { 35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson super(insn.getResult(), block); 36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.insn = insn; 37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public final void mapSourceRegisters(RegisterMapper mapper) { 42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList oldSources = insn.getSources(); 43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList newSources = mapper.map(oldSources); 44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (newSources != oldSources) { 46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson insn = insn.withNewRegisters(getResult(), newSources); 47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson getBlock().getParent().onSourcesChanged(this, oldSources); 48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Changes one of the insn's sources. New source should be of same type 53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * and category. 54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param index {@code >=0;} index of source to change 56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param newSpec spec for new source 57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public final void changeOneSource(int index, RegisterSpec newSpec) { 59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList origSources = insn.getSources(); 60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int sz = origSources.size(); 61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList newSources = new RegisterSpecList(sz); 62579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 63579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < sz; i++) { 64579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson newSources.set(i, i == index ? newSpec : origSources.get(i)); 65579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 66579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 67579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson newSources.setImmutable(); 68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpec origSpec = origSources.get(index); 70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (origSpec.getReg() != newSpec.getReg()) { 71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /* 72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * If the register remains unchanged, we're only changing 73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * the type or local var name so don't update use list 74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 75579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson getBlock().getParent().onSourceChanged(this, origSpec, newSpec); 76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson insn = insn.withNewRegisters(getResult(), newSources); 79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Changes the source list of the insn. New source list should be the 83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * same size and consist of sources of identical types. 84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param newSources non-null new sources list. 86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public final void setNewSources (RegisterSpecList newSources) { 88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList origSources = insn.getSources(); 89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (origSources.size() != newSources.size()) { 91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new RuntimeException("Sources counts don't match"); 92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson insn = insn.withNewRegisters(getResult(), newSources); 95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public NormalSsaInsn clone() { 100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return (NormalSsaInsn) super.clone(); 101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Like rop.Insn.getSources(). 105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code null-ok;} sources list 107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public RegisterSpecList getSources() { 110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return insn.getSources(); 111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String toHuman() { 115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return toRopInsn().toHuman(); 116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Insn toRopInsn() { 121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return insn.withNewRegisters(getResult(), insn.getSources()); 122579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return the Rop opcode for this insn 126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Rop getOpcode() { 129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return insn.getOpcode(); 130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 131579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 132579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 133579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 134579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Insn getOriginalRopInsn() { 135579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return insn; 136579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 137579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 138579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 139579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 140579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public RegisterSpec getLocalAssignment() { 141579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpec assignment; 142579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 143579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (insn.getOpcode().getOpcode() == RegOps.MARK_LOCAL) { 144579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assignment = insn.getSources().get(0); 145579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 146579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson assignment = getResult(); 147579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 148579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 149579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (assignment == null) { 150579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return null; 151579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 152579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 153579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson LocalItem local = assignment.getLocalItem(); 154579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 155579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (local == null) { 156579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return null; 157579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 158579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 159579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return assignment; 160579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 161579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 162579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 163579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Upgrades this insn to a version that represents the constant source 164579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * literally. If the upgrade is not possible, this does nothing. 165579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 166579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @see Insn#withSourceLiteral 167579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 168579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void upgradeToLiteral() { 169579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList oldSources = insn.getSources(); 170579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 171579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson insn = insn.withSourceLiteral(); 172579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson getBlock().getParent().onSourcesChanged(this, oldSources); 173579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 174579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 175579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 176579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return true if this is a move (but not a move-operand) instruction 177579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 178579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 179579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean isNormalMoveInsn() { 180579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return insn.getOpcode().getOpcode() == RegOps.MOVE; 181579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 182579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 183579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 184579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 185579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean isMoveException() { 186579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return insn.getOpcode().getOpcode() == RegOps.MOVE_EXCEPTION; 187579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 188579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 189579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 190579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 191579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean canThrow() { 192579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return insn.canThrow(); 193579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 194579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 195579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 196579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 197579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void accept(Visitor v) { 198579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (isNormalMoveInsn()) { 199579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson v.visitMoveInsn(this); 200579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 201579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson v.visitNonMoveInsn(this); 202579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 203579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 204579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 205579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 206579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 207579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean isPhiOrMove() { 208579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return isNormalMoveInsn(); 209579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 210579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 211579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 212579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@inheritDoc} 213579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 214579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * TODO: Increase the scope of this. 215579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 216579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 217579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean hasSideEffect() { 218579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Rop opcode = getOpcode(); 219579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 220579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (opcode.getBranchingness() != Rop.BRANCH_NONE) { 221579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return true; 222579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 223579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 224579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson boolean hasLocalSideEffect 225579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson = Optimizer.getPreserveLocals() && getLocalAssignment() != null; 226579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 227579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson switch (opcode.getOpcode()) { 228579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.MOVE_RESULT: 229579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.MOVE: 230579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.CONST: 231579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return hasLocalSideEffect; 232579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson default: 233579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return true; 234579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 235579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 236579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson} 237