diff --git a/js/rhino/src/org/mozilla/javascript/Context.java b/js/rhino/src/org/mozilla/javascript/Context.java index 0d21b223895b..e34285f47000 100644 --- a/js/rhino/src/org/mozilla/javascript/Context.java +++ b/js/rhino/src/org/mozilla/javascript/Context.java @@ -349,6 +349,15 @@ public class Context } } + /** + * Return {@link ContextFactory} instance to use to create Context instances + * for other execution threads. + */ + protected ContextFactory factory() + { + return ContextFactory.getDefault(); + } + /** * Call {@link * Callable#call(Context cx, Scriptable scope, Scriptable thisObj, @@ -364,6 +373,14 @@ public class Context public static Object call(Callable callable, Scriptable scope, Scriptable thisObj, Object[] args) throws JavaScriptException + { + return call(ContextFactory.getDefault(), callable, scope, thisObj, + args); + } + + static Object call(ContextFactory f, Callable callable, Scriptable scope, + Scriptable thisObj, Object[] args) + throws JavaScriptException { Context[] storage = getThreadContextStorage(); Context cx; @@ -377,7 +394,7 @@ public class Context return callable.call(cx, scope, thisObj, args); } - cx = new Context(); + cx = f.newContext(); if (!cx.creationEventWasSent) { cx.creationEventWasSent = true; cx.runListeners(CONTEXT_CREATED_EVENT); diff --git a/js/rhino/src/org/mozilla/javascript/ContextFactory.java b/js/rhino/src/org/mozilla/javascript/ContextFactory.java new file mode 100644 index 000000000000..628f950595ee --- /dev/null +++ b/js/rhino/src/org/mozilla/javascript/ContextFactory.java @@ -0,0 +1,65 @@ +/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is a factory class for Context creation. + * + * The Initial Developer of the Original Code is + * RUnit Software AS. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Igor Bukanov, igor@fastmail.fm + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// API class + +package org.mozilla.javascript; + + +public class ContextFactory +{ + protected Context newContext() + { + return new Context(); + } + + public final Object call(Callable callable, Scriptable scope, + Scriptable thisObj, Object[] args) + { + return Context.call(this, callable, scope, thisObj, args); + } + + public static ContextFactory getDefault() + { + return defaultFactory; + } + + private static ContextFactory defaultFactory = new ContextFactory(); + +} + diff --git a/js/rhino/src/org/mozilla/javascript/JavaAdapter.java b/js/rhino/src/org/mozilla/javascript/JavaAdapter.java index 4f33c23a619e..a1f2558f2650 100644 --- a/js/rhino/src/org/mozilla/javascript/JavaAdapter.java +++ b/js/rhino/src/org/mozilla/javascript/JavaAdapter.java @@ -69,6 +69,7 @@ public final class JavaAdapter copy = null; } copy.function = function; + copy.contextFactory = currentFactory(); return copy; } @@ -84,7 +85,7 @@ public final class JavaAdapter { Scriptable scope = function.getParentScope(); Scriptable thisObj = scope; - return Context.call(this, scope, thisObj, args); + return contextFactory.call(this, scope, thisObj, args); } public Object call(Context cx, Scriptable scope, Scriptable thisObj, @@ -106,6 +107,7 @@ public final class JavaAdapter private Function function; + private ContextFactory contextFactory; private int[] argsToConvert; } @@ -380,6 +382,10 @@ public final class JavaAdapter cfw.addField("self", "Lorg/mozilla/javascript/Scriptable;", (short) (ClassFileWriter.ACC_PUBLIC | ClassFileWriter.ACC_FINAL)); + cfw.addField("contextFactory", + "Lorg/mozilla/javascript/ContextFactory;", + (short) (ClassFileWriter.ACC_PRIVATE | + ClassFileWriter.ACC_FINAL)); int interfacesCount = interfaces == null ? 0 : interfaces.length; for (int i=0; i < interfacesCount; i++) { if (interfaces[i] != null) @@ -596,12 +602,18 @@ public final class JavaAdapter return (Function)x; } + public static ContextFactory currentFactory() + { + return Context.getContext().factory(); + } + /** * Utility method which dynamically binds a Context to the current thread, * if none already exists. */ public static Object callMethod(Scriptable scope, Scriptable thisObj, - Function f, Object[] args, long argsToWrap) + Function f, Object[] args, long argsToWrap, + ContextFactory factory) { if (f == null) { // See comments in getFunction @@ -612,7 +624,7 @@ public final class JavaAdapter if (cx != null) { return doCall(cx, scope, thisObj, f, args, argsToWrap); } else { - cx = Context.enter(); + cx = Context.enter(factory.newContext()); try { return doCall(cx, scope, thisObj, f, args, argsToWrap); } finally { @@ -668,6 +680,8 @@ public final class JavaAdapter cfw.add(ByteCode.PUTFIELD, adapterName, "self", "Lorg/mozilla/javascript/Scriptable;"); + generateContextFactoryInit(cfw, adapterName); + cfw.add(ByteCode.RETURN); cfw.stopMethod((short)3); // 2: this + delegee } @@ -698,6 +712,8 @@ public final class JavaAdapter cfw.add(ByteCode.PUTFIELD, adapterName, "self", "Lorg/mozilla/javascript/Scriptable;"); + generateContextFactoryInit(cfw, adapterName); + cfw.add(ByteCode.RETURN); cfw.stopMethod((short)20); // TODO: magic number "20" } @@ -745,10 +761,24 @@ public final class JavaAdapter cfw.add(ByteCode.PUTFIELD, adapterName, "self", "Lorg/mozilla/javascript/Scriptable;"); + generateContextFactoryInit(cfw, adapterName); + cfw.add(ByteCode.RETURN); cfw.stopMethod((short)2); // this + delegee } + private static void generateContextFactoryInit(ClassFileWriter cfw, + String adapterName) + { + cfw.add(ByteCode.ALOAD_0); // this for the following PUTFIELD for self + cfw.addInvoke(ByteCode.INVOKESTATIC, + "org/mozilla/javascript/JavaAdapter", + "currentFactory", + "()Lorg/mozilla/javascript/ContextFactory;"); + cfw.add(ByteCode.PUTFIELD, adapterName, "contextFactory", + "Lorg/mozilla/javascript/ContextFactory;"); + } + /** * Generates code to wrap Java arguments into Object[]. * Non-primitive Java types are left as is pending convertion @@ -972,6 +1002,10 @@ public final class JavaAdapter } cfw.addPush(convertionMask); + cfw.add(ByteCode.ALOAD_0); + cfw.add(ByteCode.GETFIELD, genName, "contextFactory", + "Lorg/mozilla/javascript/ContextFactory;"); + // go through utility method, which creates a Context to run the // method in. cfw.addInvoke(ByteCode.INVOKESTATIC, @@ -982,6 +1016,7 @@ public final class JavaAdapter +"Lorg/mozilla/javascript/Function;" +"[Ljava/lang/Object;" +"J" + +"Lorg/mozilla/javascript/ContextFactory;" +")Ljava/lang/Object;"); generateReturnResult(cfw, returnType);