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

📄 context.java

📁 java中比较著名的js引擎当属mozilla开源的rhino
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                // Context with associated factory will be released                // automatically and does not need to change enterCount                return old;            }            if (old.sealed) onSealedMutation();            cx = old;        } else {            if (cx == null) {                cx = factory.makeContext();            } else {                if (cx.sealed) onSealedMutation();            }            if (cx.enterCount != 0 || cx.factory != null) {                throw new IllegalStateException();            }            if (!cx.creationEventWasSent) {                cx.creationEventWasSent = true;                factory.onContextCreated(cx);            }        }        if (old == null) {            VMBridge.instance.setContext(helper, cx);        }        ++cx.enterCount;        return cx;     }    /**     * Exit a block of code requiring a Context.     *     * Calling <code>exit()</code> will remove the association between     * the current thread and a Context if the prior call to     * <code>enter()</code> on this thread newly associated a Context     * with this thread.     * Once the current thread no longer has an associated Context,     * it cannot be used to execute JavaScript until it is again associated     * with a Context.     *     * @see org.mozilla.javascript.Context#enter()     * @see #call(ContextAction)     * @see ContextFactory#call(ContextAction)     */    public static void exit()    {        exit(ContextFactory.getGlobal());    }        static void exit(ContextFactory factory)    {        Object helper = VMBridge.instance.getThreadContextHelper();        Context cx = VMBridge.instance.getContext(helper);        if (cx == null) {            throw new IllegalStateException(                "Calling Context.exit without previous Context.enter");        }        if (cx.factory != null) {            // Context with associated factory will be released            // automatically and does not need to change enterCount            return;        }        if (cx.enterCount < 1) Kit.codeBug();        if (cx.sealed) onSealedMutation();        --cx.enterCount;        if (cx.enterCount == 0) {            VMBridge.instance.setContext(helper, null);            factory.onContextReleased(cx);        }    }        /**     * Call {@link ContextAction#run(Context cx)}     * using the Context instance associated with the current thread.     * If no Context is associated with the thread, then     * <tt>ContextFactory.getGlobal().makeContext()</tt> will be called to     * construct new Context instance. The instance will be temporary     * associated with the thread during call to     * {@link ContextAction#run(Context)}.     *     * @return The result of {@link ContextAction#run(Context)}.     */    public static Object call(ContextAction action)    {        return call(ContextFactory.getGlobal(), action);    }    /**     * Call {@link     * Callable#call(Context cx, Scriptable scope, Scriptable thisObj,     *               Object[] args)}     * using the Context instance associated with the current thread.     * If no Context is associated with the thread, then     * {@link ContextFactory#makeContext()} will be called to construct     * new Context instance. The instance will be temporary associated     * with the thread during call to {@link ContextAction#run(Context)}.     * <p>     * It is allowed to use null for <tt>factory</tt> argument     * in which case the factory associated with the scope will be     * used to create new context instances.     *     * @see ContextFactory#call(ContextAction)     */    public static Object call(ContextFactory factory, Callable callable,                              Scriptable scope, Scriptable thisObj,                              Object[] args)    {        if (factory == null) {            factory = ContextFactory.getGlobal();        }        Object helper = VMBridge.instance.getThreadContextHelper();        Context cx = VMBridge.instance.getContext(helper);        if (cx != null) {            Object result;            if (cx.factory != null) {                result = callable.call(cx, scope, thisObj, args);            } else {                // Context was associated with the thread via Context.enter,                // set factory to make Context.enter/exit to be no-op                // during call                cx.factory = factory;                try {                    result = callable.call(cx, scope, thisObj, args);                } finally {                    cx.factory = null;                }            }            return result;        }        cx = prepareNewContext(factory, helper);        try {            return callable.call(cx, scope, thisObj, args);        } finally {            releaseContext(helper, cx);        }    }    /**     * The method implements {@links ContextFactory#call(ContextAction)} logic.     */    static Object call(ContextFactory factory, ContextAction action)    {        Object helper = VMBridge.instance.getThreadContextHelper();        Context cx = VMBridge.instance.getContext(helper);        if (cx != null) {            if (cx.factory != null) {                return action.run(cx);            } else {                cx.factory = factory;                try {                    return action.run(cx);                } finally {                    cx.factory = null;                }            }        }        cx = prepareNewContext(factory, helper);        try {            return action.run(cx);        } finally {            releaseContext(helper, cx);        }    }    private static Context prepareNewContext(ContextFactory factory,                                             Object contextHelper)    {        Context cx = factory.makeContext();        if (cx.factory != null || cx.enterCount != 0) {            throw new IllegalStateException("factory.makeContext() returned Context instance already associated with some thread");        }        cx.factory = factory;        factory.onContextCreated(cx);        if (factory.isSealed() && !cx.isSealed()) {            cx.seal(null);        }        VMBridge.instance.setContext(contextHelper, cx);        return cx;    }    private static void releaseContext(Object contextHelper, Context cx)    {        VMBridge.instance.setContext(contextHelper, null);        try {            cx.factory.onContextReleased(cx);        } finally {            cx.factory = null;        }    }    /**     * @deprecated     * @see ContextFactory#addListener(ContextFactory.Listener)     * @see ContextFactory#getGlobal()     */    public static void addContextListener(ContextListener listener)    {        // Special workaround for the debugger        String DBG = "org.mozilla.javascript.tools.debugger.Main";        if (DBG.equals(listener.getClass().getName())) {            Class cl = listener.getClass();            Class factoryClass = Kit.classOrNull(                "org.mozilla.javascript.ContextFactory");            Class[] sig = { factoryClass };            Object[] args = { ContextFactory.getGlobal() };            try {                Method m = cl.getMethod("attachTo", sig);                m.invoke(listener, args);            } catch (Exception ex) {                RuntimeException rex = new RuntimeException();                Kit.initCause(rex, ex);                throw rex;            }            return;        }        ContextFactory.getGlobal().addListener(listener);    }    /**     * @deprecated     * @see ContextFactory#removeListener(ContextFactory.Listener)     * @see ContextFactory#getGlobal()     */    public static void removeContextListener(ContextListener listener)    {        ContextFactory.getGlobal().addListener(listener);    }    /**     * Return {@link ContextFactory} instance used to create this Context     * or the result of {@link ContextFactory#getGlobal()} if no factory     * was used for Context creation.     */    public final ContextFactory getFactory()    {        ContextFactory result = factory;        if (result == null) {            result = ContextFactory.getGlobal();        }        return result;    }    /**     * Checks if this is a sealed Context. A sealed Context instance does not     * allow to modify any of its properties and will throw an exception     * on any such attempt.     * @see #seal(Object sealKey)     */    public final boolean isSealed()    {        return sealed;    }    /**     * Seal this Context object so any attempt to modify any of its properties     * including calling {@link #enter()} and {@link #exit()} methods will     * throw an exception.     * <p>     * If <tt>sealKey</tt> is not null, calling     * {@link #unseal(Object sealKey)} with the same key unseals     * the object. If <tt>sealKey</tt> is null, unsealing is no longer possible.     *     * @see #isSealed()     * @see #unseal(Object)     */    public final void seal(Object sealKey)    {        if (sealed) onSealedMutation();        sealed = true;        this.sealKey = sealKey;    }    /**     * Unseal previously sealed Context object.     * The <tt>sealKey</tt> argument should not be null and should match     * <tt>sealKey</tt> suplied with the last call to     * {@link #seal(Object)} or an exception will be thrown.     *     * @see #isSealed()     * @see #seal(Object sealKey)     */    public final void unseal(Object sealKey)    {        if (sealKey == null) throw new IllegalArgumentException();        if (this.sealKey != sealKey) throw new IllegalArgumentException();        if (!sealed) throw new IllegalStateException();        sealed = false;        this.sealKey = null;    }    static void onSealedMutation()    {        throw new IllegalStateException();    }    /**     * Get the current language version.     * <p>     * The language version number affects JavaScript semantics as detailed     * in the overview documentation.     *     * @return an integer that is one of VERSION_1_0, VERSION_1_1, etc.     */    public final int getLanguageVersion()    {       return version;    }    /**     * Set the language version.     *     * <p>     * Setting the language version will affect functions and scripts compiled     * subsequently. See the overview documentation for version-specific     * behavior.     *     * @param version the version as specified by VERSION_1_0, VERSION_1_1, etc.     */    public void setLanguageVersion(int version)    {        if (sealed) onSealedMutation();        checkLanguageVersion(version);        Object listeners = propertyListeners;        if (listeners != null && version != this.version) {            firePropertyChangeImpl(listeners, languageVersionProperty,                               new Integer(this.version),                               new Integer(version));        }        this.version = version;    }    public static boolean isValidLanguageVersion(int version)    {        switch (version) {            case VERSION_DEFAULT:            case VERSION_1_0:            case VERSION_1_1:            case VERSION_1_2:            case VERSION_1_3:            case VERSION_1_4:            case VERSION_1_5:            case VERSION_1_6:                return true;        }        return false;    }    public static void checkLanguageVersion(int version)    {        if (isValidLanguageVersion(version)) {            return;        }        throw new IllegalArgumentException("Bad language version: "+version);    }    /**

⌨️ 快捷键说明

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