On Wednesday, December 4, 2013 6:18:37 PM UTC-8, Vyacheslav Egorov wrote:
>
> > 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.
>

I do not understand "can't ... but engines allow": are there states other 
than "can" and "cannot"?  Maybe, given the following, you meant "I 
recommend against function declarations inside of if-statements because it 
leads to problems like those you hit, see below".?
 

>
> 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. 
>

The intent of this code is to illustrate a problem in a 20kloc failure. The 
original code did not have an if (){function dcl{}}, I was attempting to 
simulate its failure in the second of two calls of the preprocessor.
 

> 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'm confused by your explanation: which 'it" can't be cached or saved, the 
declaration, the closure, the function?

I think what you are saying is: "Your example suggests that you expected to 
repeatedly execute a function within a closure environment but instead each 
time you re-executed the declaration. Each declaration created a new 
closure. To avoid re-declaring the function, use a function expression and 
save the function 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;
> })();
>

I was able to succeed with something similar where wrapSource is prefixed 
by the transcoded source of traceur and wrapSource calls the traceur 
functions.

Thanks for your help, very much appreciated!
jjb
 
 

>
> Vyacheslav Egorov
>
>
> On Thu, Dec 5, 2013 at 12:04 AM, <[email protected] <javascript:>>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] <javascript:>
>> 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] <javascript:>.
>> 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.

Reply via email to