public void storeVar(BytecodeVariable variable) { MethodVisitor mv = controller.getMethodVisitor(); int idx = variable.getIndex(); ClassNode type = variable.getType(); // value is on stack if (variable.isHolder()) { doGroovyCast(type); box(); mv.visitVarInsn(ALOAD, idx); mv.visitTypeInsn(CHECKCAST, "groovy/lang/Reference"); mv.visitInsn(SWAP); mv.visitMethodInsn( INVOKEVIRTUAL, "groovy/lang/Reference", "set", "(Ljava/lang/Object;)V", false); } else { doGroovyCast(type); if (type == ClassHelper.double_TYPE) { mv.visitVarInsn(DSTORE, idx); } else if (type == ClassHelper.float_TYPE) { mv.visitVarInsn(FSTORE, idx); } else if (type == ClassHelper.long_TYPE) { mv.visitVarInsn(LSTORE, idx); } else if (type == ClassHelper.boolean_TYPE || type == ClassHelper.char_TYPE || type == ClassHelper.byte_TYPE || type == ClassHelper.int_TYPE || type == ClassHelper.short_TYPE) { mv.visitVarInsn(ISTORE, idx); } else { mv.visitVarInsn(ASTORE, idx); } } // remove RHS value from operand stack remove(1); }
public static void loadReference(String name, WriterController controller) { CompileStack compileStack = controller.getCompileStack(); MethodVisitor mv = controller.getMethodVisitor(); ClassNode classNode = controller.getClassNode(); AsmClassGenerator acg = controller.getAcg(); // compileStack.containsVariable(name) means to ask if the variable is already declared // compileStack.getScope().isReferencedClassVariable(name) means to ask if the variable is a // field // If it is no field and is not yet declared, then it is either a closure shared variable or // an already declared variable. if (!compileStack.containsVariable(name) && compileStack.getScope().isReferencedClassVariable(name)) { acg.visitFieldExpression(new FieldExpression(classNode.getDeclaredField(name))); } else { BytecodeVariable v = compileStack.getVariable(name, !classNodeUsesReferences(controller.getClassNode())); if (v == null) { // variable is not on stack because we are // inside a nested Closure and this variable // was not used before // then load it from the Closure field FieldNode field = classNode.getDeclaredField(name); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( GETFIELD, controller.getInternalClassName(), name, BytecodeHelper.getTypeDescription(field.getType())); } else { mv.visitVarInsn(ALOAD, v.getIndex()); } controller.getOperandStack().push(ClassHelper.REFERENCE_TYPE); } }
public void loadOrStoreVariable(BytecodeVariable variable, boolean useReferenceDirectly) { CompileStack compileStack = controller.getCompileStack(); if (compileStack.isLHS()) { storeVar(variable); } else { MethodVisitor mv = controller.getMethodVisitor(); int idx = variable.getIndex(); ClassNode type = variable.getType(); if (variable.isHolder()) { mv.visitVarInsn(ALOAD, idx); if (!useReferenceDirectly) { mv.visitMethodInsn( INVOKEVIRTUAL, "groovy/lang/Reference", "get", "()Ljava/lang/Object;", false); BytecodeHelper.doCast(mv, type); push(type); } else { push(ClassHelper.REFERENCE_TYPE); } } else { load(type, idx); } } }