diff --git a/modules/globals.js b/modules/globals.js index 5d4903e4b..a2d710341 100644 --- a/modules/globals.js +++ b/modules/globals.js @@ -85,7 +85,7 @@ Object.defineProperty(this, "global", { value: this }); this.setTimeout = function(callback, delay) { var args = Array.slice(arguments, 2); delay = parseInt(delay, 10) || 0; - var worker = engine.getCurrentWorker(); + var worker = engine.getCurrentWorker(callback); return worker.schedule(delay, this, callback, args); }; @@ -121,7 +121,7 @@ Object.defineProperty(this, "global", { value: this }); global.setInterval = function(callback, delay) { var args = Array.slice(arguments, 2); delay = Math.max(parseInt(delay, 10) || 0, 1); - var worker = engine.getCurrentWorker(); + var worker = engine.getCurrentWorker(callback); return worker.scheduleInterval(delay, this, callback, args); }; diff --git a/modules/ringo/engine.js b/modules/ringo/engine.js index 9ecff0d3a..329067b17 100644 --- a/modules/ringo/engine.js +++ b/modules/ringo/engine.js @@ -164,11 +164,12 @@ function getWorker() { } /** - * Get the current worker instance. - * @return {org.ringojs.engine.RingoWorker} the current RingoWorker instance + * Get the worker instance associated with the current thread or the given scope or function object. + * @param obj {Object} optional scope or function to get the worker from. + * @return {org.ringojs.engine.RingoWorker} the current worker */ -function getCurrentWorker() { - return engine.getCurrentWorker(); +function getCurrentWorker(obj) { + return engine.getCurrentWorker(obj || null); } /** diff --git a/src/org/ringojs/engine/Callback.java b/src/org/ringojs/engine/Callback.java index 71fa895de..2099b45e3 100644 --- a/src/org/ringojs/engine/Callback.java +++ b/src/org/ringojs/engine/Callback.java @@ -51,10 +51,7 @@ public Callback(Scriptable function, RhinoEngine engine, boolean sync) { if (function instanceof Function) { this.module = scope; this.function = function; - worker = engine.getCurrentWorker(); - if (worker == null) { - worker = engine.getWorker(); - } + this.worker = engine.getCurrentWorker(function); } else { this.module = ScriptableObject.getProperty(function, "module"); this.function = ScriptableObject.getProperty(function, "name"); diff --git a/src/org/ringojs/engine/ModuleScope.java b/src/org/ringojs/engine/ModuleScope.java index 6fdfe58d8..c7a6aa67e 100644 --- a/src/org/ringojs/engine/ModuleScope.java +++ b/src/org/ringojs/engine/ModuleScope.java @@ -29,6 +29,7 @@ public class ModuleScope extends ImporterTopLevel { private Trackable source; private Repository repository; private String id; + private RingoWorker worker; private long checksum; private Scriptable exportsObject, moduleObject; private static final long serialVersionUID = -2409425841990094897L; @@ -50,6 +51,7 @@ public ModuleScope(String moduleId, Trackable source, this.repository = source instanceof Repository ? (Repository) source : source.getParentRepository(); this.id = moduleId; + this.worker = worker; // create and define module meta-object moduleObject = new ModuleObject(this); defineProperty("module", moduleObject, DONTENUM); @@ -69,6 +71,10 @@ public Repository getRepository() { return repository; } + public RingoWorker getWorker() { + return worker; + } + public void reset() { Scriptable exports = new ExportsObject(); defineProperty("exports", exports, DONTENUM); diff --git a/src/org/ringojs/engine/Require.java b/src/org/ringojs/engine/Require.java index 543e38372..08d42368f 100644 --- a/src/org/ringojs/engine/Require.java +++ b/src/org/ringojs/engine/Require.java @@ -76,10 +76,7 @@ public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] ar ModuleScope moduleScope = thisObj instanceof ModuleScope ? (ModuleScope) thisObj : null; try { - RingoWorker worker = engine.getCurrentWorker(); - if (worker == null) { - worker = engine.getMainWorker(); - } + RingoWorker worker = engine.getCurrentWorker(scope); String arg = args[0].toString(); Scriptable module = worker.loadModule(cx, arg, moduleScope); return module instanceof ModuleScope ? diff --git a/src/org/ringojs/engine/RhinoEngine.java b/src/org/ringojs/engine/RhinoEngine.java index f046e14bc..1abd9b43a 100644 --- a/src/org/ringojs/engine/RhinoEngine.java +++ b/src/org/ringojs/engine/RhinoEngine.java @@ -275,11 +275,35 @@ protected RingoWorker setCurrentWorker(RingoWorker worker) { } /** - * Get the worker associated with the given scope, or null. - * @return the worker associated with the current thread, or null. + * Get the worker associated with the current thread, or the given scope or function argument if provided. + * An {@code IllegalStateException} is thrown if no worker could be found or if different workers are + * associated with the current thread and the argument object. + * + * @param obj a scope or function object + * @throws IllegalStateException if no worker could be found, or if different workers are associates with + * the current thread and the argument object + * @return the current worker */ - public RingoWorker getCurrentWorker() { - return currentWorker.get(); + public RingoWorker getCurrentWorker(Scriptable obj) { + RingoWorker worker = currentWorker.get(); // Get worker associated with current thread + Scriptable scriptable = obj; + + while (scriptable != null) { + if (scriptable instanceof ModuleScope) { + RingoWorker scopeWorker = ((ModuleScope) scriptable).getWorker(); + if (worker == null) { + worker = scopeWorker; + } else if (worker != scopeWorker) { + throw new IllegalStateException("Current thread worker differs from scope worker"); + } + break; + } + scriptable = scriptable.getParentScope(); + } + if (worker == null) { + throw new IllegalStateException("No worker associated with current thread or scope"); + } + return worker; } /**