Added DynamicGlobalObject. Currently, this just falls back to the

per-thread scope when a get() returns NOT_FOUND on the shared
global scope, fixing http://helma.org/bugs/show_bug.cgi?id=322
(kind of hackish, but ok performance-wise).

Potentially this might also be the place to add compile-once script
modules to the global object using a mixin-style approach.
This commit is contained in:
hns 2004-01-20 17:57:35 +00:00
parent 8236ff3e18
commit 908f8134cb
3 changed files with 72 additions and 14 deletions

View file

@ -0,0 +1,58 @@
/*
* 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 java.util.WeakHashMap;
/**
* 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 {
WeakHashMap map = new WeakHashMap();
public DynamicGlobalObject(RhinoCore core, Application app) {
super(core, app);
}
public Object get(String s, Scriptable scriptable) {
Object obj = super.get(s, scriptable);
if (obj != null && obj != NOT_FOUND)
return obj;
Scriptable scope = getScope();
if (scope != null) {
return scope.get(s, scope);
}
return NOT_FOUND;
}
public void registerScope(Scriptable scope) {
map.put(Thread.currentThread(), scope);
}
public Scriptable unregisterScope() {
return (Scriptable) map.remove(Thread.currentThread());
}
public final Scriptable getScope() {
return (Scriptable) map.get(Thread.currentThread());
}
}

View file

@ -37,7 +37,7 @@ public final class RhinoCore {
public final Application app;
// the global object
GlobalObject global;
DynamicGlobalObject global;
// caching table for JavaScript object wrappers
CacheMap wrappercache;
@ -88,10 +88,10 @@ public final class RhinoCore {
context.setOptimizationLevel(optLevel);
try {
GlobalObject g = new GlobalObject(this, app);
DynamicGlobalObject g = new DynamicGlobalObject(this, app);
g.init();
global = (GlobalObject) context.initStandardObjects(g);
global = (DynamicGlobalObject) context.initStandardObjects(g);
pathProto = new PathWrapper(this);
@ -568,15 +568,6 @@ public final class RhinoCore {
String protoname = n.getPrototype();
// set the DbMapping of the node according to its prototype.
// this *should* be done on the objectmodel level, but isn't currently
// for embedded nodes since there's not enough type info at the objectmodel level
// for those nodes.
/* if ((protoname != null) && (protoname.length() > 0) &&
(n.getDbMapping() == null)) {
n.setDbMapping(app.getDbMapping(protoname));
} */
Scriptable op = null;
op = getValidPrototype(protoname);
@ -761,6 +752,8 @@ public final class RhinoCore {
private synchronized void updateEvaluator(TypeInfo type, Reader reader,
String sourceName, int firstline) {
// System.err.println("UPDATE EVALUATOR: "+prototype+" - "+sourceName);
Scriptable threadScope = global.unregisterScope();
try {
// get the current context
Context cx = Context.getCurrentContext();
@ -794,6 +787,9 @@ public final class RhinoCore {
// shouldn't happen
}
}
if (threadScope != null) {
global.registerScope(threadScope);
}
}
}

View file

@ -44,7 +44,7 @@ public class RhinoEngine implements ScriptingEngine {
// The Rhino context
Context context;
// the global object
// the per-thread global object
Scriptable global;
// the request evaluator instance owning this fesi evaluator
@ -82,7 +82,7 @@ public class RhinoEngine implements ScriptingEngine {
context.setApplicationClassLoader(app.getClassLoader());
try {
global = new GlobalObject(core, app); // context.newObject(core.global);
global = new GlobalObject(core, app);
global.setPrototype(core.global);
global.setParentScope(null);
@ -162,6 +162,9 @@ public class RhinoEngine implements ScriptingEngine {
}
context.setOptimizationLevel(optLevel);
// register the per-thread scope with the dynamic scope
core.global.registerScope(global);
// update prototypes
core.updatePrototypes();
context.putThreadLocal("reval", reval);
context.putThreadLocal("engine", this);
@ -216,6 +219,7 @@ public class RhinoEngine implements ScriptingEngine {
context.removeThreadLocal("reval");
context.removeThreadLocal("engine");
Context.exit();
core.global.unregisterScope();
thread = null;
// loop through previous globals and unset them, if necessary.