Context-allocate all parameters in generators
authorwingo@igalia.com <wingo@igalia.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 22 Apr 2014 11:34:16 +0000 (11:34 +0000)
committerwingo@igalia.com <wingo@igalia.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 22 Apr 2014 11:34:16 +0000 (11:34 +0000)
Generator function scopes have forced context allocation.  Ensure that
all variables in such scopes get context allocation -- even unused
variables.

This fixes an assertion when reifying generator scopes in the debugger.

R=yangguo@chromium.org
LOG=Y
BUG=v8:3280

Review URL: https://codereview.chromium.org/246733003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20883 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/scopes.cc
test/mjsunit/regress/regress-3280.js [new file with mode: 0644]

index 4c4729e69ceee1d55624ddc4d278e3dec1b92495..833198ca0d4b9af508a272a7d81c83b80ba70c77 100644 (file)
@@ -1266,7 +1266,7 @@ void Scope::AllocateParameterLocals() {
   for (int i = params_.length() - 1; i >= 0; --i) {
     Variable* var = params_[i];
     ASSERT(var->scope() == this);
-    if (uses_sloppy_arguments) {
+    if (uses_sloppy_arguments || has_forced_context_allocation()) {
       // Force context allocation of the parameter.
       var->ForceContextAllocation();
     }
diff --git a/test/mjsunit/regress/regress-3280.js b/test/mjsunit/regress/regress-3280.js
new file mode 100644 (file)
index 0000000..2fc72cc
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-generators --expose-debug-as debug
+
+var Debug = debug.Debug;
+
+var listener_called;
+
+function listener(event, exec_state, event_data, data) {
+  if (event == Debug.DebugEvent.Break) {
+    listener_called = true;
+    exec_state.frame().allScopes();
+  }
+}
+
+Debug.setListener(listener);
+
+function *generator_local_2(a) {
+  debugger;
+}
+generator_local_2(1).next();
+
+assertTrue(listener_called, "listener not called");