diff --git a/src/helma/scripting/rhino/DynamicGlobalObject.java b/src/helma/scripting/rhino/DynamicGlobalObject.java deleted file mode 100644 index 0f6a03be..00000000 --- a/src/helma/scripting/rhino/DynamicGlobalObject.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Helma License Notice - * - * The contents of this file are subject to the Helma License - * Version 2.0 (the "License"). You may not use this file except in - * compliance with the License. A copy of the License is available at - * http://adele.helma.org/download/helma/license.txt - * - * Copyright 1998-2003 Helma Software. All Rights Reserved. - * - * $RCSfile$ - * $Author$ - * $Revision$ - * $Date$ - */ - -package helma.scripting.rhino; - -import helma.framework.core.Application; -import org.mozilla.javascript.Scriptable; -import org.mozilla.javascript.Context; - - -/** - * This class implements a global scope object that is a dynamic proxy - * to a shared global scope and a per-thread dynamic scope. - */ -public class DynamicGlobalObject extends GlobalObject { - - public DynamicGlobalObject(RhinoCore core, Application app) { - super(core, app); - } - - public Object get(String s, Scriptable scriptable) { - Context cx = Context.getCurrentContext(); - Scriptable scope = (Scriptable) cx.getThreadLocal("threadscope"); - if (scope != null) { - Object obj = scope.get(s, scope); - if (obj != null && obj != NOT_FOUND) { - return obj; - } - // make thread scope accessible as "global" - if ("global".equals(s)) { - return scope; - } - } - return super.get(s, scriptable); - } - -} diff --git a/src/helma/scripting/rhino/GlobalObject.java b/src/helma/scripting/rhino/GlobalObject.java index 706bdf0c..219410fe 100644 --- a/src/helma/scripting/rhino/GlobalObject.java +++ b/src/helma/scripting/rhino/GlobalObject.java @@ -39,6 +39,7 @@ import java.io.*; public class GlobalObject extends ImporterTopLevel implements PropertyRecorder { Application app; RhinoCore core; + GlobalObject sharedGlobal = null; // fields to implement PropertyRecorder private boolean isRecording = false; @@ -50,9 +51,14 @@ public class GlobalObject extends ImporterTopLevel implements PropertyRecorder { * @param core ... * @param app ... */ - public GlobalObject(RhinoCore core, Application app) { + public GlobalObject(RhinoCore core, Application app, boolean perThread) { this.core = core; this.app = app; + if (perThread) { + sharedGlobal = core.global; + setPrototype(sharedGlobal); + setParentScope(null); + } } /** @@ -92,21 +98,6 @@ public class GlobalObject extends ImporterTopLevel implements PropertyRecorder { return "GlobalObject"; } - /** - * Override ScriptableObject.get() to synchronize it. - * - * @param name - * @param start - * @return the property for the given name - */ - public synchronized Object get(String name, Scriptable start) { - // register property for PropertyRecorder interface - if (isRecording) { - changedProperties.add(name); - } - return super.get(name, start); - } - /** * Override ScriptableObject.put() to implement PropertyRecorder interface * and to synchronize method. @@ -123,6 +114,48 @@ public class GlobalObject extends ImporterTopLevel implements PropertyRecorder { super.put(name, start, value); } + /** + * Override ScriptableObject.get() to synchronize it, use the per-thread scope if possible, + * and return the per-thread scope for "global". + * + * @param name + * @param start + * @return the property for the given name + */ + public synchronized Object get(String name, Scriptable start) { + // register property for PropertyRecorder interface + if (isRecording) { + changedProperties.add(name); + } + Context cx = Context.getCurrentContext(); + GlobalObject scope = (GlobalObject) cx.getThreadLocal("threadscope"); + if (scope != null) { + Object obj = scope.get(name); + if (obj != null && obj != NOT_FOUND) { + return obj; + } + // make thread scope accessible as "global" + if ("global".equals(name)) { + return scope; + } + } + if (sharedGlobal != null) { + return sharedGlobal.get(name); + } else { + return super.get(name, start); + } + } + + /** + * Directly get a property, bypassing the extra stuff in get(String, Scriptable) + * + * @param name + * @return the property for the given name + */ + protected synchronized Object get(String name) { + return super.get(name, this); + } + /** * * diff --git a/src/helma/scripting/rhino/RhinoCore.java b/src/helma/scripting/rhino/RhinoCore.java index ff8bf613..6f666376 100644 --- a/src/helma/scripting/rhino/RhinoCore.java +++ b/src/helma/scripting/rhino/RhinoCore.java @@ -42,7 +42,7 @@ public final class RhinoCore implements ScopeProvider { public final Application app; // the global object - DynamicGlobalObject global; + GlobalObject global; // caching table for JavaScript object wrappers CacheMap wrappercache; @@ -104,7 +104,7 @@ public final class RhinoCore implements ScopeProvider { try { // create global object - global = new DynamicGlobalObject(this, app); + global = new GlobalObject(this, app, false); // call the initStandardsObject in ImporterTopLevel so that // importClass() and importPackage() are set up. global.initStandardObjects(context, false); diff --git a/src/helma/scripting/rhino/RhinoEngine.java b/src/helma/scripting/rhino/RhinoEngine.java index 45af486a..6257dc35 100644 --- a/src/helma/scripting/rhino/RhinoEngine.java +++ b/src/helma/scripting/rhino/RhinoEngine.java @@ -49,7 +49,7 @@ public class RhinoEngine implements ScriptingEngine { Context context; // the per-thread global object - Scriptable global; + GlobalObject global; // the request evaluator instance owning this fesi evaluator RequestEvaluator reval; @@ -87,9 +87,7 @@ public class RhinoEngine implements ScriptingEngine { context.setApplicationClassLoader(app.getClassLoader()); try { - global = new GlobalObject(core, app); - global.setPrototype(core.global); - global.setParentScope(null); + global = new GlobalObject(core, app, true); extensionGlobals = new HashMap();