private void beginInit() { ClassVisitor cv = getClassVisitor(); initMethod = new SkinnyMethodAdapter(cv, ACC_PUBLIC, "<init>", sig(Void.TYPE), null, null); initMethod.start(); initMethod.aload(THIS); initMethod.invokespecial(p(AbstractScript.class), "<init>", sig(Void.TYPE)); // JRUBY-3014: make __FILE__ dynamically determined at load time, but // we provide a reasonable default here initMethod.aload(THIS); initMethod.ldc(getSourcename()); initMethod.putfield(getClassname(), "filename", ci(String.class)); }
public void endScript(boolean generateLoad, boolean generateMain) { // add Script#run impl, used for running this script with a specified threadcontext and self // root method of a script is always in __file__ method String methodName = "__file__"; String loadSig = sig(IRubyObject.class, ThreadContext.class, IRubyObject.class, boolean.class); if (generateLoad || generateMain) { // the load method is used for loading as a top-level script, and prepares appropriate scoping // around the code SkinnyMethodAdapter method = new SkinnyMethodAdapter(getClassVisitor(), ACC_PUBLIC, "load", loadSig, null, null); method.start(); // invoke __file__ with threadcontext, self, args (null), and block (null) Label tryBegin = new Label(); Label tryFinally = new Label(); method.label(tryBegin); method.aload(THREADCONTEXT_INDEX); String scopeNames = Helpers.encodeScope(topLevelScope); method.ldc(scopeNames); method.iload(SELF_INDEX + 1); method.invokestatic( p(Helpers.class), "preLoad", sig(StaticScope.class, ThreadContext.class, String.class, boolean.class)); // store root scope method.aload(THIS); method.swap(); method.invokevirtual( p(AbstractScript.class), "setRootScope", sig(void.class, StaticScope.class)); method.aload(THIS); method.aload(THREADCONTEXT_INDEX); method.aload(SELF_INDEX); method.getstatic(p(IRubyObject.class), "NULL_ARRAY", ci(IRubyObject[].class)); method.getstatic(p(Block.class), "NULL_BLOCK", ci(Block.class)); method.invokestatic(getClassname(), methodName, getStaticMethodSignature(getClassname(), 4)); method.aload(THREADCONTEXT_INDEX); method.invokestatic(p(Helpers.class), "postLoad", sig(void.class, ThreadContext.class)); method.areturn(); method.label(tryFinally); method.aload(THREADCONTEXT_INDEX); method.invokestatic(p(Helpers.class), "postLoad", sig(void.class, ThreadContext.class)); method.athrow(); method.trycatch(tryBegin, tryFinally, tryFinally, null); method.end(); } if (generateMain) { // add main impl, used for detached or command-line execution of this script with a new // runtime // root method of a script is always in stub0, method0 SkinnyMethodAdapter method = new SkinnyMethodAdapter( getClassVisitor(), ACC_PUBLIC | ACC_STATIC, "main", sig(Void.TYPE, params(String[].class)), null, null); method.start(); // init script filename to simple class name in case we don't assign it (null ClassLoader) method.ldc(getClassname().replaceAll("\\\\.", "/")); method.astore(1); // new instance to invoke run against method.newobj(getClassname()); method.dup(); method.invokespecial(getClassname(), "<init>", sig(Void.TYPE)); // guard against null classloader method.ldc(Type.getType("L" + getClassname() + ";")); method.invokevirtual(p(Class.class), "getClassLoader", sig(ClassLoader.class)); Label skip = new Label(); method.ifnull(skip); // set filename for the loaded script class (JRUBY-4825) method.dup(); method.ldc(Type.getType("L" + getClassname() + ";")); method.invokevirtual(p(Class.class), "getClassLoader", sig(ClassLoader.class)); method.ldc(getClassname() + ".class"); method.invokevirtual(p(ClassLoader.class), "getResource", sig(URL.class, String.class)); method.invokevirtual(p(Object.class), "toString", sig(String.class)); method.astore(1); method.aload(1); method.invokevirtual(p(AbstractScript.class), "setFilename", sig(void.class, String.class)); // ifnull ClassLoader method.label(skip); // instance config for the script run method.newobj(p(RubyInstanceConfig.class)); method.dup(); method.invokespecial(p(RubyInstanceConfig.class), "<init>", "()V"); // set argv from main's args method.dup(); method.aload(0); method.invokevirtual(p(RubyInstanceConfig.class), "setArgv", sig(void.class, String[].class)); // set script filename ($0) method.dup(); method.aload(1); method.invokevirtual( p(RubyInstanceConfig.class), "setScriptFileName", sig(void.class, String.class)); // invoke run with threadcontext and topself method.invokestatic(p(Ruby.class), "newInstance", sig(Ruby.class, RubyInstanceConfig.class)); method.dup(); method.invokevirtual(RUBY, "getCurrentContext", sig(ThreadContext.class)); method.swap(); method.invokevirtual(RUBY, "getTopSelf", sig(IRubyObject.class)); method.ldc(false); method.invokevirtual(getClassname(), "load", loadSig); method.voidreturn(); method.end(); } getCacheCompiler().finish(); endInit(); endClassInit(); }