> Here is a simple example of the issue from the JS point of view:
You actually can't have a function declaration inside an if-statement but
engines allow that for compat reasons.
Now what you have written is equivalent to:
function preprocessor(source, url, listenerName) {
function wrapSource(source, url, listenerName) {
console.log('closeOverMe=' + closeOverMe);
return source + '\n//' + postfix;
}
var closeOverMe;
if (!window.wasCompiledPreviously) {
closeOverMe = 'I am closed over';
console.log('unclosed closeOverMe=' + closeOverMe);
window.wasCompiledPreviously = true;
}
return wrapSource(source, url, listenerName);
}
Now you should be able to see why closeOverMe is undefined on the second
invocation.
Honestly I am not sure I understand the intent of the code. function
literal / declaration create a new closure every time they are executed,
you can't cache it like that. You need to explicitly save it in a variable.
I would say that clean JavaScript way to do this is something along this
lines:
var preprocessor = (function () {
var wrapSource = null;
function preprocessor(source, url, listenerName) {
if (wrapSource === null) {
var closeOverMe = 'I am closed over';
wrapSource = function wrapSource(source, url, listenerName) {
console.log('closeOverMe=' + closeOverMe);
return source + '\n//' + postfix;
};
}
return wrapSource(source, url, listenerName);
}
return preprocessor;
})();
Vyacheslav Egorov
On Thu, Dec 5, 2013 at 12:04 AM, <[email protected]> wrote:
> Let me start with a request for patience, I have a complex problem and I'm
> unsure on some of the V8 terminology.
>
> Chrome's DevTools supports "script preprocessing": from the DevTools you
> can reload a Web page and preprocess every thing that will go into V8 with
> a JS to JS preprocessor. This allows tracing and runtime analysis tools
> based on recompilation to be implemented in JS.
>
> In applying this preprocessor with the traceur-compiler (
> https://github.com/google/traceur-compiler) I hit a snag: functions
> within the JS preprocessor sometimes reference 'undefined' rather than the
> object expected. ("sometimes" here is one kind of complication, the
> failures are deterministic and in simple cases the failure 100%,
> thankfully). These undefined references are always pointing to objects
> created in closure environments.
>
> As the web page loads, scripts from the browser enter V8, V8 emits a
> before-compile event, the preprocessor runs and returns modified code, then
> V8 proceeds with its work. The first event works; subsequent ones all fail.
>
> The preprocessor itself is running in a separate Context modeled after the
> Chrome browser's content-script mechanism. We compile the JS preprocessor
> into this Context to obtain a C++ reference to a function within the
> Context. Then we call the function from C++ every time we get the V8
> before-compile event.
>
> Here is a simple example of the issue from the JS point of view:
>
> function preprocessor(source, url, listenerName) {
> if (!window.wasCompiledPreviously) {
> var closeOverMe = 'I am closed over';
> console.log('unclosed closeOverMe=' + closeOverMe);
> function wrapSource(source, url, listenerName) {
> console.log('closeOverMe=' + closeOverMe);
> return source + '\n//' + postfix;
> }
> window.wasCompiledPreviously = true;
> }
> return wrapSource(source, url, listenerName);
> }
>
> On the first preprocessor call the console log messages are ok, but
> subsequent calls will have closeOverMe undefined. So the 'window' state is
> being saved between calls and the function wrapSource() can be called, but
> the thing that closeOverMe points to has gone away.
>
> I'm hoping that some reading this far will say "Oh that means you did not
> ..." in the V8 blink binding code. If this does not ring any bells I'll
> have to start asking about the details of how Blink calls in to V8 for this
> case.
>
> Thanks,
> jjb
>
> --
> --
> v8-users mailing list
> [email protected]
> http://groups.google.com/group/v8-users
> ---
> You received this message because you are subscribed to the Google Groups
> "v8-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/groups/opt_out.
>
--
--
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
---
You received this message because you are subscribed to the Google Groups
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.