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:
parent
8236ff3e18
commit
908f8134cb
3 changed files with 72 additions and 14 deletions
58
src/helma/scripting/rhino/DynamicGlobalObject.java
Normal file
58
src/helma/scripting/rhino/DynamicGlobalObject.java
Normal 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -37,7 +37,7 @@ public final class RhinoCore {
|
||||||
public final Application app;
|
public final Application app;
|
||||||
|
|
||||||
// the global object
|
// the global object
|
||||||
GlobalObject global;
|
DynamicGlobalObject global;
|
||||||
|
|
||||||
// caching table for JavaScript object wrappers
|
// caching table for JavaScript object wrappers
|
||||||
CacheMap wrappercache;
|
CacheMap wrappercache;
|
||||||
|
@ -88,10 +88,10 @@ public final class RhinoCore {
|
||||||
context.setOptimizationLevel(optLevel);
|
context.setOptimizationLevel(optLevel);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
GlobalObject g = new GlobalObject(this, app);
|
DynamicGlobalObject g = new DynamicGlobalObject(this, app);
|
||||||
g.init();
|
g.init();
|
||||||
|
|
||||||
global = (GlobalObject) context.initStandardObjects(g);
|
global = (DynamicGlobalObject) context.initStandardObjects(g);
|
||||||
|
|
||||||
pathProto = new PathWrapper(this);
|
pathProto = new PathWrapper(this);
|
||||||
|
|
||||||
|
@ -568,15 +568,6 @@ public final class RhinoCore {
|
||||||
|
|
||||||
String protoname = n.getPrototype();
|
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;
|
Scriptable op = null;
|
||||||
|
|
||||||
op = getValidPrototype(protoname);
|
op = getValidPrototype(protoname);
|
||||||
|
@ -761,6 +752,8 @@ public final class RhinoCore {
|
||||||
private synchronized void updateEvaluator(TypeInfo type, Reader reader,
|
private synchronized void updateEvaluator(TypeInfo type, Reader reader,
|
||||||
String sourceName, int firstline) {
|
String sourceName, int firstline) {
|
||||||
// System.err.println("UPDATE EVALUATOR: "+prototype+" - "+sourceName);
|
// System.err.println("UPDATE EVALUATOR: "+prototype+" - "+sourceName);
|
||||||
|
Scriptable threadScope = global.unregisterScope();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// get the current context
|
// get the current context
|
||||||
Context cx = Context.getCurrentContext();
|
Context cx = Context.getCurrentContext();
|
||||||
|
@ -794,6 +787,9 @@ public final class RhinoCore {
|
||||||
// shouldn't happen
|
// shouldn't happen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (threadScope != null) {
|
||||||
|
global.registerScope(threadScope);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ public class RhinoEngine implements ScriptingEngine {
|
||||||
// The Rhino context
|
// The Rhino context
|
||||||
Context context;
|
Context context;
|
||||||
|
|
||||||
// the global object
|
// the per-thread global object
|
||||||
Scriptable global;
|
Scriptable global;
|
||||||
|
|
||||||
// the request evaluator instance owning this fesi evaluator
|
// the request evaluator instance owning this fesi evaluator
|
||||||
|
@ -82,7 +82,7 @@ public class RhinoEngine implements ScriptingEngine {
|
||||||
context.setApplicationClassLoader(app.getClassLoader());
|
context.setApplicationClassLoader(app.getClassLoader());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
global = new GlobalObject(core, app); // context.newObject(core.global);
|
global = new GlobalObject(core, app);
|
||||||
global.setPrototype(core.global);
|
global.setPrototype(core.global);
|
||||||
global.setParentScope(null);
|
global.setParentScope(null);
|
||||||
|
|
||||||
|
@ -162,6 +162,9 @@ public class RhinoEngine implements ScriptingEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
context.setOptimizationLevel(optLevel);
|
context.setOptimizationLevel(optLevel);
|
||||||
|
// register the per-thread scope with the dynamic scope
|
||||||
|
core.global.registerScope(global);
|
||||||
|
// update prototypes
|
||||||
core.updatePrototypes();
|
core.updatePrototypes();
|
||||||
context.putThreadLocal("reval", reval);
|
context.putThreadLocal("reval", reval);
|
||||||
context.putThreadLocal("engine", this);
|
context.putThreadLocal("engine", this);
|
||||||
|
@ -216,6 +219,7 @@ public class RhinoEngine implements ScriptingEngine {
|
||||||
context.removeThreadLocal("reval");
|
context.removeThreadLocal("reval");
|
||||||
context.removeThreadLocal("engine");
|
context.removeThreadLocal("engine");
|
||||||
Context.exit();
|
Context.exit();
|
||||||
|
core.global.unregisterScope();
|
||||||
thread = null;
|
thread = null;
|
||||||
|
|
||||||
// loop through previous globals and unset them, if necessary.
|
// loop through previous globals and unset them, if necessary.
|
||||||
|
|
Loading…
Add table
Reference in a new issue