⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 javaadapter.java

📁 這是一個javascript 的 interpreter是了解 web browser的好材料
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
                    } catch (NoSuchMethodException e) {                        // Not implemented by superclass; fall through                    }                }                // make sure to generate only one instance of a particular                // method/signature.                String methodSignature = getMethodSignature(method, argTypes);                String methodKey = methodName + methodSignature;                if (! generatedOverrides.has(methodKey)) {                    generateMethod(cfw, adapterName, methodName,                                   argTypes, method.getReturnType());                    generatedOverrides.put(methodKey, 0);                    generatedMethods.put(methodName, 0);                }            }        }        // Now, go through the superclass's methods, checking for abstract        // methods or additional methods to override.        // generate any additional overrides that the object might contain.        Method[] methods = getOverridableMethods(superClass);        for (int j = 0; j < methods.length; j++) {            Method method = methods[j];            int mods = method.getModifiers();            // if a method is marked abstract, must implement it or the            // resulting class won't be instantiable. otherwise, if the object            // has a property of the same name, then an override is intended.            boolean isAbstractMethod = Modifier.isAbstract(mods);            String methodName = method.getName();            if (isAbstractMethod || functionNames.has(methodName)) {                // make sure to generate only one instance of a particular                // method/signature.                Class[] argTypes = method.getParameterTypes();                String methodSignature = getMethodSignature(method, argTypes);                String methodKey = methodName + methodSignature;                if (! generatedOverrides.has(methodKey)) {                    generateMethod(cfw, adapterName, methodName,                                   argTypes, method.getReturnType());                    generatedOverrides.put(methodKey, 0);                    generatedMethods.put(methodName, 0);                                        // if a method was overridden, generate a "super$method"                    // which lets the delegate call the superclass' version.                    if (!isAbstractMethod) {                        generateSuper(cfw, adapterName, superName,                                      methodName, methodSignature,                                      argTypes, method.getReturnType());                    }                }            }        }        // Generate Java methods for remaining properties that are not        // overrides.        ObjToIntMap.Iterator iter = new ObjToIntMap.Iterator(functionNames);        for (iter.start(); !iter.done(); iter.next()) {            String functionName = (String)iter.getKey();            if (generatedMethods.has(functionName))                continue;            int length = iter.getValue();            Class[] parms = new Class[length];            for (int k=0; k < length; k++)                parms[k] = ScriptRuntime.ObjectClass;            generateMethod(cfw, adapterName, functionName, parms,                           ScriptRuntime.ObjectClass);        }        return cfw.toByteArray();    }    static Method[] getOverridableMethods(Class c)    {        ArrayList<Method> list = new ArrayList<Method>();        HashSet<String> skip = new HashSet<String>();        while (c != null) {            Method[] methods = c.getDeclaredMethods();            for (int i = 0; i < methods.length; i++) {                String methodKey = methods[i].getName() +                     getMethodSignature(methods[i],                            methods[i].getParameterTypes());                if (skip.contains(methodKey))                    continue; // skip this method                int mods = methods[i].getModifiers();                if (Modifier.isStatic(mods))                    continue;                if (Modifier.isFinal(mods)) {                    // Make sure we don't add a final method to the list                    // of overridable methods.                    skip.add(methodKey);                    continue;                }                if (Modifier.isPublic(mods) || Modifier.isProtected(mods)) {                    list.add(methods[i]);                    skip.add(methodKey);                }            }            c = c.getSuperclass();        }        return list.toArray(new Method[list.size()]);    }    static Class loadAdapterClass(String className, byte[] classBytes)    {        Object staticDomain;        Class domainClass = SecurityController.getStaticSecurityDomainClass();        if(domainClass == CodeSource.class || domainClass == ProtectionDomain.class) {            ProtectionDomain protectionDomain = JavaAdapter.class.getProtectionDomain();            if(domainClass == CodeSource.class) {                staticDomain = protectionDomain == null ? null : protectionDomain.getCodeSource();            }            else {                staticDomain = protectionDomain;            }        }        else {            staticDomain = null;        }        GeneratedClassLoader loader = SecurityController.createLoader(null,                 staticDomain);        Class result = loader.defineClass(className, classBytes);        loader.linkClass(result);        return result;    }    public static Function getFunction(Scriptable obj, String functionName)    {        Object x = ScriptableObject.getProperty(obj, functionName);        if (x == Scriptable.NOT_FOUND) {            // This method used to swallow the exception from calling            // an undefined method. People have come to depend on this            // somewhat dubious behavior. It allows people to avoid            // implementing listener methods that they don't care about,            // for instance.            return null;        }        if (!(x instanceof Function))            throw ScriptRuntime.notFunctionError(x, functionName);        return (Function)x;    }    /**     * Utility method which dynamically binds a Context to the current thread,     * if none already exists.     */    public static Object callMethod(ContextFactory factory,                                    final Scriptable thisObj,                                    final Function f, final Object[] args,                                    final long argsToWrap)    {        if (f == null) {            // See comments in getFunction            return Undefined.instance;        }        if (factory == null) {            factory = ContextFactory.getGlobal();        }        final Scriptable scope = f.getParentScope();        if (argsToWrap == 0) {            return Context.call(factory, f, scope, thisObj, args);        }        Context cx = Context.getCurrentContext();        if (cx != null) {            return doCall(cx, scope, thisObj, f, args, argsToWrap);        } else {            return factory.call(new ContextAction() {                public Object run(Context cx)                {                    return doCall(cx, scope, thisObj, f, args, argsToWrap);                }            });        }    }    private static Object doCall(Context cx, Scriptable scope,                                 Scriptable thisObj, Function f,                                 Object[] args, long argsToWrap)    {        // Wrap the rest of objects        for (int i = 0; i != args.length; ++i) {            if (0 != (argsToWrap & (1 << i))) {                Object arg = args[i];                if (!(arg instanceof Scriptable)) {                    args[i] = cx.getWrapFactory().wrap(cx, scope, arg,                                                       null);                }            }        }        return f.call(cx, scope, thisObj, args);    }    public static Scriptable runScript(final Script script)    {        return (Scriptable)Context.call(new ContextAction() {            public Object run(Context cx)            {                ScriptableObject global = ScriptRuntime.getGlobal(cx);                script.exec(cx, global);                return global;            }        });    }    private static void generateCtor(ClassFileWriter cfw, String adapterName,                                     String superName)    {        cfw.startMethod("<init>",                        "(Lorg/mozilla/javascript/ContextFactory;"                        +"Lorg/mozilla/javascript/Scriptable;)V",                        ClassFileWriter.ACC_PUBLIC);        // Invoke base class constructor        cfw.add(ByteCode.ALOAD_0);  // this        cfw.addInvoke(ByteCode.INVOKESPECIAL, superName, "<init>", "()V");        // Save parameter in instance variable "factory"        cfw.add(ByteCode.ALOAD_0);  // this        cfw.add(ByteCode.ALOAD_1);  // first arg: ContextFactory instance        cfw.add(ByteCode.PUTFIELD, adapterName, "factory",                "Lorg/mozilla/javascript/ContextFactory;");        // Save parameter in instance variable "delegee"        cfw.add(ByteCode.ALOAD_0);  // this        cfw.add(ByteCode.ALOAD_2);  // second arg: Scriptable delegee        cfw.add(ByteCode.PUTFIELD, adapterName, "delegee",                "Lorg/mozilla/javascript/Scriptable;");        cfw.add(ByteCode.ALOAD_0);  // this for the following PUTFIELD for self        // create a wrapper object to be used as "this" in method calls        cfw.add(ByteCode.ALOAD_2);  // the Scriptable delegee        cfw.add(ByteCode.ALOAD_0);  // this        cfw.addInvoke(ByteCode.INVOKESTATIC,                      "org/mozilla/javascript/JavaAdapter",                      "createAdapterWrapper",                      "(Lorg/mozilla/javascript/Scriptable;"                      +"Ljava/lang/Object;"                      +")Lorg/mozilla/javascript/Scriptable;");        cfw.add(ByteCode.PUTFIELD, adapterName, "self",                "Lorg/mozilla/javascript/Scriptable;");        cfw.add(ByteCode.RETURN);        cfw.stopMethod((short)3); // 3: this + factory + delegee    }    private static void generateSerialCtor(ClassFileWriter cfw,                                           String adapterName,                                           String superName)    {        cfw.startMethod("<init>",                        "(Lorg/mozilla/javascript/ContextFactory;"                        +"Lorg/mozilla/javascript/Scriptable;"                        +"Lorg/mozilla/javascript/Scriptable;"                        +")V",                        ClassFileWriter.ACC_PUBLIC);        // Invoke base class constructor        cfw.add(ByteCode.ALOAD_0);  // this        cfw.addInvoke(ByteCode.INVOKESPECIAL, superName, "<init>", "()V");        // Save parameter in instance variable "factory"        cfw.add(ByteCode.ALOAD_0);  // this        cfw.add(ByteCode.ALOAD_1);  // first arg: ContextFactory instance        cfw.add(ByteCode.PUTFIELD, adapterName, "factory",                "Lorg/mozilla/javascript/ContextFactory;");        // Save parameter in instance variable "delegee"        cfw.add(ByteCode.ALOAD_0);  // this        cfw.add(ByteCode.ALOAD_2);  // second arg: Scriptable delegee        cfw.add(ByteCode.PUTFIELD, adapterName, "delegee",                "Lorg/mozilla/javascript/Scriptable;");        // save self        cfw.add(ByteCode.ALOAD_0);  // this        cfw.add(ByteCode.ALOAD_3);  // second arg: Scriptable self        cfw.add(ByteCode.PUTFIELD, adapterName, "self",                "Lorg/mozilla/javascript/Scriptable;");        cfw.add(ByteCode.RETURN);        cfw.stopMethod((short)4); // 4: this + factory + delegee + self    }    private static void generateEmptyCtor(ClassFileWriter cfw,                                          String adapterName,                                          String superName,                                          String scriptClassName)    {        cfw.startMethod("<init>", "()V", ClassFileWriter.ACC_PUBLIC);        // Invoke base class constructor        cfw.add(ByteCode.ALOAD_0);  // this        cfw.addInvoke(ByteCode.INVOKESPECIAL, superName, "<init>", "()V");        // Set factory to null to use current global when necessary        cfw.add(ByteCode.ALOAD_0);        cfw.add(ByteCode.ACONST_NULL);        cfw.add(ByteCode.PUTFIELD, adapterName, "factory",                "Lorg/mozilla/javascript/ContextFactory;");        // Load script class        cfw.add(ByteCode.NEW, scriptClassName);        cfw.add(ByteCode.DUP);        cfw.addInvoke(ByteCode.INVOKESPECIAL, scriptClassName, "<init>", "()V");        // Run script and save resulting scope        cfw.addInvoke(ByteCode.INVOKESTATIC,                      "org/mozilla/javascript/JavaAdapter",                      "runScript",                      "(Lorg/mozilla/javascript/Script;"                      +")Lorg/mozilla/javascript/Scriptable;");        cfw.add(ByteCode.ASTORE_1);        // Save the Scriptable in instance variable "delegee"        cfw.add(ByteCode.ALOAD_0);  // this        cfw.add(ByteCode.ALOAD_1);  // the Scriptable        cfw.add(ByteCode.PUTFIELD, adapterName, "delegee",                "Lorg/mozilla/javascript/Scriptable;");        cfw.add(ByteCode.ALOAD_0);  // this for the following PUTFIELD for self        // create a wrapper object to be used as "this" in method calls        cfw.add(ByteCode.ALOAD_1);  // the Scriptable        cfw.add(ByteCode.ALOAD_0);  // this        cfw.addInvoke(ByteCode.INVOKESTATIC,                      "org/mozilla/javascript/JavaAdapter",                      "createAdapterWrapper",                      "(Lorg/mozilla/javascript/Scriptable;"                      +"Ljava/lang/Object;"                      +")Lorg/mozilla/javascript/Scriptable;");        cfw.add(ByteCode.PUTFIELD, adapterName, "self",                "Lorg/mozilla/javascript/Scriptable;");        cfw.add(ByteCode.RETURN);        cfw.stopMethod((short)2); // this + delegee    }    /**     * Generates code to wrap Java arguments into Object[].     * Non-primitive Java types are left as-is pending conversion     * in the helper method. Leaves the array object on the top of the stack.     */    static void generatePushWrappedArgs(ClassFileWriter cfw,                                        Class[] argTypes,                                        int arrayLength)    {        // push arguments        cfw.addPush(arrayLength);        cfw.add(ByteCode.ANEWARRAY, "java/lang/Object");        int paramOffset = 1;        for (int i = 0; i != argTypes.length; ++i) {            cfw.add(ByteCode.DUP); // duplicate array reference            cfw.addPush(i);            paramOffset += generateWrapArg(cfw, paramOffset, argTypes[i]);            cfw.add(ByteCode.AASTORE);        }    }    /**     * Generates code to wrap Java argument into Object.     * Non-primitive Java types are left unconverted pending conversion     * in the helper method. Leaves the wrapper object on the top of the stack.     */    private static int generateWrapArg(ClassFileWriter cfw, int paramOffset,                                       Class argType)    {        int size = 1;        if (!argType.isPrimitive()) {            cfw.add(ByteCode.ALOAD, paramOffset);        } else if (argType == Boolean.TYPE) {            // wrap boolean values with java.lang.Boolean.            cfw.add(ByteCode.NEW, "java/lang/Boolean");            cfw.add(ByteCode.DUP);            cfw.add(ByteCode.ILOAD, paramOffset);            cfw.addInvoke(ByteCode.INVOKESPECIAL, "java/lang/Boolean",                          "<init>", "(Z)V");        } else if (argType == Character.TYPE) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -