Package org.jruby.compiler.impl

Examples of org.jruby.compiler.impl.SkinnyMethodAdapter


    }

    @Override
    public void BoxFixnumInstr(BoxFixnumInstr instr) {
        IRBytecodeAdapter   m = jvmMethod();
        SkinnyMethodAdapter a = m.adapter;

        // Load runtime
        m.loadContext();
        a.getfield(p(ThreadContext.class), "runtime", ci(Ruby.class));

        // Get unboxed fixnum
        loadFixnumArg(instr.getValue());

        // Box the fixnum
        a.invokevirtual(p(Ruby.class), "newFixnum", sig(RubyFixnum.class, long.class));

        // Store it
        jvmStoreLocal(instr.getResult());
    }
View Full Code Here


    }

    @Override
    public void BoxBooleanInstr(BoxBooleanInstr instr) {
        IRBytecodeAdapter   m = jvmMethod();
        SkinnyMethodAdapter a = m.adapter;

        // Load runtime
        m.loadContext();
        a.getfield(p(ThreadContext.class), "runtime", ci(Ruby.class));

        // Get unboxed boolean
        loadBooleanArg(instr.getValue());

        // Box the fixnum
        a.invokevirtual(p(Ruby.class), "newBoolean", sig(RubyBoolean.class, boolean.class));

        // Store it
        jvmStoreLocal(instr.getResult());
    }
View Full Code Here

        jvmStoreLocal(instr.getResult());
    }

    public void AluInstr(AluInstr instr) {
        IRBytecodeAdapter   m = jvmMethod();
        SkinnyMethodAdapter a = m.adapter;

        // Load args
        visit(instr.getArg1());
        visit(instr.getArg2());

        // Compute result
        switch (instr.getOperation()) {
            case FADD: a.dadd(); break;
            case FSUB: a.dsub(); break;
            case FMUL: a.dmul(); break;
            case FDIV: a.ddiv(); break;
            case FLT: m.invokeIRHelper("flt", sig(boolean.class, double.class, double.class)); break; // annoying to have to do it in a method
            case FGT: m.invokeIRHelper("fgt", sig(boolean.class, double.class, double.class)); break; // annoying to have to do it in a method
            case FEQ: m.invokeIRHelper("feq", sig(boolean.class, double.class, double.class)); break; // annoying to have to do it in a method
            case IADD: a.ladd(); break;
            case ISUB: a.lsub(); break;
            case IMUL: a.lmul(); break;
            case IDIV: a.ldiv(); break;
            case ILT: m.invokeIRHelper("ilt", sig(boolean.class, long.class, long.class)); break; // annoying to have to do it in a method
            case IGT: m.invokeIRHelper("igt", sig(boolean.class, long.class, long.class)); break; // annoying to have to do it in a method
            case IOR: a.lor(); break;
            case IAND: a.land(); break;
            case IXOR: a.lxor(); break;
            case ISHL: a.lshl(); break;
            case ISHR: a.lshr(); break;
            case IEQ: m.invokeIRHelper("ilt", sig(boolean.class, long.class, long.class)); break; // annoying to have to do it in a method
            default: throw new NotCompilableException("UNHANDLED!");
        }

        // Store it
View Full Code Here

    }

    @Override
    public void BuildDynRegExpInstr(BuildDynRegExpInstr instr) {
        final IRBytecodeAdapter m = jvmMethod();
        SkinnyMethodAdapter a = m.adapter;

        RegexpOptions options = instr.getOptions();
        final List<Operand> operands = instr.getPieces();

        Runnable r = new Runnable() {
View Full Code Here

    @Override
    public void DefineInstanceMethodInstr(DefineInstanceMethodInstr defineinstancemethodinstr) {
        IRMethod method = defineinstancemethodinstr.getMethod();

        IRBytecodeAdapter   m = jvmMethod();
        SkinnyMethodAdapter a = m.adapter;

        m.loadContext();

        emitMethod(method);
        Map<Integer, MethodType> signatures = method.getNativeSignatures();

        MethodType variable = signatures.get(-1); // always a variable arity handle

        String defSignature = pushHandlesForDef(
                method.getJittedName(),
                signatures,
                variable,
                sig(void.class, ThreadContext.class, java.lang.invoke.MethodHandle.class, IRScope.class, DynamicScope.class, IRubyObject.class),
                sig(void.class, ThreadContext.class, java.lang.invoke.MethodHandle.class, java.lang.invoke.MethodHandle.class, int.class, IRScope.class, DynamicScope.class, IRubyObject.class));

        a.getstatic(jvm.clsData().clsName, method.getJittedName() + "_IRScope", ci(IRScope.class));
        jvmLoadLocal(DYNAMIC_SCOPE);
        jvmMethod().loadSelf();

        // add method
        a.invokestatic(p(IRRuntimeHelpers.class), "defCompiledInstanceMethod", defSignature);
    }
View Full Code Here

        // fields to hold Ruby and RubyClass references
        cw.visitField(ACC_STATIC | ACC_PRIVATE, "ruby", ci(Ruby.class), null, null);
        cw.visitField(ACC_STATIC | ACC_PRIVATE, "rubyClass", ci(RubyClass.class), null, null);

        // static initializing method
        SkinnyMethodAdapter m = new SkinnyMethodAdapter(cw, ACC_PUBLIC | ACC_STATIC, "clinit", sig(void.class, Ruby.class, RubyClass.class), null, null);
        m.start();
        m.aload(0);
        m.putstatic(javaPath, "ruby", ci(Ruby.class));
        m.aload(1);
        m.putstatic(javaPath, "rubyClass", ci(RubyClass.class));
        m.voidreturn();
        m.end();

        // standard constructor that accepts Ruby, RubyClass
        m = new SkinnyMethodAdapter(cw, ACC_PUBLIC, "<init>", sig(void.class, Ruby.class, RubyClass.class), null, null);
        m.aload(0);
        m.aload(1);
        m.aload(2);
        m.invokespecial(p(reifiedParent), "<init>", sig(void.class, Ruby.class, RubyClass.class));
        m.voidreturn();
        m.end();

        // no-arg constructor using static references to Ruby and RubyClass
        m = new SkinnyMethodAdapter(cw, ACC_PUBLIC, "<init>", CodegenUtils.sig(void.class), null, null);
        m.aload(0);
        m.getstatic(javaPath, "ruby", ci(Ruby.class));
        m.getstatic(javaPath, "rubyClass", ci(RubyClass.class));
        m.invokespecial(p(reifiedParent), "<init>", sig(void.class, Ruby.class, RubyClass.class));
        m.voidreturn();
        m.end();

        // define fields
        for (Map.Entry<String, Class> fieldSignature : getFieldSignatures().entrySet()) {
            String fieldName = fieldSignature.getKey();
            Class type = fieldSignature.getValue();
            Map<Class, Map<String, Object>> fieldAnnos = getFieldAnnotations().get(fieldName);

            FieldVisitor fieldVisitor = cw.visitField(ACC_PUBLIC, fieldName, ci(type), null, null);

            if (fieldAnnos == null) {
              continue;
            }

            for (Map.Entry<Class, Map<String, Object>> fieldAnno : fieldAnnos.entrySet()) {
                Class annoType = fieldAnno.getKey();
                AnnotationVisitor av = fieldVisitor.visitAnnotation(ci(annoType), true);
                CodegenUtils.visitAnnotationFields(av, fieldAnno.getValue());
            }
            fieldVisitor.visitEnd();
        }

        // gather a list of instance methods, so we don't accidentally make static ones that conflict
        Set<String> instanceMethods = new HashSet<String>();

        // define instance methods
        for (Map.Entry<String,DynamicMethod> methodEntry : getMethods().entrySet()) {
            String methodName = methodEntry.getKey();

            if (!JavaNameMangler.willMethodMangleOk(methodName)) continue;

            String javaMethodName = JavaNameMangler.mangleMethodName(methodName);

            Map<Class,Map<String,Object>> methodAnnos = getMethodAnnotations().get(methodName);
            List<Map<Class,Map<String,Object>>> parameterAnnos = getParameterAnnotations().get(methodName);
            Class[] methodSignature = getMethodSignatures().get(methodName);

            String signature;
            if (methodSignature == null) {
                // non-signature signature with just IRubyObject
                switch (methodEntry.getValue().getArity().getValue()) {
                case 0:
                    signature = sig(IRubyObject.class);
                    m = new SkinnyMethodAdapter(cw, ACC_PUBLIC | ACC_VARARGS, javaMethodName, signature, null, null);
                    generateMethodAnnotations(methodAnnos, m, parameterAnnos);

                    m.aload(0);
                    m.ldc(methodName);
                    m.invokevirtual(javaPath, "callMethod", sig(IRubyObject.class, String.class));
                    break;
                default:
                    signature = sig(IRubyObject.class, IRubyObject[].class);
                    m = new SkinnyMethodAdapter(cw, ACC_PUBLIC | ACC_VARARGS, javaMethodName, signature, null, null);
                    generateMethodAnnotations(methodAnnos, m, parameterAnnos);

                    m.aload(0);
                    m.ldc(methodName);
                    m.aload(1);
                    m.invokevirtual(javaPath, "callMethod", sig(IRubyObject.class, String.class, IRubyObject[].class));
                }
                m.areturn();
            } else {
                // generate a real method signature for the method, with to/from coercions

                // indices for temp values
                Class[] params = new Class[methodSignature.length - 1];
                System.arraycopy(methodSignature, 1, params, 0, params.length);
                int baseIndex = 1;
                for (Class paramType : params) {
                    if (paramType == double.class || paramType == long.class) {
                        baseIndex += 2;
                    } else {
                        baseIndex += 1;
                    }
                }
                int rubyIndex = baseIndex;

                signature = sig(methodSignature[0], params);
                m = new SkinnyMethodAdapter(cw, ACC_PUBLIC | ACC_VARARGS, javaMethodName, signature, null, null);
                generateMethodAnnotations(methodAnnos, m, parameterAnnos);

                m.getstatic(javaPath, "ruby", ci(Ruby.class));
                m.astore(rubyIndex);

                m.aload(0); // self
                m.ldc(methodName); // method name
                RealClassGenerator.coerceArgumentsToRuby(m, params, rubyIndex);
                m.invokevirtual(javaPath, "callMethod", sig(IRubyObject.class, String.class, IRubyObject[].class));

                RealClassGenerator.coerceResultAndReturn(m, methodSignature[0]);
            }

            if (DEBUG_REIFY) LOG.debug("defining {}#{} as {}#{}", getName(), methodName, javaName, javaMethodName + signature);

            instanceMethods.add(javaMethodName + signature);

            m.end();
        }

        // define class/static methods
        for (Map.Entry<String,DynamicMethod> methodEntry : getMetaClass().getMethods().entrySet()) {
            String methodName = methodEntry.getKey();

            if (!JavaNameMangler.willMethodMangleOk(methodName)) continue;

            String javaMethodName = JavaNameMangler.mangleMethodName(methodName);

            Map<Class,Map<String,Object>> methodAnnos = getMetaClass().getMethodAnnotations().get(methodName);
            List<Map<Class,Map<String,Object>>> parameterAnnos = getMetaClass().getParameterAnnotations().get(methodName);
            Class[] methodSignature = getMetaClass().getMethodSignatures().get(methodName);

            String signature;
            if (methodSignature == null) {
                // non-signature signature with just IRubyObject
                switch (methodEntry.getValue().getArity().getValue()) {
                case 0:
                    signature = sig(IRubyObject.class);
                    if (instanceMethods.contains(javaMethodName + signature)) continue;
                    m = new SkinnyMethodAdapter(cw, ACC_PUBLIC | ACC_VARARGS | ACC_STATIC, javaMethodName, signature, null, null);
                    generateMethodAnnotations(methodAnnos, m, parameterAnnos);

                    m.getstatic(javaPath, "rubyClass", ci(RubyClass.class));
                    //m.invokevirtual("org/jruby/RubyClass", "getMetaClass", sig(RubyClass.class) );
                    m.ldc(methodName); // Method name
                    m.invokevirtual("org/jruby/RubyClass", "callMethod", sig(IRubyObject.class, String.class) );
                    break;
                default:
                    signature = sig(IRubyObject.class, IRubyObject[].class);
                    if (instanceMethods.contains(javaMethodName + signature)) continue;
                    m = new SkinnyMethodAdapter(cw, ACC_PUBLIC | ACC_VARARGS | ACC_STATIC, javaMethodName, signature, null, null);
                    generateMethodAnnotations(methodAnnos, m, parameterAnnos);

                    m.getstatic(javaPath, "rubyClass", ci(RubyClass.class));
                    m.ldc(methodName); // Method name
                    m.aload(0);
                    m.invokevirtual("org/jruby/RubyClass", "callMethod", sig(IRubyObject.class, String.class, IRubyObject[].class) );
                }
                m.areturn();
            } else {
                // generate a real method signature for the method, with to/from coercions

                // indices for temp values
                Class[] params = new Class[methodSignature.length - 1];
                System.arraycopy(methodSignature, 1, params, 0, params.length);
                int baseIndex = 0;
                for (Class paramType : params) {
                    if (paramType == double.class || paramType == long.class) {
                        baseIndex += 2;
                    } else {
                        baseIndex += 1;
                    }
                }
                int rubyIndex = baseIndex;

                signature = sig(methodSignature[0], params);
                if (instanceMethods.contains(javaMethodName + signature)) continue;
                m = new SkinnyMethodAdapter(cw, ACC_PUBLIC | ACC_VARARGS | ACC_STATIC, javaMethodName, signature, null, null);
                generateMethodAnnotations(methodAnnos, m, parameterAnnos);

                m.getstatic(javaPath, "ruby", ci(Ruby.class));
                m.astore(rubyIndex);

                m.getstatic(javaPath, "rubyClass", ci(RubyClass.class));
               
                m.ldc(methodName); // method name
                RealClassGenerator.coerceArgumentsToRuby(m, params, rubyIndex);
                m.invokevirtual("org/jruby/RubyClass", "callMethod", sig(IRubyObject.class, String.class, IRubyObject[].class));

                RealClassGenerator.coerceResultAndReturn(m, methodSignature[0]);
            }

            if (DEBUG_REIFY) LOG.debug("defining {}.{} as {}.{}", getName(), methodName, javaName, javaMethodName + signature);

            m.end();
        }


        cw.visitEnd();
        byte[] classBytes = cw.toByteArray();
View Full Code Here

            Class[] signature = new Class[stub.getParameterTypes().length - 1];
            for (int i = 0; i < signature.length; i++) {
                signature[i] = stub.getParameterTypes()[i + 1];
            }
           
            SkinnyMethodAdapter method = new SkinnyMethodAdapter(
                    cv, Opcodes.ACC_PUBLIC | Opcodes.ACC_BRIDGE, stub.getName(), sig(stub.getReturnType(), signature), null, null);
            method.start();

            // load self
            method.aload(0);

            // load arguments
            int nextIndex = 1;
            for (Class argType : signature) {
                if (argType.isPrimitive()) {
                    if (argType == boolean.class ||
                            argType == byte.class ||
                            argType == char.class ||
                            argType == short.class ||
                            argType == int.class) {
                        method.iload(nextIndex);
                        nextIndex++;
                    } else if (argType == long.class) {
                        method.lload(nextIndex);
                        nextIndex += 2;
                    } else if (argType == float.class) {
                        method.fload(nextIndex);
                        nextIndex++;
                    } else if (argType == double.class) {
                        method.dload(nextIndex);
                        nextIndex += 2;
                    } else {
                        throw new RuntimeException("unknown primitive type: " + argType);
                    }
                } else {
                    method.aload(nextIndex);
                    nextIndex++;
                }
            }

            // invoke stub
            method.invokestatic(p(BasicObjectStub.class), stub.getName(), sig(stub.getReturnType(), stub.getParameterTypes()));

            Class retType = stub.getReturnType();
            if (retType == void.class) {
                method.voidreturn();
            } else {
                if (retType.isPrimitive()) {
                    if (retType == boolean.class ||
                            retType == byte.class ||
                            retType == char.class ||
                            retType == short.class ||
                            retType == int.class) {
                        method.ireturn();
                    } else if (retType == long.class) {
                        method.lreturn();
                    } else if (retType == float.class) {
                        method.freturn();
                    } else if (retType == double.class) {
                        method.dreturn();
                    } else {
                        throw new RuntimeException("unknown primitive type: " + retType);
                    }
                } else {
                    method.areturn();
                }
            }

            method.end();
        }
    }
View Full Code Here

        Class returnType = method.getReturnType();
        Class[] paramTypes = method.getParameterTypes();
        ClassVisitor cv = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        cv.visit(ACC_PUBLIC | ACC_FINAL | ACC_SUPER, V1_5, name, null, p(Handle.class), null);

        SkinnyMethodAdapter m;
        String signature;
        boolean needsArgsVersion = true;
        switch (paramTypes.length) {
        case 0:
            signature = sig(Object.class, Object.class);
            break;
        case 1:
            signature = sig(Object.class, Object.class, Object.class);
            break;
        case 2:
            signature = sig(Object.class, Object.class, Object.class, Object.class);
            break;
        case 3:
            signature = sig(Object.class, Object.class, Object.class, Object.class, Object.class);
            break;
//        case 4:
//            signature = sig(Object.class, Object.class, Object.class, Object.class, Object.class);
//            break;
//        case 5:
//            signature = sig(Object.class, Object.class, Object.class, Object.class, Object.class, Object.class);
//            break;
        default:
            needsArgsVersion = false;
            signature = sig(Object.class, Object.class, Object[].class);
            break;
        }
        m = new SkinnyMethodAdapter(cv, ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC, "invoke", signature, null, null);

        m.start();

        // load receiver
        if (!Modifier.isStatic(method.getModifiers())) {
            m.aload(1); // receiver
            if (method.getDeclaringClass() != Object.class) {
                m.checkcast(p(method.getDeclaringClass()));
            }
        }

        // load arguments
        switch (paramTypes.length) {
        case 0:
        case 1:
        case 2:
        case 3:
//        case 4:
//        case 5:
            for (int i = 0; i < paramTypes.length; i++) {
                loadUnboxedArgument(m, i + 2, paramTypes[i]);
            }
            break;
        default:
            for (int i = 0; i < paramTypes.length; i++) {
                m.aload(2); // Object[] args
                m.pushInt(i);
                m.aaload();
                Class paramClass = paramTypes[i];
                if (paramClass.isPrimitive()) {
                    Class boxType = getBoxType(paramClass);
                    m.checkcast(p(boxType));
                    m.invokevirtual(p(boxType), paramClass.toString() + "Value", sig(paramClass));
                } else if (paramClass != Object.class) {
                    m.checkcast(p(paramClass));
                }
            }
            break;
        }

        if (Modifier.isStatic(method.getModifiers())) {
            m.invokestatic(p(method.getDeclaringClass()), method.getName(), sig(returnType, paramTypes));
        } else if (Modifier.isInterface(method.getDeclaringClass().getModifiers())) {
            m.invokeinterface(p(method.getDeclaringClass()), method.getName(), sig(returnType, paramTypes));
        } else {
            m.invokevirtual(p(method.getDeclaringClass()), method.getName(), sig(returnType, paramTypes));
        }

        if (returnType == void.class) {
            m.aconst_null();
        } else if (returnType.isPrimitive()) {
            Class boxType = getBoxType(returnType);
            m.invokestatic(p(boxType), "valueOf", sig(boxType, returnType));
        }
        m.areturn();
        m.end();

        if (needsArgsVersion) {
            m = new SkinnyMethodAdapter(cv, ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC, "invoke", sig(Object.class, Object.class, Object[].class), null, null);

            m.start();

            // load handle
            m.aload(0);

            // load receiver
            m.aload(1);

            // load arguments
            for (int i = 0; i < paramTypes.length; i++) {
                m.aload(2); // args array
                m.ldc(i);
                m.aaload(); // i'th argument
            }

            // invoke specific arity version
            m.invokevirtual(name, "invoke", sig(Object.class, params(Object.class, Object.class, paramTypes.length)));

            // return result
            m.areturn();
            m.end();
        }

        // constructor
        m = new SkinnyMethodAdapter(cv, ACC_PUBLIC, "<init>", sig(void.class), null, null);
        m.start();
        m.aload(0);
        m.invokespecial(p(Handle.class), "<init>", sig(void.class));
        m.voidreturn();
        m.end();

        cv.visitEnd();

        byte[] bytes = ((ClassWriter)cv).toByteArray();
View Full Code Here

        params[0] = ThreadContext.class;
        params[1] = IRubyObject.class;
        params[2] = RubyModule.class;
        params[3] = String.class;
        Arrays.fill(params, 4, params.length, IRubyObject.class);
        SkinnyMethodAdapter mv = new SkinnyMethodAdapter(builder.getClassVisitor(),
                ACC_PUBLIC | ACC_FINAL, functionName,
                sig(IRubyObject.class, params),
                null, null);

        mv.start();
        generate(builder, mv, signature, 5);
        mv.visitMaxs(30, 30);
        mv.visitEnd();
    }
View Full Code Here

                p(parentClass), new String[0]);
    }
   
    Class<? extends NativeInvoker> build() {
        // Create the constructor to set the 'library' & functions fields
        SkinnyMethodAdapter init = new SkinnyMethodAdapter(classVisitor, ACC_PUBLIC, "<init>",
                sig(void.class, RubyModule.class, com.kenai.jffi.Function.class, Signature.class),
                null, null);
       
        init.start();

        // Invoker the superclass's constructor
        init.aload(0); // this
        init.aload(1); // implementationClass
        init.aload(2); // jffi function
        init.aload(3); // signature
        init.invokespecial(p(parentClass), "<init>",
                sig(void.class, RubyModule.class, com.kenai.jffi.Function.class, Signature.class));
        init.voidreturn();
        init.visitMaxs(10, 10);
        init.visitEnd();
       
        generator.generate(this, "call", signature);

        classVisitor.visitEnd();
View Full Code Here

TOP

Related Classes of org.jruby.compiler.impl.SkinnyMethodAdapter

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.