Examples of SkinnyMethodAdapter


Examples of org.jruby.compiler.impl.SkinnyMethodAdapter

        throw new RuntimeException("Unsupported method signature for dynamic call: " + site.type());
    }
   
    public static void installBytecode(MethodVisitor method, String classname) {
        SkinnyMethodAdapter clinitMethod = new SkinnyMethodAdapter(method);
        clinitMethod.ldc(c(classname));
        clinitMethod.invokestatic(p(Class.class), "forName", sig(Class.class, params(String.class)));
        clinitMethod.ldc(Type.getType(InvokeDynamicSupport.class));
        clinitMethod.ldc("bootstrap");
        clinitMethod.getstatic(p(Linkage.class), "BOOTSTRAP_METHOD_TYPE", ci(MethodType.class));
        clinitMethod.invokestatic(p(MethodHandles.class), "findStatic", sig(MethodHandle.class, Class.class, String.class, MethodType.class));
        clinitMethod.invokestatic(p(Linkage.class), "registerBootstrapMethod", sig(void.class, Class.class, MethodHandle.class));
    }
View Full Code Here

Examples of org.jruby.compiler.impl.SkinnyMethodAdapter

       
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
        cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, classname, null, p(Object.class), new String[] {p(Unsafe.class)});
        cw.visitSource("<generated>", null);
       
        SkinnyMethodAdapter method = new SkinnyMethodAdapter(cw.visitMethod(ACC_PUBLIC, "<init>", sig(void.class), null, null));
        method.start();
        method.aload(0);
        method.invokespecial(p(Object.class), "<init>", sig(void.class));
        method.voidreturn();
        method.end();
       
        method = new SkinnyMethodAdapter(cw.visitMethod(ACC_PUBLIC, "throwException", sig(void.class, Throwable.class), null, null));
        method.start();
        method.aload(1);
        method.athrow();
        method.end();
       
        cw.visitEnd();
       
        byte[] bytecode = cw.toByteArray();
       
View Full Code Here

Examples of org.jruby.compiler.impl.SkinnyMethodAdapter

        cw.visitField(ACC_STATIC | ACC_PRIVATE, "ruby", ci(Ruby.class), null, null).visitEnd();
        cw.visitField(ACC_STATIC | ACC_PRIVATE, "rubyClass", ci(RubyClass.class), null, null).visitEnd();
        cw.visitField(ACC_PRIVATE | ACC_FINAL, "self", ci(IRubyObject.class), null, null).visitEnd();
       
        // create constructor
        SkinnyMethodAdapter initMethod = new SkinnyMethodAdapter(cw.visitMethod(ACC_PUBLIC, "<init>", sig(void.class), null, null));
        initMethod.aload(0);
        initMethod.invokespecial(p(Object.class), "<init>", sig(void.class));
       
        // wrap self and store the wrapper
        initMethod.aload(0);
        initMethod.getstatic(name, "ruby", ci(Ruby.class));
        initMethod.aload(0);
        initMethod.invokestatic(p(MiniJava.class), "javaToRuby", sig(IRubyObject.class, Ruby.class, Object.class));
        initMethod.putfield(name, "self", ci(IRubyObject.class));
       
        // end constructor
        initMethod.voidreturn();
        initMethod.end();
       
        // start setup method
        SkinnyMethodAdapter setupMethod = new SkinnyMethodAdapter(cw.visitMethod(ACC_STATIC | ACC_PUBLIC | ACC_SYNTHETIC, "__setup__", sig(void.class, RubyClass.class), null, null));
        setupMethod.start();
       
        // set RubyClass
        setupMethod.aload(0);
        setupMethod.dup();
        setupMethod.putstatic(name, "rubyClass", ci(RubyClass.class));
       
        // set Ruby
        setupMethod.invokevirtual(p(RubyClass.class), "getClassRuntime", sig(Ruby.class));
        setupMethod.putstatic(name, "ruby", ci(Ruby.class));
       
        // for each simple method name, implement the complex methods, calling the simple version
        for (Map.Entry<String, List<Method>> entry : simpleToAll.entrySet()) {
            String simpleName = entry.getKey();
           
            // all methods dispatch to the simple version by default, which is method_missing normally
            cw.visitField(ACC_STATIC | ACC_PUBLIC | ACC_VOLATILE, simpleName, ci(DynamicMethod.class), null, null).visitEnd();
           
            for (Method method : entry.getValue()) {
                Class[] paramTypes = method.getParameterTypes();
                Class returnType = method.getReturnType();
               
                SkinnyMethodAdapter mv = new SkinnyMethodAdapter(
                        cw.visitMethod(ACC_PUBLIC, simpleName, sig(returnType, paramTypes), null, null));
                mv.start();

                String fieldName = mangleMethodFieldName(simpleName, paramTypes);
               
                // try specific name first, falling back on simple name
                Label dispatch = new Label();
                cw.visitField(ACC_STATIC | ACC_PUBLIC | ACC_VOLATILE, fieldName, ci(DynamicMethod.class), null, null).visitEnd();
                mv.getstatic(name, fieldName, ci(DynamicMethod.class));
                mv.dup();
                mv.ifnonnull(dispatch);
                mv.pop();
                mv.getstatic(name, simpleName, ci(DynamicMethod.class));
                mv.dup();
                mv.ifnonnull(dispatch);
                mv.pop();
                mv.getstatic(name, "rubyClass", ci(RubyClass.class));
                mv.ldc("method_missing");
                mv.invokevirtual(p(RubyClass.class), "searchMethod", sig(DynamicMethod.class, String.class));
                mv.label(dispatch);
               
                // get current context
                mv.getstatic(name, "ruby", ci(Ruby.class));
                mv.invokevirtual(p(Ruby.class), "getCurrentContext", sig(ThreadContext.class));
               
                // load self, class, and name
                mv.aload(0);
                mv.getfield(name, "self", ci(IRubyObject.class));
                mv.getstatic(name, "rubyClass", ci(RubyClass.class));
                mv.ldc(simpleName);
               
                // load arguments into IRubyObject[] for dispatch
                if (method.getParameterTypes().length != 0) {
                    mv.pushInt(method.getParameterTypes().length);
                    mv.anewarray(p(IRubyObject.class));
                   
                    for (int i = 0; i < paramTypes.length; i++) {
                        mv.dup();
                        mv.pushInt(i);
                        // convert to IRubyObject
                        mv.getstatic(name, "ruby", ci(Ruby.class));
                        mv.aload(i + 1);
                        mv.invokestatic(p(MiniJava.class), "javaToRuby", sig(IRubyObject.class, Ruby.class, Object.class));
                        mv.aastore();
                    }
                } else {
                    mv.getstatic(p(IRubyObject.class), "NULL_ARRAY", ci(IRubyObject[].class));
                }
               
                // load null block
                mv.getstatic(p(Block.class), "NULL_BLOCK", ci(Block.class));
               
                // invoke method
                mv.invokevirtual(p(DynamicMethod.class), "call", sig(IRubyObject.class, ThreadContext.class, IRubyObject.class, RubyModule.class, String.class, IRubyObject[].class, Block.class));
               
                // if we expect a return value, unwrap it
                if (method.getReturnType() != void.class) {
                    mv.invokestatic(p(MiniJava.class), "rubyToJava", sig(Object.class, IRubyObject.class));
                    mv.checkcast(p(returnType));

                    mv.areturn();
                } else {
                    mv.voidreturn();
                }

                mv.end();
            }
        }
       
        // end setup method
        setupMethod.voidreturn();
View Full Code Here

Examples of org.jruby.compiler.impl.SkinnyMethodAdapter

        cw.visitField(ACC_STATIC | ACC_PRIVATE, "ruby", ci(Ruby.class), null, null).visitEnd();
        cw.visitField(ACC_STATIC | ACC_PRIVATE, "rubyClass", ci(RubyClass.class), null, null).visitEnd();
        cw.visitField(ACC_PRIVATE | ACC_FINAL, "self", ci(IRubyObject.class), null, null).visitEnd();
       
        // create constructor
        SkinnyMethodAdapter initMethod = new SkinnyMethodAdapter(cw.visitMethod(ACC_PUBLIC, "<init>", sig(void.class, IRubyObject.class), null, null));
        initMethod.aload(0);
        initMethod.invokespecial(p(Object.class), "<init>", sig(void.class));
       
        // store the wrapper
        initMethod.aload(0);
        initMethod.aload(1);
        initMethod.putfield(pathName, "self", ci(IRubyObject.class));
       
        // end constructor
        initMethod.voidreturn();
        initMethod.end();
       
        // start setup method
        SkinnyMethodAdapter setupMethod = new SkinnyMethodAdapter(cw.visitMethod(ACC_STATIC | ACC_PUBLIC | ACC_SYNTHETIC, "__setup__", sig(void.class, RubyClass.class), null, null));
        setupMethod.start();
       
        // set RubyClass
        setupMethod.aload(0);
        setupMethod.dup();
        setupMethod.putstatic(pathName, "rubyClass", ci(RubyClass.class));
       
        // set Ruby
        setupMethod.invokevirtual(p(RubyClass.class), "getClassRuntime", sig(Ruby.class));
        setupMethod.putstatic(pathName, "ruby", ci(Ruby.class));
       
        // for each simple method name, implement the complex methods, calling the simple version
        for (Map.Entry<String, List<Method>> entry : simpleToAll.entrySet()) {
            String simpleName = entry.getKey();
            Set<String> nameSet = JavaUtil.getRubyNamesForJavaName(simpleName, entry.getValue());
               
            // all methods dispatch to the simple version by default, or method_missing if it's not present
            cw.visitField(ACC_STATIC | ACC_PUBLIC | ACC_VOLATILE, simpleName, ci(DynamicMethod.class), null, null).visitEnd();
           
            for (Method method : entry.getValue()) {
                Class[] paramTypes = method.getParameterTypes();
                Class returnType = method.getReturnType();
               
                SkinnyMethodAdapter mv = new SkinnyMethodAdapter(
                        cw.visitMethod(ACC_PUBLIC, simpleName, sig(returnType, paramTypes), null, null));
                mv.start();
               
                // TODO: this code should really check if a Ruby equals method is implemented or not.
                if(simpleName.equals("equals") && paramTypes.length == 1 && paramTypes[0] == Object.class && returnType == Boolean.TYPE) {
                    mv.aload(0);
                    mv.aload(1);
                    mv.invokespecial(p(Object.class), "equals", sig(Boolean.TYPE, params(Object.class)));
                    mv.ireturn();
                } else if(simpleName.equals("hashCode") && paramTypes.length == 0 && returnType == Integer.TYPE) {
                    mv.aload(0);
                    mv.invokespecial(p(Object.class), "hashCode", sig(Integer.TYPE));
                    mv.ireturn();
                } else if(simpleName.equals("toString") && paramTypes.length == 0 && returnType == String.class) {
                    mv.aload(0);
                    mv.invokespecial(p(Object.class), "toString", sig(String.class));
                    mv.areturn();
                } else {
                    Label dispatch = new Label();
                    Label end = new Label();
                    Label recheckMethod = new Label();

                    // Try to look up field for simple name

                    // get field; if nonnull, go straight to dispatch
                    mv.getstatic(pathName, simpleName, ci(DynamicMethod.class));
                    mv.dup();
                    mv.ifnonnull(dispatch);

                    // field is null, lock class and try to populate
                    mv.pop();
                    mv.getstatic(pathName, "rubyClass", ci(RubyClass.class));
                    mv.monitorenter();

                    // try/finally block to ensure unlock
                    Label tryStart = new Label();
                    Label tryEnd = new Label();
                    Label finallyStart = new Label();
                    Label finallyEnd = new Label();
                    mv.label(tryStart);

                    mv.aload(0);
                    mv.getfield(pathName, "self", ci(IRubyObject.class));
                    for (String eachName : nameSet) {
                        mv.ldc(eachName);
                    }
                    mv.invokestatic(p(MiniJava.class), "searchMethod", sig(DynamicMethod.class, params(IRubyObject.class, String.class, nameSet.size())));
                    mv.dup();
               
                    // if it's not undefined...
                    mv.getstatic(p(UndefinedMethod.class), "INSTANCE", ci(UndefinedMethod.class));
                    Label noStore = new Label();
                    mv.if_acmpeq(noStore);

                    // store it
                    mv.dup();
                    mv.putstatic(pathName, simpleName, ci(DynamicMethod.class));

                    // all done with lookup attempts, pop any result and release monitor
                    mv.label(noStore);
                    mv.pop();
                    mv.getstatic(pathName, "rubyClass", ci(RubyClass.class));
                    mv.monitorexit();
                    mv.go_to(recheckMethod);

                    // end of try block
                    mv.label(tryEnd);

                    // finally block to release monitor
                    mv.label(finallyStart);
                    mv.getstatic(pathName, "rubyClass", ci(RubyClass.class));
                    mv.monitorexit();
                    mv.label(finallyEnd);
                    mv.athrow();

                    // exception handling for monitor release
                    mv.trycatch(tryStart, tryEnd, finallyStart, null);
                    mv.trycatch(finallyStart, finallyEnd, finallyStart, null);

                    // re-get, re-check method; if not null now, go to dispatch
                    mv.label(recheckMethod);
                    mv.getstatic(pathName, simpleName, ci(DynamicMethod.class));
                    mv.dup();
                    mv.ifnonnull(dispatch);

                    // method still not available, call method_missing
                    mv.pop();
                    // exit monitor before making call
                    // FIXME: this not being in a finally is a little worrisome
                    mv.aload(0);
                    mv.getfield(pathName, "self", ci(IRubyObject.class));
                    mv.ldc(simpleName);
                    coerceArgumentsToRuby(mv, paramTypes, pathName);
                    mv.invokestatic(p(RuntimeHelpers.class), "invokeMethodMissing", sig(IRubyObject.class, IRubyObject.class, String.class, IRubyObject[].class));
                    mv.go_to(end);
               
                    // perform the dispatch
                    mv.label(dispatch);
                    // get current context
                    mv.getstatic(pathName, "ruby", ci(Ruby.class));
                    mv.invokevirtual(p(Ruby.class), "getCurrentContext", sig(ThreadContext.class));
               
                    // load self, class, and name
                    mv.aload(0);
                    mv.getfield(pathName, "self", ci(IRubyObject.class));
                    mv.getstatic(pathName, "rubyClass", ci(RubyClass.class));
                    mv.ldc(simpleName);
               
                    // coerce arguments
                    coerceArgumentsToRuby(mv, paramTypes, pathName);
               
                    // load null block
                    mv.getstatic(p(Block.class), "NULL_BLOCK", ci(Block.class));
               
                    // invoke method
                    mv.invokevirtual(p(DynamicMethod.class), "call", sig(IRubyObject.class, ThreadContext.class, IRubyObject.class, RubyModule.class, String.class, IRubyObject[].class, Block.class));
               
                    mv.label(end);
                    coerceResultAndReturn(method, mv, returnType);
                }               
                mv.end();
            }
        }
       
        // end setup method
        setupMethod.voidreturn();
View Full Code Here

Examples of org.jruby.compiler.impl.SkinnyMethodAdapter

            return (Handle)existing.newInstance();
        } catch (Exception e) {
        }
        cv.visit(ACC_PUBLIC | ACC_FINAL | ACC_SUPER, V1_5, name, null, p(Handle.class), null);
       
        SkinnyMethodAdapter m;
        String signature;
        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:
            signature = sig(Object.class, Object.class, Object[].class);
            break;
        }
        m = new SkinnyMethodAdapter(cv.visitMethod(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.aload(1);
        } else if (returnType.isPrimitive()) {
            Class boxType = getBoxType(returnType);
            m.invokestatic(p(boxType), "valueOf", sig(boxType, returnType));
        }
        m.areturn();
        m.end();
       
        // constructor
        m = new SkinnyMethodAdapter(cv.visitMethod(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();
       
        if (debug) {
            ((ASMifierClassVisitor)cv).print(new PrintWriter(System.out));
View Full Code Here

Examples of org.jruby.compiler.impl.SkinnyMethodAdapter

    private ClassWriter createBlockCtor(String namePath) throws Exception {
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        cw.visit(V1_4, ACC_PUBLIC + ACC_SUPER, namePath, null, p(AbstractCompiledBlockCallback.class), null);
        cw.visitField(ACC_PRIVATE | ACC_FINAL, "$scriptObject", ci(Object.class), null, null);
        SkinnyMethodAdapter mv = new SkinnyMethodAdapter(cw.visitMethod(ACC_PUBLIC, "<init>", sig(Void.TYPE, params(Object.class)), null, null));
        mv.start();
        mv.aload(0);
        mv.aload(1);
        mv.invokespecial(p(AbstractCompiledBlockCallback.class), "<init>", sig(void.class, Object.class));
        mv.voidreturn();
        mv.end();
       
        return cw;
    }
View Full Code Here

Examples of org.jruby.compiler.impl.SkinnyMethodAdapter

        mv.visitTypeInsn(CHECKCAST, IRUB);
        return mv;
    }

    private SkinnyMethodAdapter startBlockCall(ClassWriter cw) {
        SkinnyMethodAdapter mv = new SkinnyMethodAdapter(cw.visitMethod(ACC_PUBLIC | ACC_SYNTHETIC | ACC_FINAL, "call", BLOCK_CALL_SIG, null, null));
       
        mv.visitCode();
        Label line = new Label();
        mv.visitLineNumber(0, line);
        return mv;
    }
View Full Code Here

Examples of org.jruby.compiler.impl.SkinnyMethodAdapter

        synchronized (classLoader) {
            Class c = tryClass(mname);
            try {
                if (c == null) {
                    ClassWriter cw = createBlockCtor(mnamePath);
                    SkinnyMethodAdapter mv = startBlockCall(cw);
                    mv.aload(0);
                    mv.getfield(p(AbstractCompiledBlockCallback.class), "$scriptObject", ci(Object.class));
                    mv.checkcast(p(typeClass));
                    mv.aload(1);
                    mv.aload(2);
                    mv.aload(3);
                    mv.invokevirtual(typePathString, method, sig(
                            RubyKernel.IRUBY_OBJECT, params(ThreadContext.class,
                                    RubyKernel.IRUBY_OBJECT, IRubyObject.class)));
                    mv.areturn();
                   
                    mv.visitMaxs(2, 3);
                    c = endCall(cw, mv, mname);
                }
                CompiledBlockCallback ic = (CompiledBlockCallback) c.getConstructor(Object.class).newInstance(scriptObject);
                return ic;
            } catch (IllegalArgumentException e) {
View Full Code Here

Examples of org.jruby.compiler.impl.SkinnyMethodAdapter

            try {
                if (generatedClass == null) {
                    String typePath = p(scriptClass);
                    String mnamePath = typePath + "Invoker" + method + arity;
                    ClassWriter cw = createCompiledCtor(mnamePath,sup);
                    SkinnyMethodAdapter mv = null;
                    String signature = null;
                    boolean specificArity = false;
                   
                    if (scope.getRestArg() >= 0 || scope.getOptionalArgs() > 0 || scope.getRequiredArgs() > 3) {
                        signature = COMPILED_CALL_SIG_BLOCK;
                        mv = new SkinnyMethodAdapter(cw.visitMethod(ACC_PUBLIC, "call", signature, null, null));
                    } else {
                        specificArity = true;
                       
                        mv = new SkinnyMethodAdapter(cw.visitMethod(ACC_PUBLIC, "call", COMPILED_CALL_SIG_BLOCK, null, null));
                        mv.start();
                       
                        // check arity
                        mv.aload(1);
                        mv.invokevirtual(p(ThreadContext.class), "getRuntime", sig(Ruby.class));
                        mv.aload(5);
                        mv.pushInt(scope.getRequiredArgs());
                        mv.pushInt(scope.getRequiredArgs());
                        mv.invokestatic(p(Arity.class), "checkArgumentCount", sig(int.class, Ruby.class, IRubyObject[].class, int.class, int.class));
                        mv.pop();
                       
                        mv.aload(0);
                        mv.aload(1);
                        mv.aload(2);
                        mv.aload(3);
                        mv.aload(4);
                        for (int i = 0; i < scope.getRequiredArgs(); i++) {
                            mv.aload(5);
                            mv.ldc(i);
                            mv.arrayload();
                        }
                        mv.aload(6);

                        switch (scope.getRequiredArgs()) {
                        case 0:
                            signature = COMPILED_CALL_SIG_ZERO_BLOCK;
                            break;
                        case 1:
                            signature = COMPILED_CALL_SIG_ONE_BLOCK;
                            break;
                        case 2:
                            signature = COMPILED_CALL_SIG_TWO_BLOCK;
                            break;
                        case 3:
                            signature = COMPILED_CALL_SIG_THREE_BLOCK;
                            break;
                        }
                       
                        mv.invokevirtual(mnamePath, "call", signature);
                        mv.areturn();
                        mv.end();
                       
                        mv = new SkinnyMethodAdapter(cw.visitMethod(ACC_PUBLIC, "call", signature, null, null));
                    }

                    mv.visitCode();
                    Label line = new Label();
                    mv.visitLineNumber(0, line);
                   
//                    // check arity
//                    checkArity(mv, scope);

                    // invoke pre method stuff
                    if (!callConfig.isNoop()) {
                        if (specificArity) {
                            invokeCallConfigPre(mv, COMPILED_SUPER_CLASS, scope.getRequiredArgs(), true, callConfig);
                        } else {
                            invokeCallConfigPre(mv, COMPILED_SUPER_CLASS, -1, true, callConfig);
                        }
                    }

                    Label tryBegin = new Label();
                    Label tryEnd = new Label();
                    Label doFinally = new Label();
                    Label doReturnFinally = new Label();
                    Label doRedoFinally = new Label();
                    Label catchReturnJump = new Label();
                    Label catchRedoJump = new Label();

                    if (callConfig != CallConfiguration.FRAME_AND_DUMMY_SCOPE) {
                        mv.trycatch(tryBegin, tryEnd, catchReturnJump, p(JumpException.ReturnJump.class));
                    }
                    mv.trycatch(tryBegin, tryEnd, catchRedoJump, p(JumpException.RedoJump.class));
                    mv.trycatch(tryBegin, tryEnd, doFinally, null);
                    if (callConfig != CallConfiguration.FRAME_AND_DUMMY_SCOPE) {
                        mv.trycatch(catchReturnJump, doReturnFinally, doFinally, null);
                    }
                    mv.trycatch(catchRedoJump, doRedoFinally, doFinally, null);
                    mv.label(tryBegin);
                    {
                        mv.aload(0);
                        // FIXME we want to eliminate these type casts when possible
                        mv.getfield(mnamePath, "$scriptObject", ci(Object.class));
                        mv.checkcast(typePath);
                        mv.aload(THREADCONTEXT_INDEX);
                        mv.aload(RECEIVER_INDEX);
                        if (specificArity) {
                            for (int i = 0; i < scope.getRequiredArgs(); i++) {
                                mv.aload(ARGS_INDEX + i);
                            }
                            mv.aload(ARGS_INDEX + scope.getRequiredArgs());
                            mv.invokevirtual(typePath, method, StandardASMCompiler.METHOD_SIGNATURES[scope.getRequiredArgs()]);
                        } else {
                            mv.aload(ARGS_INDEX);
                            mv.aload(BLOCK_INDEX);
                            mv.invokevirtual(typePath, method, StandardASMCompiler.METHOD_SIGNATURES[4]);
                        }
                    }
                    mv.label(tryEnd);
                   
                    // normal exit, perform finally and return
                    {
                        if (!callConfig.isNoop()) {
                            invokeCallConfigPost(mv, COMPILED_SUPER_CLASS, callConfig);
                        }
                        mv.visitInsn(ARETURN);
                    }

                    // return jump handling
                    if (callConfig != CallConfiguration.FRAME_AND_DUMMY_SCOPE) {
                        mv.label(catchReturnJump);
                        {
                            mv.aload(0);
                            mv.swap();
                            mv.aload(1);
                            mv.swap();
                            mv.invokevirtual(COMPILED_SUPER_CLASS, "handleReturn", sig(IRubyObject.class, ThreadContext.class, JumpException.ReturnJump.class));
                            mv.label(doReturnFinally);

                            // finally
                            if (!callConfig.isNoop()) {
                                invokeCallConfigPost(mv, COMPILED_SUPER_CLASS, callConfig);
                            }

                            // return result if we're still good
                            mv.areturn();
                        }
                    }

                    // redo jump handling
                    mv.label(catchRedoJump);
                    {
                        // clear the redo
                        mv.pop();
                       
                        // get runtime, create jump error, and throw it
                        mv.aload(1);
                        mv.invokevirtual(p(ThreadContext.class), "getRuntime", sig(Ruby.class));
                        mv.invokevirtual(p(Ruby.class), "newRedoLocalJumpError", sig(RaiseException.class));
                        mv.label(doRedoFinally);
                       
                        // finally
                        if (!callConfig.isNoop()) {
                            invokeCallConfigPost(mv, COMPILED_SUPER_CLASS, callConfig);
                        }
                       
                        // throw redo error if we're still good
                        mv.athrow();
                    }

                    // finally handling for abnormal exit
                    {
                        mv.label(doFinally);

                        //call post method stuff (exception raised)
                        if (!callConfig.isNoop()) {
                            invokeCallConfigPost(mv, COMPILED_SUPER_CLASS, callConfig);
                        }

                        // rethrow exception
                        mv.athrow(); // rethrow it
                    }

                    generatedClass = endCall(cw,mv,mname);
                }
View Full Code Here

Examples of org.jruby.compiler.impl.SkinnyMethodAdapter

                            specificArity = desc.required;
                        }
                    }

                    boolean hasBlock = desc.hasBlock;
                    SkinnyMethodAdapter mv = null;

                    mv = beginMethod(cw, "call", specificArity, hasBlock);
                    mv.visitCode();
                    Label line = new Label();
                    mv.visitLineNumber(0, line);

                    createAnnotatedMethodInvocation(desc, mv, superClass, specificArity, hasBlock);

                    endMethod(mv);
                }
View Full Code Here
TOP
Copyright © 2018 www.massapi.com. 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.