public Object evaluate(final String scriptstr)
throws InterpreterException {
final Context ctx = enterContext();
Script script = null;
Entry et = null;
Iterator it = compiledScripts.iterator();
// between nlog(n) and log(n) because it is
// an AbstractSequentialList
while (it.hasNext()) {
if ((et = (Entry)(it.next())).str.equals(scriptstr)) {
// if it is not at the end, remove it because
// it will change from place (it is faster
// to remove it now)
script = et.script;
it.remove();
break;
}
}
if (script == null) {
// this script has not been compiled yet or has been forgotten
// since the compilation:
// compile it and store it for future use.
script = (Script)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
try {
return ctx.compileReader(globalObject,
new StringReader(scriptstr),
SOURCE_NAME_SVG,
1, rhinoClassLoader);
} catch (IOException io) {
// Should never happen: we are using a string
throw new Error();
}
}
});
if (compiledScripts.size()+1 > MAX_CACHED_SCRIPTS) {
// too many cached items - we should delete the oldest entry.
// all of this is very fast on linkedlist
compiledScripts.removeFirst();
}
// stroring is done here:
compiledScripts.addLast(new Entry(scriptstr, script));
} else {
// this script has been compiled before,
// just update it's index so it won't get deleted soon.
compiledScripts.addLast(et);
}
Object rv = null;
try {
rv = script.exec(ctx, globalObject);
} catch (JavaScriptException e) {
// exception from JavaScript (possibly wrapping a Java Ex)
if (e.getValue() instanceof Exception) {
Exception ex = (Exception)e.getValue();
throw new InterpreterException(ex, ex.getMessage(), -1, -1);