-
Notifications
You must be signed in to change notification settings - Fork 860
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot capture continuation from JavaScript code not called directly by executeScriptWithContinuations or callFunctionWithContinuations #1444
Comments
Don't think this is actionable as it currently stand. In order to make it actionable, this issue would have to include a runnable (java) sample, that demonstrates the issue and some analysis of the likely reason of the issue and whether the reason it fails in several scenarios is likely the same or not |
@p-bakker Hello, I have updated the comment as per your requirements and I hope this information is useful to you. |
Thnx, that indeed provides a better starting point to understand the issue! I doubt there are many devs around that have intricate knowledge of the inner workings of continuations, why they fail in these scenarios, if they can be supported in these scenarios and what is needed to do so... 😐 But who knows... @szegedi: any thoughts maybe? Otherwise if you have ideas on how to make this work, a PR is always welcome There's also case #1475, which is a different scenario in which capturing a Continuation fails |
👋 Continuations work as long as all of the execution is contained within a single invocation of Bound functions aren't handled specially by the interpreter loop – they could be, though. Just as the special handling for Same for arrow functions – I was actually surprised these didn't work out of the box, but I just looked at the code now as I didn't really work much on Rhino since they were introduced and I can see that lambdas are implemented as As these things can of course get combined (e.g. you can call apply() on a bound arrow function) to implement this properly, we'd need a generic mechanism for peeling the invoked function in the interpreter back to the interpreted function it ultimately reduces to, and if it does, then walk the chain of functions one more time, invoke all requisite It might actually be simpler to write the code to mark the stack position, then opportunistically start executing all this with the assumption the ultimate function will be an interpreted one, and when it isn't, pop the stack back to the marked position and bail out of the interpreter by invoking |
@szegedi Thx a lot for the analysis & input! @821938089 Think you can roll with all this info and maybe put together a PR? |
@p-bakker No, I don't know is what "opportunistically start executing all this" means in the last paragraph. And I don't know how the interpreter works and I can't be sure if the code I wrote is correct. |
I might take a stab at it, it looks like a rather fun task. |
PR ready for review! |
Does this pr work in eval? I see the test doesn't have anything about this. |
(I used the |
Is it possible to make continuations work in eval? I looked at the source code and found that specific function names can also cause continuations to fail. System.out.println("eval()");
executeScript(cx, "function eval(){myObj.capture()};eval()");
System.out.println("With()");
executeScript(cx, "function With(){myObj.capture()};With()"); |
Having some names work differently is curious – where in the source code did you look? And while the functions invoked in eval are interpreted functions, eval itself is not an interpreted function, so when you call eval, you'll step out of the current interpreter loop, hence functions won't work. You'll have on stack:
I don't expect this will change. At least I'm definitely not inclined to put in the work to make this additional corner case work. |
I think it's possible to handle eval in the same interpreter loop for all cases: What I've found here is that a function with the name eval or With is assumed to be a special call, and there is a special branch in the interpreter that takes care of it, so it won't jump out of the interpreter loop in that case. I would expect the continuation to work in this case. In doCallSpecial the call object is checked to see if it is expected, otherwise it falls back to a normal call, but this normal call will not run in the same interpreter. rhino/rhino/src/main/java/org/mozilla/javascript/IRFactory.java Lines 2069 to 2091 in d3ebdc5
rhino/rhino/src/main/java/org/mozilla/javascript/CodeGenerator.java Lines 603 to 649 in 3581b02
rhino/rhino/src/main/java/org/mozilla/javascript/Interpreter.java Lines 1737 to 1747 in 3581b02
rhino/rhino/src/main/java/org/mozilla/javascript/Interpreter.java Lines 2919 to 2964 in 3581b02
rhino/rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java Lines 2757 to 2780 in 3581b02
|
I've used executeScriptWithContinuations to call the js code, but it still throws this error.
In testing, I found that continuation cannot be captured in some cases.
example code that list fail case:
The reason for this failure is that the call method of the InterpretedFunction class does not inherit from the previous CallFrame, causing outermost.isContinuationsTopFrame to be false.
rhino/rhino/src/main/java/org/mozilla/javascript/InterpretedFunction.java
Lines 83 to 88 in f48a40d
rhino/rhino/src/main/java/org/mozilla/javascript/Interpreter.java
Lines 1074 to 1076 in f48a40d
rhino/rhino/src/main/java/org/mozilla/javascript/Interpreter.java
Lines 3477 to 3487 in f48a40d
The text was updated successfully, but these errors were encountered: