List of usage examples for org.eclipse.jdt.internal.compiler.codegen Opcodes OPC_aconst_null
byte OPC_aconst_null
To view the source code for org.eclipse.jdt.internal.compiler.codegen Opcodes OPC_aconst_null.
Click Source Link
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.BytecodeTransformer.java
License:Open Source License
/** * This method replaces all references to constantpool of the superclass with references * to current subclass constantpool/*from www .java2 s .c om*/ * - all References in codeToAdjust will be exchanged * - unknown references must be added to the ConstantPool of classFile * * @param dstClassFile This is the destination Classfile wich contains the later flushed ConstantPool * @param mModel the destination method * @param codeToAdjust this is the duplicated code-part of the code_attribute (see getCodeByteCode) * @param codeAttributeOffset attribute offset within codeToAdjust * @param codeLength length of codeToAdjust * @param isCtorAddingMarkArg are we copying into a tsuper ctor with additional marger arg? */ private void adjustCode(ClassFile dstClassFile, MethodModel mModel, byte[] codeToAdjust, int codeAttributeOffset, int codeLength, boolean isCtorAddingMarkArg) { /* * States concerning marker-arg chaining sequences: * (See class comment of class ExlicitConstructorCall for background information). * * 0 : do nothing * 1 : this is a ctor * 2 : saw aconst_null * 3 : saw astore_<n> : volatile state: immediately leave this state. * When in state 3 we immediately see a self call invokespecial * replace the chaining sequence and replace the method to call; * This heuristic is safe, since the sequence * "aconst_null; astore<n>; invokespecial" * could not be created from source-code. */ int state = 1; boolean initCachesAdded = false; int actualBytecodeStart = codeAttributeOffset + CODE_ATTR_PREFIX_LEN; for (int i = actualBytecodeStart; i < actualBytecodeStart + codeLength; i++) { //get byte from bytecode array byte b_int = codeToAdjust[i]; //get number of operands from Table int length = OTByteCodes.cpReferenceLength(b_int); // if byte code is followed by a reference into the cp if (length != 0) { //get reference from current code position -> a reference consist of one or more bytes int ref = OTByteCodes.getRef(length, codeToAdjust, i + 1); ConstantPoolObject src_cpo = this._reader.readConstantPoolObject(ref, length); ConstantPoolObject dst_cpo = this._mapper.mapConstantPoolObject(src_cpo, state == 3/*addMarkerArgAllowed*/); if (dst_cpo.isMethod()) { if (dst_cpo.isIllegallyCopiedCtor()) { // illegal ctor is actually used: report as error! AbstractMethodDeclaration methodDecl = mModel.getDecl(); methodDecl.scope.problemReporter().illegallyCopiedDefaultCtor(methodDecl, methodDecl.scope.referenceType()); return; } MethodBinding method = dst_cpo.getMethodRef(); if (state == 3) { if (isCtorAddingMarkArg && method.overriddenTSupers != null && method.isConstructor()) { // statemachine recognized full pattern for chaining marker arg. Patch now: MethodBinding tsuperVersion = findTSuperVersion(method); if (tsuperVersion != null) { replaceChainArg(codeToAdjust, i - 3); dst_cpo.setMethod(tsuperVersion); } } else if (method.parameters.length > src_cpo.getMethodRef().parameters.length) { if (method.copyInheritanceSrc != null) { // overwrite 2-byte astore_n: // as to leave preceding aconst_null on stack to match the tsuper-marker codeToAdjust[i - 2] = Opcodes.OPC_nop; codeToAdjust[i - 1] = Opcodes.OPC_nop; } } } } this._writer.writeConstantPoolObject(codeToAdjust, i + 1, length, dst_cpo); } else if (b_int == Opcodes.OPC_nop && mModel != null && mModel.liftedParams != null && mModel.liftedParams.length > 0) { int arg = checkPatchLiftingNops(codeToAdjust, i); if (arg >= 0) { // found a nop sequence to be patched (constant parts are already patched) ConstantPoolObject dst_cpo = null; int loadPos = arg & 0x1FFF; // bit 0x2000 flags (storePos > 3) if (!initCachesAdded) { // only insert once // find the _OT$initCaches method: dst_cpo = getInitCachesMethod(dstClassFile); if (dst_cpo != null) { // write the method reference into the nop space: this._writer.writeConstantPoolObject(codeToAdjust, i + 2, 2, dst_cpo); } initCachesAdded = true; } if (dst_cpo == null) { codeToAdjust[i + 1] = Opcodes.OPC_nop; // delete invokevirtual // Note: aload_0 and pop are already balanced } int offset = (loadPos > 3) ? 1 : 0; // longer byte code used for aload? // find the lift method: dst_cpo = getLiftMethod(dstClassFile, mModel, loadPos); if (dst_cpo == null) return; // cannot perform required lifting // write the method reference into the nop space: this._writer.writeConstantPoolObject(codeToAdjust, i + offset + 8, 2, dst_cpo); // call sequence had two additional loads, reserve space on the stack: incrementWord(codeToAdjust, codeAttributeOffset, 6, 2); // max_stack++ length = 10 + offset; if ((arg & 0x2000) != 0) // longer byte code used for astore? length++; } } // state machine: if (state == 1 && b_int == Opcodes.OPC_aconst_null) state = 2; else if (state == 2 && b_int == Opcodes.OPC_astore) state = 3; else if (state == 3) state = 0; // patch sequence not followed by self call: quit state machine. i += length; // also skip parameters, which are not CP-index i += OTByteCodes.getParamLength(b_int, codeToAdjust, i, actualBytecodeStart); } }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.BytecodeTransformer.java
License:Open Source License
/** * When copying a team constructor which might require lifting, * peek into the byte code to find the self call. * @param model//from w w w.ja va 2 s . c o m * @return called constructor or null */ public MethodBinding peekConstructorCall(TeamModel teamModel, MethodModel model, LookupEnvironment environment) { byte[] bytes = model.getBytes(); int offset = model.getStructOffset(); this._reader = new ConstantPoolObjectReader(model, teamModel, environment); int codeAttributeOffset = findCodeAttribute(bytes, offset); int start = codeAttributeOffset + CODE_ATTR_PREFIX_LEN; int i = 0; while (true) { byte b_int = bytes[start + i]; int length = OTByteCodes.cpReferenceLength(b_int); if (length != 0) { int ref = OTByteCodes.getRef(length, bytes, start + i + 1); ConstantPoolObject src_cpo = this._reader.readConstantPoolObject(ref, length); if (!src_cpo.isMethod() || !src_cpo.getMethodRef().isConstructor()) { if (src_cpo.isSpecificType(TypeConstants.JAVA_LANG_ERROR)) { try { // search subsequent string b_int = bytes[start + i + 4]; length = OTByteCodes.cpReferenceLength(b_int); src_cpo = this._reader.readConstantPoolObject( OTByteCodes.getRef(length, bytes, start + i + 5), length); if (src_cpo.getType() == ClassFileConstants.StringTag) if (src_cpo.getString().startsWith("Unresolved compilation problem:")) //$NON-NLS-1$ model.getBinding().bytecodeMissing = true; // signal that byte code is not usable due to compile error } catch (Throwable t) { // nop, string not found } } return null; } return src_cpo.getMethodRef(); } else if (OTByteCodes.getAloadPos(b_int, bytes[start + i + 1]) != i && b_int != Opcodes.OPC_aconst_null) return null; i++; } }