Updates:
        Status: WorkingAsIntended
        Owner: [email protected]

Comment #1 on issue 3491 by [email protected]: ReferenceError when using variable in closure, in Object.keys(), in debugger
http://code.google.com/p/v8/issues/detail?id=3491

In your example, foo is not bound to the inner function since it does not use it. Therefore, it is stack allocated.

The test case in d8 would be:

  Debug = debug.Debug;

  function f() {
    var foo = 1;
    Object.keys({a: 1, a: 2}).forEach(function(k) {
      debugger;
    });
  }

  function listener(event, exec_state, event_data, data) {
    if (event == Debug.DebugEvent.Break) {
      print(exec_state.frame(0).sourceLineText());
      print(exec_state.frame(1).evaluate("foo").value());
    }
  }

  Debug.setListener(listener);
  f();

Running that with --print-scopes, we get

  function f () { // (32, 134)
    // scope has trivial outer context
    // 1 stack slots
    // local vars:
    VAR foo;  // local[0]
    VAR this;  // parameter[-1]

    function (k) { // (96, 130)
      // scope has trivial outer context
      // local vars:
      VAR this;  // parameter[-1]
    }
  }

Now if I changed the inner function to use foo like this:

  function f() {
    var foo = 1;
    Object.keys({a: 1, a: 2}).forEach(function(k) {
      foo;
      debugger;
    });
  }

the scope would look different:

  function f () { // (32, 132)
    // scope has trivial outer context
    // 5 heap slots
    // local vars:
    VAR foo;  // context[4], forced context allocation
    VAR this;  // parameter[-1]

    function (k) { // (96, 128)
      // local vars:
      VAR this;  // parameter[-1]
    }
  }

foo is now context allocated.

Note that foo is still accessible in the outer function, which is still on the stack. Having the debug listener evaluate using the context from frame 1 works.

print(exec_state.frame(1).evaluate("foo").value());

You might argue that it works if we had something like

  function f() {
    var foo = 1;
    Object.keys({a: 1, a: 2}).forEach(function(k) {
      print(eval("foo"));
    });
  }

That's correct. But that's due to special handling of eval. Since we have eval at that point, the compiler knows that "anything could happen" at that point, and allocates every local variable to the context just to cater to eval. But the debugger could break anywhere in the code. We are not going to context-allocate everything just because the debugger might inspect the value at any point.


--
You received this message because this project is configured to send all issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" 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/d/optout.

Reply via email to