Example usage for org.eclipse.jdt.internal.compiler.codegen CodeStream invoke

List of usage examples for org.eclipse.jdt.internal.compiler.codegen CodeStream invoke

Introduction

In this page you can find the example usage for org.eclipse.jdt.internal.compiler.codegen CodeStream invoke.

Prototype

public void invoke(byte opcode, MethodBinding methodBinding, TypeBinding declaringClass) 

Source Link

Usage

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.lifting.Lifting.java

License:Open Source License

/**
* API for AbstractMethodDeclaration://from   w  ww .j  a  v a  2s  . c o  m
*
 *  Create a byte code sequence for a runtime check in a creation method:
 *  R _OT$create_OT$R(B b) {
 *       if (this._OT$cache_OT$R.contains(b))
 *       throw new DuplicateRoleException("R");
 *     // continue regular code.
 *  }
 *
 * Note, the need for this runtime check is detected quite late.
 * At this point it is easier to create the byte code sequence directly,
 * rather the creating AST first.
 */
public static void createDuplicateRoleCheck(CodeStream codeStream, AbstractMethodDeclaration method) {
    MethodBinding binding = method.binding;
    Scope scope = method.scope;

    ReferenceBinding roleType = (ReferenceBinding) binding.returnType;
    String roleName = new String(roleType.readableName());
    // TODO(SH): check why roleType.getRoleModel().getClassPartBinding().roleModel may yield a different result.
    // I think it occured in haeder/stopwatch from smile-CVS.
    //RoleModel role = roleType.getRealClass().roleModel;
    char[] cacheName = LiftingEnvironment.getCacheName(roleType.roleModel.getBoundRootRole());

    ReferenceBinding teamBinding = roleType.enclosingType();//role.getTeamModel().getBinding();
    FieldBinding cache = TypeAnalyzer.findField(teamBinding, cacheName, /*static*/false, /*outer*/false,
            ITranslationStates.STATE_FULL_LIFTING); // generated by this state
    if (cache == null)
        throw new InternalCompilerError("generated cache field not found: " + new String(cacheName)); //$NON-NLS-1$
    ReferenceBinding map = (ReferenceBinding) scope.getType(IOTConstants.WEAK_HASH_MAP, 3);
    MethodBinding contains = map.getMethod(scope, IOTConstants.CONTAINS_KEY);

    ReferenceBinding exc = (ReferenceBinding) scope.getType(IOTConstants.ORG_OBJECTTEAMS_DUPLICATE_ROLE, 3);
    TypeBinding[] types = new TypeBinding[] { scope.getJavaLangString() };
    MethodBinding excInit = exc.getExactConstructor(types);

    BranchLabel normalCase = new BranchLabel(codeStream);

    codeStream.aload_0(); // this
    codeStream.fieldAccess(Opcodes.OPC_getfield, cache, teamBinding); // getfield      MyTeam._OT$cache_OT$R Ljava/util/WeakHashMap;
    codeStream.aload_1(); // arg0
    codeStream.invoke(Opcodes.OPC_invokevirtual, contains, map); // invokevirtual java.util.WeakHashMap.containsKey (Ljava/lang/Object;)Z
    codeStream.ifeq(normalCase); // false -> #endif
    codeStream.new_(exc); // new           <org.objectteams.DuplicateRoleException>
    codeStream.dup(); // dup
    codeStream.ldc(roleName); // ldc "R"
    codeStream.invoke(Opcodes.OPC_invokespecial, excInit, exc); // invokespecial org.objectteams.DuplicateRoleException.<init> (Ljava/lang/String;)V
    codeStream.athrow(); // athrow
    normalCase.place(); // #endif
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticBaseCallSurrogate.java

License:Open Source License

/** Directly generate the instruction for this method's body (no AST available). */
public void generateInstructions(CodeStream codeStream) {
    codeStream.new_(this.errorType);
    codeStream.dup();/*ww  w  .ja v  a2  s  .  c o m*/
    codeStream.ldc("Binding error: base-call impossible!"); //$NON-NLS-1$
    MethodBinding ctorBinding = ((ReferenceBinding) this.errorType)
            .getExactConstructor(new TypeBinding[] { this.stringType });
    codeStream.invoke(Opcodes.OPC_invokespecial, ctorBinding, this.errorType);
    codeStream.athrow();
    codeStream.aconst_null(); // always generalized to Object
    codeStream.areturn();
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticRoleBridgeMethodBinding.java

License:Open Source License

@Override
public void generateInstructions(CodeStream codeStream) {
    TypeBinding[] arguments = this.parameters;
    int argLen = arguments.length;
    TypeBinding[] targetParameters = this.targetMethod.parameters;
    int resolvedPosition = 0;
    int argIdx = 0;
    int targetIdx = 0;
    switch (this.purpose) {
    case RoleMethodBridgeInner:
        codeStream.aload_0(); // synthetic first arg is the receiver role
        codeStream.checkcast(this.targetMethod.declaringClass);
        resolvedPosition = 1; // first arg is processed
        argIdx = 1;//www  .j a va  2s.  c o  m
        if (this.targetMethod.isStatic()) {
            codeStream.iconst_0(); // dummy int
            codeStream.aload_2(); // pass synth. team arg
            argIdx += 2;
            resolvedPosition += 2;
        }
        break;
    case RoleMethodBridgeOuter:
        resolvedPosition = 1; // ignore team instance at 0
        argIdx = 0; // pass all args unchanged
        break;
    }
    while (argIdx < argLen) {
        TypeBinding parameter = targetParameters[targetIdx++];
        TypeBinding argument = arguments[argIdx++];
        codeStream.load(argument, resolvedPosition);
        if (TypeBinding.notEquals(argument, parameter))
            codeStream.checkcast(parameter);
        switch (parameter.id) {
        case TypeIds.T_long:
        case TypeIds.T_double:
            resolvedPosition += 2;
            break;
        default:
            resolvedPosition++;
            break;
        }
    }
    if (this.targetMethod.isStatic())
        codeStream.invoke(Opcodes.OPC_invokestatic, this.targetMethod, null);
    else
        codeStream.invoke(Opcodes.OPC_invokespecial, this.targetMethod, null); // non-static private role method
    switch (this.targetMethod.returnType.id) {
    case TypeIds.T_void:
        codeStream.return_();
        break;
    case TypeIds.T_boolean:
    case TypeIds.T_byte:
    case TypeIds.T_char:
    case TypeIds.T_short:
    case TypeIds.T_int:
        codeStream.ireturn();
        break;
    case TypeIds.T_long:
        codeStream.lreturn();
        break;
    case TypeIds.T_float:
        codeStream.freturn();
        break;
    case TypeIds.T_double:
        codeStream.dreturn();
        break;
    default:
        codeStream.areturn();
    }
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.lookup.SyntheticRoleFieldAccess.java

License:Open Source License

/**
 * Generate the sequence for invoking this accessor.
 *
 * PRE: the role instance is on the stack, for write access also the new value
 * POST: values from PRE have been consumed, for read access the value is on the stack
 *
 * @param codeStream/*from  w w w.  ja v  a  2s  .c  o m*/
 */
public byte prepareOrGenerateInvocation(CodeStream codeStream, byte opcode) {
    ReferenceBinding roleType = (ReferenceBinding) this.parameters[0];
    if (roleType instanceof UnresolvedReferenceBinding) {
        try {
            roleType = ((UnresolvedReferenceBinding) roleType).resolve(Config.getLookupEnvironment(), false);
        } catch (NotConfiguredException e) {
            e.logWarning("Failed to generate accessor"); //$NON-NLS-1$
            return opcode;
        }
        this.parameters[0] = roleType;
    }
    if (this.purpose == FieldReadAccess || this.purpose == SuperFieldReadAccess) {
        insertOuterAccess(codeStream, roleType); // role -> role,team
        codeStream.swap(); // role,team -> team,role
        codeStream.invoke(Opcodes.OPC_invokevirtual, this, // team,role -> result
                this.declaringClass);
    } else {
        TypeBinding targetType = this.targetWriteField.type;
        LocalVariableBinding arg = new LocalVariableBinding("<tmp>".toCharArray(), //$NON-NLS-1$
                targetType, 0, false);
        arg.resolvedPosition = codeStream.maxLocals;
        arg.useFlag = LocalVariableBinding.USED;
        codeStream.record(arg);
        arg.recordInitializationStartPC(codeStream.position);
        codeStream.store(arg, false/*valueRequired*/); // role, arg -> role
        insertOuterAccess(codeStream, roleType); // role -> role,team
        codeStream.swap(); // role,team -> team,role
        codeStream.load(arg); //            -> team,role,arg
        codeStream.invoke(Opcodes.OPC_invokevirtual, this, //           -> <empty>
                this.declaringClass);
        if (arg.initializationPCs != null) // null checking is asymmetric in LocalVariableBinding.
            arg.recordInitializationEndPC(codeStream.position);
    }
    return 0; // done
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.RoleMigrationImplementor.java

License:Open Source License

private static void doAddMigrateMethod(TypeDeclaration roleClassDecl, char[] selector,
        TypeReference argumentTypeRef, TypeReference returnTypeRef, final String kind, final char[] cacheName) {
    AstGenerator gen = new AstGenerator(roleClassDecl.sourceStart, roleClassDecl.sourceEnd);
    MethodDeclaration migrate = new MethodDeclaration(roleClassDecl.compilationResult) {
        @Override/*from w w  w.ja  va2 s.c o m*/
        protected void endOfMethodHook(ClassFile classfile) {
            // common code for both variants:
            CodeStream codeStream = classfile.codeStream;
            // if (otherTeam == null)
            BranchLabel goOn = new BranchLabel(codeStream);
            codeStream.aload_1(); //otherTeam / otherBase
            codeStream.ifnonnull(goOn);
            // { throw new NullPointerException("Team/base argument must not be null"); }
            ReferenceBinding npeBinding = (ReferenceBinding) this.scope.getType(JAVA_LANG_NULLPOINTEREXCEPTION,
                    3);
            codeStream.new_(npeBinding);
            codeStream.dup();
            MethodBinding npeStringCtor = getStringArgCtor(npeBinding);
            if (npeStringCtor == null)
                throw new InternalCompilerError(
                        "Expected constructor NullPointerException.<init>(String) not found"); //$NON-NLS-1$
            codeStream.ldc(kind + " argument must not be null"); //$NON-NLS-1$
            codeStream.invoke(Opcodes.OPC_invokespecial, npeStringCtor, npeBinding);
            codeStream.athrow();
            goOn.place();

            // specific code:
            if (kind == TEAM)
                genMigrateToTeamInstructions(codeStream, this.scope.enclosingSourceType());
            else
                genMigrateToBaseInstructions(codeStream, this.scope.enclosingSourceType(), this.scope,
                        cacheName);
        }

        private MethodBinding getStringArgCtor(ReferenceBinding npeBinding) {
            MethodBinding[] ctors = npeBinding.getMethods(TypeConstants.INIT);
            for (MethodBinding ctor : ctors) {
                if (ctor.parameters.length == 1 && ctor.parameters[0].id == TypeIds.T_JavaLangString)
                    return ctor;
            }
            return null;
        }

        @Override
        public void analyseCode(ClassScope classScope, FlowContext flowContext, FlowInfo flowInfo) {
            // noop
        }
    };
    gen.setMethodPositions(migrate);
    migrate.isGenerated = true;

    migrate.modifiers = AccPublic | AccSynchronized;
    migrate.typeParameters = new TypeParameter[] {
            gen.unboundedTypeParameter(RoleMigrationImplementor.TYPEPARAM) };
    migrate.returnType = returnTypeRef;
    migrate.selector = selector;
    migrate.arguments = new Argument[] { gen.argument(("other" + kind).toCharArray(), argumentTypeRef) }; //$NON-NLS-1$
    migrate.statements = new Statement[0];
    migrate.hasParsedStatements = true;
    AstEdit.addMethod(roleClassDecl, migrate);
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.RoleMigrationImplementor.java

License:Open Source License

static void genMigrateToBaseInstructions(CodeStream codeStream, SourceTypeBinding roleBinding, Scope scope,
        char[] cacheName) {
    FieldBinding baseField = roleBinding.getField(IOTConstants._OT_BASE, true);
    // accessing the cache (using remove() and put()):
    ReferenceBinding cacheTypeBinding = (ReferenceBinding) scope.getType(IOTConstants.WEAK_HASH_MAP, 3);
    MethodBinding remove = getMethod(cacheTypeBinding, "remove".toCharArray(), 1); //$NON-NLS-1$
    MethodBinding put = cacheTypeBinding.getMethod(scope, "put".toCharArray()); //$NON-NLS-1$
    // accessing the base object (using _OT$removeRole() and _OT$addRole()):
    WeavingScheme weavingScheme = scope.compilerOptions().weavingScheme;
    ReferenceBinding iboundBase = (ReferenceBinding) scope
            .getType(weavingScheme == WeavingScheme.OTDRE ? IOTConstants.ORG_OBJECTTEAMS_IBOUNDBASE2
                    : IOTConstants.ORG_OBJECTTEAMS_IBOUNDBASE, 3);

    // remove old from cache
    codeStream.aload_0(); // this
    codeStream.fieldAccess(Opcodes.OPC_getfield, enclosingInstanceField(roleBinding), // this.this$n
            roleBinding);/*from   w w w  .  ja v  a2s. c om*/
    codeStream.fieldAccess(Opcodes.OPC_getfield, roleBinding.enclosingType().getField(cacheName, true), // this.this$n._OT$cache$R
            roleBinding.enclosingType());
    codeStream.dup(); // for use in put() below
    codeStream.aload_0(); // this
    codeStream.fieldAccess(Opcodes.OPC_getfield, baseField, // this._OT$base
            roleBinding);
    codeStream.dup(); // share for nested method call         // this._OT$base
    // remove role from this (old) base
    genAddOrRemoveRole(codeStream, scope, iboundBase, false);// -> void      // -> base._OT$removeRole(this)
    codeStream.invoke(Opcodes.OPC_invokevirtual, remove, // -> cache.remove(base)
            cacheTypeBinding);
    codeStream.pop(); // discard result

    // this._OT$base = (MyBase)otherBase
    codeStream.aload_0(); // this
    codeStream.aload_1(); // otherBase
    codeStream.checkcast(roleBinding.baseclass());
    codeStream.fieldAccess(Opcodes.OPC_putfield, baseField, roleBinding);

    // add new to cache (cache is still on the stack)
    codeStream.aload_1(); // otherBase
    codeStream.aload_0(); // this (role)
    codeStream.invoke(Opcodes.OPC_invokevirtual, put, cacheTypeBinding);

    // add to new base:
    codeStream.aload_1(); // otherBase
    genAddOrRemoveRole(codeStream, scope, iboundBase, true); // -> void      // -> base._OT$addRemoveRole(this, false)

    codeStream.return_();
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.RoleMigrationImplementor.java

License:Open Source License

static void genAddOrRemoveRole(CodeStream codeStream, Scope scope, ReferenceBinding iboundBase,
        boolean isAdding) {
    codeStream.aload_0(); // this
    // OTDYN: Slightly different methods depending on the weaving strategy:
    switch (scope.compilerOptions().weavingScheme) {
    case OTDRE://from   w w w. j  av  a2s  .c  o m
        // _OT$addOrRemoveRole(role, isAdding)
        if (isAdding)
            codeStream.iconst_1(); // isAdding=true
        else
            codeStream.iconst_0(); // isAdding=false   
        codeStream.invoke(Opcodes.OPC_invokeinterface,
                iboundBase.getMethod(scope, IOTConstants.ADD_REMOVE_ROLE), iboundBase);
        break;
    case OTRE:
        // _OT$addRole(role) or _OT$removeRole(role):
        codeStream.invoke(Opcodes.OPC_invokeinterface,
                isAdding ? iboundBase.getMethod(scope, IOTConstants.ADD_ROLE)
                        : iboundBase.getMethod(scope, IOTConstants.REMOVE_ROLE),
                iboundBase);
    }
}