Example usage for org.objectweb.asm Opcodes DUP

List of usage examples for org.objectweb.asm Opcodes DUP

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes DUP.

Prototype

int DUP

To view the source code for org.objectweb.asm Opcodes DUP.

Click Source Link

Usage

From source file:org.eclipse.objectteams.otredyn.bytecode.asm.AddGlobalTeamActivationAdapter.java

License:Open Source License

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    synchronized (AddGlobalTeamActivationAdapter.class) {
        if (!done && isMainMethod(name, desc, access)) {
            done = true;//from  w ww . j  ava2s  . c om
            final MethodVisitor methodVisitor = cv.visitMethod(access, name, desc, null, null);
            return new AdviceAdapter(this.api, methodVisitor, access, name, desc) {
                @Override
                protected void onMethodEnter() {
                    List<String> teams = getTeamsFromConfigFile();
                    for (String aTeam : teams) {
                        Label start, end, typeHandler, ctorHandler, after;

                        String aTeamSlash = aTeam.replace('.', '/');

                        // new SomeTeam():
                        methodVisitor.visitLabel(start = new Label());
                        methodVisitor.visitTypeInsn(Opcodes.NEW, aTeamSlash);
                        //       .activate(Team.ALL_THREADS):
                        methodVisitor.visitInsn(Opcodes.DUP);
                        methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, aTeamSlash, "<init>", "()V",
                                false);
                        methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, ClassNames.TEAM_SLASH, "ALL_THREADS",
                                "Ljava/lang/Thread;");
                        methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, aTeamSlash, "activate",
                                "(Ljava/lang/Thread;)V", false);

                        methodVisitor.visitLabel(end = new Label());
                        methodVisitor.visitJumpInsn(Opcodes.GOTO, after = new Label());

                        // catch (ClassNotFoundException, NoClassDefFoundError):
                        //   System.err.println(...)
                        methodVisitor.visitLabel(typeHandler = new Label());
                        methodVisitor.visitInsn(Opcodes.POP); // discard the exception
                        methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "err",
                                "Ljava/io/PrintStream;");
                        methodVisitor.visitLdcInsn("Config error: Team class '" + aTeam + "' in config file '"
                                + TEAM_CONFIG_FILE + "' can not be found!");
                        methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println",
                                "(Ljava/lang/String;)V", false);
                        methodVisitor.visitJumpInsn(Opcodes.GOTO, after);
                        methodVisitor.visitTryCatchBlock(start, end, typeHandler,
                                "java/lang/ClassNotFoundException");
                        // dup to avoid stackmap errors (ASM bug at 1.8)
                        methodVisitor.visitLabel(typeHandler = new Label());
                        methodVisitor.visitInsn(Opcodes.POP); // discard the exception
                        methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "err",
                                "Ljava/io/PrintStream;");
                        methodVisitor.visitLdcInsn("Config error: Team class '" + aTeam + "' in config file '"
                                + TEAM_CONFIG_FILE + "' can not be found!");
                        methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println",
                                "(Ljava/lang/String;)V", false);
                        methodVisitor.visitJumpInsn(Opcodes.GOTO, after);
                        //
                        methodVisitor.visitTryCatchBlock(start, end, typeHandler,
                                "java/lang/NoClassDefFoundError");

                        // catch (NoSuchMethodError):
                        //   System.err.println(...)
                        methodVisitor.visitLabel(ctorHandler = new Label());
                        methodVisitor.visitInsn(Opcodes.POP); // discard the exception
                        methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "err",
                                "Ljava/io/PrintStream;");
                        methodVisitor.visitLdcInsn(
                                "Activation failed: Team class '" + aTeam + "' has no default constuctor!");
                        methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println",
                                "(Ljava/lang/String;)V", false);
                        methodVisitor.visitTryCatchBlock(start, end, ctorHandler,
                                "java/lang/NoSuchMethodError");

                        methodVisitor.visitLabel(after);
                    }
                }

                @Override
                public void visitMaxs(int maxStack, int maxLocals) {
                    super.visitMaxs(Math.max(maxStack, 3), maxLocals);
                }
            };
        }
        return null;
    }
}

From source file:org.eclipse.objectteams.otredyn.bytecode.asm.CreateAddRemoveRoleMethod.java

License:Open Source License

void genGetInitializedRoleSet(InsnList instructions, int targetLocal) {
    // x = this._OT$roleSet 
    instructions.add(new IntInsnNode(Opcodes.ALOAD, 0));
    instructions.add(new FieldInsnNode(Opcodes.GETFIELD, name, ConstantMembers.OT_ROLE_SET,
            ConstantMembers.HASH_SET_FIELD_TYPE));

    instructions.add(new IntInsnNode(Opcodes.ASTORE, targetLocal));
    instructions.add(new IntInsnNode(Opcodes.ALOAD, targetLocal));

    // if (x == null) {
    LabelNode skipInstantiation = new LabelNode();
    instructions.add(new JumpInsnNode(Opcodes.IFNONNULL, skipInstantiation));

    // this._OT$roleSet = new HashSet();
    instructions.add(new IntInsnNode(Opcodes.ALOAD, 0));
    instructions.add(new TypeInsnNode(Opcodes.NEW, ClassNames.HASH_SET_SLASH));
    instructions.add(new InsnNode(Opcodes.DUP));
    instructions//from   ww w .  jav a2s  .  c om
            .add(new MethodInsnNode(Opcodes.INVOKESPECIAL, ClassNames.HASH_SET_SLASH, "<init>", "()V", false));

    instructions.add(new IntInsnNode(Opcodes.ASTORE, targetLocal));
    instructions.add(new IntInsnNode(Opcodes.ALOAD, targetLocal));
    instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, name, ConstantMembers.OT_ROLE_SET,
            ConstantMembers.HASH_SET_FIELD_TYPE));

    instructions.add(skipInstantiation);
    // }
}

From source file:org.eclipse.objectteams.otredyn.bytecode.asm.CreateDispatchCodeInOrgMethodAdapter.java

License:Open Source License

@Override
protected InsnList createInstructionsToCheackTeams(MethodNode method) {
    InsnList instructions = new InsnList();
    instructions.add(new InsnNode(Opcodes.DUP));
    LabelNode label = new LabelNode();
    //if (teams == null) {
    instructions.add(new JumpInsnNode(Opcodes.IFNONNULL, label));
    instructions.add(new InsnNode(Opcodes.POP));
    //put the boundMethodId on the stack
    instructions.add(createLoadIntConstant(boundMethodId));
    Type[] args = Type.getArgumentTypes(method.desc);
    // box the arguments
    instructions.add(getBoxingInstructions(args, (method.access & Opcodes.ACC_STATIC) != 0));
    //callOrigStatic(boundMethodId, args);
    instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, name, ConstantMembers.callOrigStatic.getName(),
            ConstantMembers.callOrigStatic.getSignature()));
    Type returnType = Type.getReturnType(method.desc);
    instructions.add(getUnboxingInstructionsForReturnValue(returnType));
    instructions.add(label);/*from   w ww .j  ava2s.  c o m*/

    return instructions;
}

From source file:org.eclipse.objectteams.otredyn.bytecode.asm.CreateMethodAccessAdapter.java

License:Open Source License

@Override
public boolean transform() {
    MethodNode methodNode = getMethod(method);
    InsnList instructions = new InsnList();

    if (isConstructor) {
        // create empty object for constructor invocation:
        instructions.add(new TypeInsnNode(Opcodes.NEW, name));
        instructions.add(new InsnNode(Opcodes.DUP));
    } else if (!method.isStatic()) {
        //put "this" on the stack for a non-static method
        instructions.add(new IntInsnNode(Opcodes.ALOAD, 0));
    }/*from  w w  w  . j  a v a  2 s  .  c  o m*/

    //Unbox arguments
    Type[] args = Type.getArgumentTypes(methodNode.desc);

    if (args.length > 0) {

        for (int i = 0; i < args.length; i++) {
            instructions.add(new IntInsnNode(Opcodes.ALOAD, firstArgIndex + 2));
            instructions.add(createLoadIntConstant(i));
            instructions.add(new InsnNode(Opcodes.AALOAD));
            Type arg = args[i];
            if (arg.getSort() != Type.ARRAY && arg.getSort() != Type.OBJECT) {
                String objectType = AsmTypeHelper.getObjectType(arg);
                instructions.add(new TypeInsnNode(Opcodes.CHECKCAST, objectType));
                instructions.add(AsmTypeHelper.getUnboxingInstructionForType(arg, objectType));
            } else {
                instructions.add(new TypeInsnNode(Opcodes.CHECKCAST, arg.getInternalName()));
            }
        }
    }

    //call original method
    int opcode = Opcodes.INVOKEVIRTUAL;
    if (method.isStatic()) {
        opcode = Opcodes.INVOKESTATIC;
    } else if (isConstructor) {
        opcode = Opcodes.INVOKESPECIAL;
    }
    instructions.add(new MethodInsnNode(opcode, name, method.getName(), method.getSignature()));

    //box return value
    Type returnType = Type.getReturnType(methodNode.desc);

    if (returnType.getSort() != Type.OBJECT && returnType.getSort() != Type.ARRAY
            && returnType.getSort() != Type.VOID) {

        instructions.add(AsmTypeHelper.getBoxingInstructionForType(returnType));
        instructions.add(new InsnNode(Opcodes.ARETURN));
    } else if (returnType.getSort() == Type.VOID && !isConstructor) {
        instructions.add(new InsnNode(Opcodes.ACONST_NULL));
        instructions.add(new InsnNode(Opcodes.ARETURN));
    } else {
        instructions.add(new InsnNode(Opcodes.ARETURN));
    }

    //add the instructions to a new label in the existing switch
    MethodNode access = getMethod(this.access);
    addNewLabelToSwitch(access.instructions, instructions, accessId);

    return true;
}

From source file:org.eclipse.objectteams.otredyn.bytecode.asm.CreateSwitchForAccessAdapter.java

License:Open Source License

@Override
protected void addInstructionForDefaultLabel(MethodNode method) {
    if (superClassName.equals("java/lang/Object")) {
        method.instructions.add(new TypeInsnNode(Opcodes.NEW, "org/objectteams/NoSuchMethodError"));
        method.instructions.add(new InsnNode(Opcodes.DUP));
        method.instructions.add(new IntInsnNode(Opcodes.ILOAD, getFirstArgIndex())); // accessId
        method.instructions.add(new LdcInsnNode(clazz.getName())); // current class
        method.instructions.add(new LdcInsnNode("decapsulating access")); // access reason
        method.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "org/objectteams/NoSuchMethodError",
                "<init>", "(ILjava/lang/String;Ljava/lang/String;)V", false));
        method.instructions.add(new InsnNode(Opcodes.ATHROW));
    } else {//from  w w  w.  j  ava2s.  c o m
        Type[] args = Type.getArgumentTypes(method.desc);
        addInstructionsForLoadArguments(method.instructions, args, getMethod().isStatic());

        int opcode = Opcodes.INVOKESPECIAL;
        if (getMethod().isStatic()) {
            opcode = Opcodes.INVOKESTATIC;
        }
        method.instructions.add(
                new MethodInsnNode(opcode, superClassName, getMethod().getName(), getMethod().getSignature()));
        method.instructions.add(new InsnNode(Opcodes.ARETURN));
    }
}

From source file:org.eclipse.objectteams.otredyn.bytecode.asm.MoveCodeToCallOrigAdapter.java

License:Open Source License

public boolean transform() {
    MethodNode orgMethod = getMethod(method);
    if ((orgMethod.access & Opcodes.ACC_ABSTRACT) != 0)
        return false;

    MethodNode callOrig = getMethod(this.callOrig);

    Type returnType = Type.getReturnType(orgMethod.desc);

    InsnList newInstructions = new InsnList();

    //Unboxing arguments
    Type[] args = Type.getArgumentTypes(orgMethod.desc);

    int boundMethodIdSlot = firstArgIndex;

    if (args.length > 0) {
        // move boundMethodId to a higher slot, to make lower slots available for original locals
        newInstructions.add(new IntInsnNode(Opcodes.ILOAD, boundMethodIdSlot));
        boundMethodIdSlot = callOrig.maxLocals + 1;
        newInstructions.add(new IntInsnNode(Opcodes.ISTORE, boundMethodIdSlot));

        newInstructions.add(new IntInsnNode(Opcodes.ALOAD, firstArgIndex + argOffset + 1));

        int slot = firstArgIndex + argOffset;
        for (int i = argOffset; i < args.length; i++) {
            if (i < args.length - 1) {
                newInstructions.add(new InsnNode(Opcodes.DUP));
            }/*from  ww w  . j av a 2  s .  co m*/
            newInstructions.add(createLoadIntConstant(i));
            newInstructions.add(new InsnNode(Opcodes.AALOAD));
            Type arg = args[i];
            if (arg.getSort() != Type.ARRAY && arg.getSort() != Type.OBJECT) {
                String objectType = AsmTypeHelper.getObjectType(arg);
                newInstructions.add(new TypeInsnNode(Opcodes.CHECKCAST, objectType));
                newInstructions.add(AsmTypeHelper.getUnboxingInstructionForType(arg, objectType));
            } else {
                newInstructions.add(new TypeInsnNode(Opcodes.CHECKCAST, arg.getInternalName()));
            }

            newInstructions.add(new IntInsnNode(args[i].getOpcode(Opcodes.ISTORE), slot));
            slot += arg.getSize();
        }
    }

    if (superIsWeavable)
        adjustSuperCalls(orgMethod.instructions, orgMethod.name, args, returnType, boundMethodIdSlot);

    // replace return of the original method with areturn and box the result value if needed
    replaceReturn(orgMethod.instructions, returnType);

    newInstructions.add(orgMethod.instructions);

    addNewLabelToSwitch(callOrig.instructions, newInstructions, boundMethodId);

    // a minimum stacksize of 3 is needed to box the arguments
    callOrig.maxStack = Math.max(Math.max(callOrig.maxStack, orgMethod.maxStack), 3);

    // we have to increment the max. stack size, because we have to put NULL on the stack
    if (returnType.getSort() == Type.VOID) {
        callOrig.maxStack += 1;
    }
    callOrig.maxLocals = Math.max(callOrig.maxLocals, orgMethod.maxLocals);
    return true;
}

From source file:org.eclipse.objectteams.otredyn.bytecode.asm.MoveCodeToCallOrigAdapter.java

License:Open Source License

/** To avoid infinite recursion, calls super.m(a1, a2) must be translated to super.callOrig(boundMethodId, new Object[] {a1, a2}). */
private void adjustSuperCalls(InsnList instructions, String selector, Type[] args, Type returnType,
        int boundMethodIdSlot) {
    // search:// w w w  .j  a v  a  2  s . com
    List<MethodInsnNode> toReplace = new ArrayList<MethodInsnNode>();
    ListIterator<AbstractInsnNode> orgMethodIter = instructions.iterator();
    while (orgMethodIter.hasNext()) {
        AbstractInsnNode orgMethodNode = orgMethodIter.next();
        if (orgMethodNode.getOpcode() == Opcodes.INVOKESPECIAL
                && ((MethodInsnNode) orgMethodNode).name.equals(selector))
            toReplace.add((MethodInsnNode) orgMethodNode);
    }
    if (toReplace.isEmpty())
        return;
    // replace:
    for (MethodInsnNode oldNode : toReplace) {
        // we need to insert into the loading sequence before the invocation, find the insertion points:
        AbstractInsnNode[] insertionPoints = StackBalanceAnalyzer.findInsertionPointsBefore(oldNode, args);
        AbstractInsnNode firstInsert = insertionPoints.length > 0 ? insertionPoints[0] : oldNode;

        // push first arg to _OT$callOrig():
        instructions.insertBefore(firstInsert, new IntInsnNode(Opcodes.ILOAD, boundMethodIdSlot));

        // prepare array as second arg to _OT$callOrig():
        instructions.insertBefore(firstInsert, new IntInsnNode(Opcodes.BIPUSH, args.length));
        instructions.insertBefore(firstInsert, new TypeInsnNode(Opcodes.ANEWARRAY, "java/lang/Object"));

        for (int i = 0; i < insertionPoints.length; i++) {
            // NB: each iteration has an even stack balance, where the top is the Object[].
            instructions.insertBefore(insertionPoints[i], new InsnNode(Opcodes.DUP));
            instructions.insertBefore(insertionPoints[i], new IntInsnNode(Opcodes.BIPUSH, i));
            // leave the original loading sequence in tact and continue at the next point:
            AbstractInsnNode insertAt = (i + 1 < insertionPoints.length) ? insertionPoints[i + 1] : oldNode;
            instructions.insertBefore(insertAt, AsmTypeHelper.getBoxingInstructionForType(args[i]));
            instructions.insertBefore(insertAt, new InsnNode(Opcodes.AASTORE));
        }

        if (returnType == Type.VOID_TYPE)
            instructions.insert(oldNode, new InsnNode(Opcodes.POP));
        else
            instructions.insert(oldNode, AsmTypeHelper.getUnboxingInstructionForType(returnType));

        instructions.set(oldNode, new MethodInsnNode(Opcodes.INVOKESPECIAL, ((MethodInsnNode) oldNode).owner,
                callOrig.getName(), callOrig.getSignature()));
    }
}

From source file:org.elasticsearch.plan.a.External.java

License:Apache License

private void variable(final ParserRuleContext source, final String name, final boolean last) {
    final Variable variable = adapter.getVariable(name);

    if (variable == null) {
        throw new IllegalArgumentException(error(source) + "Unknown variable [" + name + "].");
    }/*  ww  w.  ja  v  a  2  s  . com*/

    final Type type = variable.type;

    if (last && write != null) {
        final ExpressionMetadata writeemd = adapter.createExpressionMetadata(write);

        if (token == CAT) {
            writeemd.promotion = caster.concat;
            analyzer.visit(write);
            writeemd.to = writeemd.from;
            caster.markCast(writeemd);

            final Cast cast = caster.getLegalCast(source, standard.stringType, type, false);

            segments.add(new VariableSegment(source, variable, false));
            segments.add(new AppendStringsSegment(source, type, true));
            segments.add(new NodeSegment(write));
            segments.add(new AppendStringsSegment(write, writeemd.to, false));
            segments.add(new ToStringsSegment(source));
            segments.add(new CastSegment(source, cast));

            if (read) {
                if (type.metadata.size == 1) {
                    segments.add(new InstructionSegment(source, Opcodes.DUP));
                } else if (type.metadata.size == 2) {
                    segments.add(new InstructionSegment(source, Opcodes.DUP2));
                } else {
                    throw new IllegalStateException(error(source) + "Unexpected type size.");
                }
            }

            segments.add(new VariableSegment(source, variable, true));
        } else if (token > 0) {
            final boolean increment = type.metadata == TypeMetadata.INT && (token == ADD || token == SUB);
            current = type;
            final Cast[] casts = toNumericCasts(source);
            writeemd.to = current;
            analyzer.visit(write);

            if (increment && writeemd.postConst != null) {
                if (read && post) {
                    segments.add(new VariableSegment(source, variable, false));
                }

                final int value = token == SUB ? -1 * (int) writeemd.postConst : (int) writeemd.postConst;
                segments.add(new IncrementSegment(source, variable, value));

                if (read && !post) {
                    segments.add(new VariableSegment(source, variable, false));
                }
            } else {
                segments.add(new VariableSegment(source, variable, false));

                if (read && post) {
                    if (type.metadata.size == 1) {
                        segments.add(new InstructionSegment(source, Opcodes.DUP));
                    } else if (type.metadata.size == 2) {
                        segments.add(new InstructionSegment(source, Opcodes.DUP2));
                    } else {
                        throw new IllegalStateException(error(source) + "Unexpected type size.");
                    }
                }

                segments.add(new CastSegment(source, casts[0]));
                segments.add(new NodeSegment(write));
                segments.add(new TokenSegment(source, current, token));
                segments.add(new CastSegment(source, casts[1]));

                if (read && !post) {
                    if (type.metadata.size == 1) {
                        segments.add(new InstructionSegment(source, Opcodes.DUP));
                    } else if (type.metadata.size == 2) {
                        segments.add(new InstructionSegment(source, Opcodes.DUP2));
                    } else {
                        throw new IllegalStateException(error(source) + "Unexpected type size.");
                    }
                }

                segments.add(new VariableSegment(source, variable, true));
            }
        } else {
            writeemd.to = type;
            analyzer.visit(write);

            segments.add(new NodeSegment(write));

            if (read && !post) {
                if (type.metadata.size == 1) {
                    segments.add(new InstructionSegment(source, Opcodes.DUP));
                } else if (type.metadata.size == 2) {
                    segments.add(new InstructionSegment(source, Opcodes.DUP2));
                } else {
                    throw new IllegalStateException(error(source) + "Unexpected type size.");
                }
            }

            segments.add(new VariableSegment(source, variable, true));
        }

        current = read ? type : standard.voidType;
    } else {
        segments.add(new VariableSegment(source, variable, false));
        current = variable.type;
    }
}

From source file:org.elasticsearch.plan.a.External.java

License:Apache License

private void field(final ParserRuleContext source, final String name, final boolean last) {
    if (current.metadata == TypeMetadata.ARRAY) {
        if ("length".equals(name)) {
            if (!read || last && write != null) {
                throw new IllegalArgumentException(error(source) + "Cannot write to read-only field [length].");
            }/* www.j  av  a 2s .co  m*/

            segments.add(new LengthSegment(source));
            current = standard.intType;
        } else {
            throw new IllegalArgumentException(error(source) + "Unexpected array field [" + name + "].");
        }
    } else {
        final Struct struct = current.struct;
        final Field field = statik ? struct.statics.get(name) : struct.members.get(name);

        if (field == null) {
            throw new IllegalArgumentException(
                    error(source) + "Unknown field [" + name + "] for type [" + struct.name + "].");
        }

        if (last && write != null) {
            if (java.lang.reflect.Modifier.isFinal(field.field.getModifiers())) {
                throw new IllegalArgumentException(error(source) + "Cannot write to read-only" + " field ["
                        + name + "] for type [" + struct.name + "].");
            }

            final ExpressionMetadata writeemd = adapter.createExpressionMetadata(write);
            final Type type = field.type;

            if (token == CAT) {
                writeemd.promotion = caster.concat;
                analyzer.visit(write);
                writeemd.to = writeemd.from;
                caster.markCast(writeemd);

                final Cast cast = caster.getLegalCast(source, standard.stringType, type, false);

                segments.add(new InstructionSegment(source, Opcodes.DUP_X1));
                segments.add(new FieldSegment(source, field, false));
                segments.add(new AppendStringsSegment(source, type, true));
                segments.add(new NodeSegment(write));
                segments.add(new AppendStringsSegment(write, writeemd.to, false));
                segments.add(new ToStringsSegment(source));
                segments.add(new CastSegment(source, cast));

                if (read) {
                    if (type.metadata.size == 1) {
                        segments.add(new InstructionSegment(source, Opcodes.DUP_X1));
                    } else if (type.metadata.size == 2) {
                        segments.add(new InstructionSegment(source, Opcodes.DUP2_X1));
                    } else {
                        throw new IllegalStateException(error(source) + "Unexpected type size.");
                    }
                }

                segments.add(new FieldSegment(source, field, true));
            } else if (token > 0) {
                current = type;
                final Cast[] casts = toNumericCasts(source);
                writeemd.to = current;
                analyzer.visit(write);

                segments.add(new InstructionSegment(source, Opcodes.DUP));
                segments.add(new FieldSegment(source, field, false));

                if (read && post) {
                    if (type.metadata.size == 1) {
                        segments.add(new InstructionSegment(source, Opcodes.DUP_X1));
                    } else if (type.metadata.size == 2) {
                        segments.add(new InstructionSegment(source, Opcodes.DUP2_X1));
                    } else {
                        throw new IllegalStateException(error(source) + "Unexpected type size.");
                    }
                }

                segments.add(new CastSegment(source, casts[0]));
                segments.add(new NodeSegment(write));
                segments.add(new TokenSegment(source, current, token));
                segments.add(new CastSegment(source, casts[1]));

                if (read && !post) {
                    if (type.metadata.size == 1) {
                        segments.add(new InstructionSegment(source, Opcodes.DUP_X1));
                    } else if (type.metadata.size == 2) {
                        segments.add(new InstructionSegment(source, Opcodes.DUP2_X1));
                    } else {
                        throw new IllegalStateException(error(source) + "Unexpected type size.");
                    }
                }

                segments.add(new FieldSegment(source, field, true));
            } else {
                writeemd.to = type;
                analyzer.visit(write);

                segments.add(new NodeSegment(write));

                if (read && !post) {
                    if (type.metadata.size == 1) {
                        segments.add(new InstructionSegment(source, Opcodes.DUP_X1));
                    } else if (type.metadata.size == 2) {
                        segments.add(new InstructionSegment(source, Opcodes.DUP2_X1));
                    } else {
                        throw new IllegalStateException(error(source) + "Unexpected type size.");
                    }
                }

                segments.add(new FieldSegment(source, field, true));
            }

            current = read ? type : standard.voidType;
        } else {
            segments.add(new FieldSegment(source, field, false));
            current = field.type;
        }
    }
}

From source file:org.elasticsearch.plan.a.External.java

License:Apache License

private void method(final ParserRuleContext source, final String name, final List<ExpressionContext> arguments,
        final boolean last) {
    final Struct struct = current.struct;

    Type[] types;//w  w w .jav  a  2s  . c  om
    Segment segment0;
    Segment segment1 = null;

    if (current.dimensions > 0) {
        throw new IllegalArgumentException(error(source) + "Unexpected call [" + name + "] on an array.");
    } else if (last && write != null) {
        throw new IllegalArgumentException(error(source) + "Cannot assign a value to a call [" + name + "].");
    } else if (statik && "makearray".equals(name)) {
        if (!read) {
            throw new IllegalArgumentException(error(source) + "A newly created array must be assigned.");
        }

        types = new Type[arguments.size()];
        Arrays.fill(types, standard.intType);
        segment0 = new MakeSegment(source, current, arguments.size());
        current = getTypeWithArrayDimensions(struct, arguments.size());
    } else {
        final Constructor constructor = statik ? struct.constructors.get(name) : null;
        final Method method = statik ? struct.functions.get(name) : struct.methods.get(name);

        if (constructor != null) {
            types = new Type[constructor.arguments.size()];
            constructor.arguments.toArray(types);

            segments.add(new NewSegment(source, constructor.owner));

            if (read) {
                segments.add(new InstructionSegment(source, Opcodes.DUP));
            } else {
                current = standard.voidType;
                statement = true;
            }

            segment0 = new ConstructorSegment(source, constructor);
        } else if (method != null) {
            types = new Type[method.arguments.size()];
            method.arguments.toArray(types);

            if (!read) {
                final int size = method.rtn.metadata.size;

                if (size == 1) {
                    segment1 = new InstructionSegment(source, Opcodes.POP);
                } else if (size == 2) {
                    segment1 = new InstructionSegment(source, Opcodes.POP2);
                } else if (size != 0) {
                    throw new IllegalStateException(error(source) + "Unexpected type size.");
                }

                current = standard.voidType;
                statement = true;
            } else {
                current = method.rtn;
            }

            segment0 = new MethodSegment(source, method);
        } else {
            throw new IllegalArgumentException(
                    error(source) + "Unknown call [" + name + "] on type [" + struct.name + "].");
        }
    }

    if (arguments.size() != types.length) {
        throw new IllegalArgumentException();
    }

    for (int argument = 0; argument < arguments.size(); ++argument) {
        final ExpressionContext exprctx = adapter.getExpressionContext(arguments.get(argument));
        final ExpressionMetadata expremd = adapter.createExpressionMetadata(exprctx);
        expremd.to = types[argument];
        analyzer.visit(exprctx);

        segments.add(new NodeSegment(exprctx));
    }

    segments.add(segment0);

    if (segment1 != null) {
        segments.add(segment1);
    }
}