Commit d7e3697d authored by dslomov's avatar dslomov Committed by Commit bot

harmony-scoping: Implement debugger support for script scope.

We add a new ScopeType, ScopeType.Script. The scope with
ScopeType.Script is always present in the scope chain (ScopeIterator
fakes it if neededi - i.e. if ScriptContext for a script has not been
allocated since that script has no lexical declarations).
ScriptScope reflects ScriptContextTable.

R=yurys@chromium.org,yangguo@chromium.org
BUG=v8:3690
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#25383}
parent e01f34b5
......@@ -193,13 +193,16 @@ PropertyAttribute.DontEnum = DONT_ENUM;
PropertyAttribute.DontDelete = DONT_DELETE;
// A copy of the scope types from runtime.cc.
// A copy of the scope types from runtime-debug.cc.
// NOTE: these constants should be backward-compatible, so
// add new ones to the end of this list.
var ScopeType = { Global: 0,
Local: 1,
With: 2,
Closure: 3,
Catch: 4,
Block: 5 };
Block: 5,
Script: 6 };
// Mirror hierarchy:
......@@ -2309,11 +2312,12 @@ ScopeMirror.prototype.scopeType = function() {
ScopeMirror.prototype.scopeObject = function() {
// For local and closure scopes create a transient mirror as these objects are
// created on the fly materializing the local or closure scopes and
// therefore will not preserve identity.
// For local, closure and script scopes create a transient mirror
// as these objects are created on the fly materializing the local
// or closure scopes and therefore will not preserve identity.
var transient = this.scopeType() == ScopeType.Local ||
this.scopeType() == ScopeType.Closure;
this.scopeType() == ScopeType.Closure ||
this.scopeType() == ScopeType.Script;
return MakeMirror(this.details_.object(), transient);
};
......
......@@ -801,6 +801,29 @@ MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalContext(
}
MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScriptScope(
Handle<GlobalObject> global) {
Isolate* isolate = global->GetIsolate();
Handle<ScriptContextTable> script_contexts(
global->native_context()->script_context_table());
Handle<JSObject> script_scope =
isolate->factory()->NewJSObject(isolate->object_function());
for (int context_index = 0; context_index < script_contexts->used();
context_index++) {
Handle<Context> context =
ScriptContextTable::GetContext(script_contexts, context_index);
Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context,
script_scope)) {
return MaybeHandle<JSObject>();
}
}
return script_scope;
}
MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalScope(
Isolate* isolate, JavaScriptFrame* frame, int inlined_jsframe_index) {
FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
......@@ -997,6 +1020,24 @@ static bool SetBlockContextVariableValue(Handle<Context> block_context,
}
static bool SetScriptVariableValue(Handle<Context> context,
Handle<String> variable_name,
Handle<Object> new_value) {
Handle<ScriptContextTable> script_contexts(
context->global_object()->native_context()->script_context_table());
ScriptContextTable::LookupResult lookup_result;
if (ScriptContextTable::Lookup(script_contexts, variable_name,
&lookup_result)) {
Handle<Context> script_context = ScriptContextTable::GetContext(
script_contexts, lookup_result.context_index);
script_context->set(lookup_result.slot_index, *new_value);
return true;
}
return false;
}
// Create a plain JSObject which materializes the scope for the specified
// catch context.
MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope(
......@@ -1084,6 +1125,7 @@ class ScopeIterator {
ScopeTypeClosure,
ScopeTypeCatch,
ScopeTypeBlock,
ScopeTypeScript,
ScopeTypeModule
};
......@@ -1095,6 +1137,7 @@ class ScopeIterator {
function_(frame->function()),
context_(Context::cast(frame->context())),
nested_scope_chain_(4),
seen_script_scope_(false),
failed_(false) {
// Catch the case when the debugger stops in an internal function.
Handle<SharedFunctionInfo> shared_info(function_->shared());
......@@ -1186,6 +1229,7 @@ class ScopeIterator {
inlined_jsframe_index_(0),
function_(function),
context_(function->context()),
seen_script_scope_(false),
failed_(false) {
if (function->IsBuiltin()) {
context_ = Handle<Context>();
......@@ -1210,8 +1254,16 @@ class ScopeIterator {
context_ = Handle<Context>();
return;
}
if (scope_type == ScopeTypeScript) seen_script_scope_ = true;
if (nested_scope_chain_.is_empty()) {
context_ = Handle<Context>(context_->previous(), isolate_);
if (scope_type == ScopeTypeScript) {
if (context_->IsScriptContext()) {
context_ = Handle<Context>(context_->previous(), isolate_);
}
CHECK(context_->IsNativeContext());
} else {
context_ = Handle<Context>(context_->previous(), isolate_);
}
} else {
if (nested_scope_chain_.last()->HasContext()) {
DCHECK(context_->previous() != NULL);
......@@ -1235,8 +1287,8 @@ class ScopeIterator {
DCHECK(context_->IsModuleContext());
return ScopeTypeModule;
case SCRIPT_SCOPE:
DCHECK(context_->IsNativeContext());
return ScopeTypeGlobal;
DCHECK(context_->IsScriptContext() || context_->IsNativeContext());
return ScopeTypeScript;
case WITH_SCOPE:
DCHECK(context_->IsWithContext());
return ScopeTypeWith;
......@@ -1252,7 +1304,9 @@ class ScopeIterator {
}
if (context_->IsNativeContext()) {
DCHECK(context_->global_object()->IsGlobalObject());
return ScopeTypeGlobal;
// If we are at the native context and have not yet seen script scope,
// fake it.
return seen_script_scope_ ? ScopeTypeGlobal : ScopeTypeScript;
}
if (context_->IsFunctionContext()) {
return ScopeTypeClosure;
......@@ -1266,6 +1320,9 @@ class ScopeIterator {
if (context_->IsModuleContext()) {
return ScopeTypeModule;
}
if (context_->IsScriptContext()) {
return ScopeTypeScript;
}
DCHECK(context_->IsWithContext());
return ScopeTypeWith;
}
......@@ -1276,6 +1333,9 @@ class ScopeIterator {
switch (Type()) {
case ScopeIterator::ScopeTypeGlobal:
return Handle<JSObject>(CurrentContext()->global_object());
case ScopeIterator::ScopeTypeScript:
return MaterializeScriptScope(
Handle<GlobalObject>(CurrentContext()->global_object()));
case ScopeIterator::ScopeTypeLocal:
// Materialize the content of the local scope into a JSObject.
DCHECK(nested_scope_chain_.length() == 1);
......@@ -1314,6 +1374,9 @@ class ScopeIterator {
case ScopeIterator::ScopeTypeClosure:
return SetClosureVariableValue(isolate_, CurrentContext(),
variable_name, new_value);
case ScopeIterator::ScopeTypeScript:
return SetScriptVariableValue(CurrentContext(), variable_name,
new_value);
case ScopeIterator::ScopeTypeBlock:
return SetBlockContextVariableValue(CurrentContext(), variable_name,
new_value);
......@@ -1340,7 +1403,8 @@ class ScopeIterator {
// be an actual context.
Handle<Context> CurrentContext() {
DCHECK(!failed_);
if (Type() == ScopeTypeGlobal || nested_scope_chain_.is_empty()) {
if (Type() == ScopeTypeGlobal || Type() == ScopeTypeScript ||
nested_scope_chain_.is_empty()) {
return context_;
} else if (nested_scope_chain_.last()->HasContext()) {
return context_;
......@@ -1397,6 +1461,15 @@ class ScopeIterator {
}
break;
case ScopeIterator::ScopeTypeScript:
os << "Script:\n";
CurrentContext()
->global_object()
->native_context()
->script_context_table()
->Print(os);
break;
default:
UNREACHABLE();
}
......@@ -1411,6 +1484,7 @@ class ScopeIterator {
Handle<JSFunction> function_;
Handle<Context> context_;
List<Handle<ScopeInfo> > nested_scope_chain_;
bool seen_script_scope_;
bool failed_;
void RetrieveScopeChain(Scope* scope,
......@@ -2175,6 +2249,7 @@ RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
// We iterate to find the function's context. If the function has no
// context-allocated variables, we iterate until we hit the outer context.
while (!function_context->IsFunctionContext() &&
!function_context->IsScriptContext() &&
!function_context.is_identical_to(outer_context)) {
inner_context = function_context;
function_context = Handle<Context>(function_context->previous(), isolate);
......
......@@ -7630,9 +7630,25 @@ static void DebugHarmonyScopingListener(
char script[128];
i::Vector<char> script_vector(script, sizeof(script));
SNPrintF(script_vector, "%%GetFrameCount(%d)", break_id);
v8::Local<v8::Value> result = CompileRun(script);
ExpectInt32(script, 1);
SNPrintF(script_vector, "var frame = new FrameMirror(%d, 0);", break_id);
CompileRun(script);
ExpectInt32("frame.evaluate('x').value_", 1);
ExpectInt32("frame.evaluate('y').value_", 2);
CompileRun("var allScopes = frame.allScopes()");
ExpectInt32("allScopes.length", 2);
CHECK_EQ(1, result->Int32Value());
ExpectBoolean("allScopes[0].scopeType() === ScopeType.Script", true);
ExpectInt32("allScopes[0].scopeObject().value_.x", 1);
ExpectInt32("allScopes[0].scopeObject().value_.y", 2);
CompileRun("allScopes[0].setVariableValue('x', 5);");
CompileRun("allScopes[0].setVariableValue('y', 6);");
ExpectInt32("frame.evaluate('x + y').value_", 11);
}
......@@ -7648,8 +7664,15 @@ TEST(DebugBreakInLexicalScopes) {
CompileRun(
"'use strict'; \n"
"let x = 1; \n");
CompileRun(
ExpectInt32(
"'use strict'; \n"
"let y = 1; \n"
"debugger \n");
"let y = 2; \n"
"debugger; \n"
"x * y",
30);
ExpectInt32(
"x = 1; y = 2; \n"
"debugger;"
"x * y",
30);
}
......@@ -89,9 +89,10 @@ function listener(event, exec_state, event_data, data) {
}
// All frames except the bottom one have two scopes.
assertEquals(2, frame.scopeCount());
assertEquals(3, frame.scopeCount());
assertEquals(debug.ScopeType.Local, frame.scope(0).scopeType());
assertEquals(debug.ScopeType.Global, frame.scope(1).scopeType());
assertEquals(debug.ScopeType.Script, frame.scope(1).scopeType());
assertEquals(debug.ScopeType.Global, frame.scope(2).scopeType());
Object.keys(expected_locals).forEach(function (name) {
assertEquals(expected_locals[name],
......@@ -134,8 +135,9 @@ function listener(event, exec_state, event_data, data) {
frame.evaluate(arguments_sum).value());
} else {
// The bottom frame only have the global scope.
assertEquals(1, frame.scopeCount());
assertEquals(debug.ScopeType.Global, frame.scope(0).scopeType());
assertEquals(2, frame.scopeCount());
assertEquals(debug.ScopeType.Script, frame.scope(0).scopeType());
assertEquals(debug.ScopeType.Global, frame.scope(1).scopeType());
}
// Check the frame function.
......
......@@ -79,10 +79,11 @@ function listener(event, exec_state, event_data, data) {
frame.argumentValue(j).value());
}
// All frames except the bottom one have two scopes.
assertEquals(2, frame.scopeCount());
// All frames except the bottom one have three scopes.
assertEquals(3, frame.scopeCount());
assertEquals(debug.ScopeType.Local, frame.scope(0).scopeType());
assertEquals(debug.ScopeType.Global, frame.scope(1).scopeType());
assertEquals(debug.ScopeType.Script, frame.scope(1).scopeType());
assertEquals(debug.ScopeType.Global, frame.scope(2).scopeType());
Object.keys(expected_locals).forEach(function (name) {
assertEquals(expected_locals[name],
......@@ -124,9 +125,10 @@ function listener(event, exec_state, event_data, data) {
assertEquals(expected_args_sum,
frame.evaluate(arguments_sum).value());
} else {
// The bottom frame only have the global scope.
assertEquals(1, frame.scopeCount());
assertEquals(debug.ScopeType.Global, frame.scope(0).scopeType());
// The bottom frame only have the script scope and the global scope.
assertEquals(2, frame.scopeCount());
assertEquals(debug.ScopeType.Script, frame.scope(0).scopeType());
assertEquals(debug.ScopeType.Global, frame.scope(1).scopeType());
}
// Check the frame function.
......
......@@ -48,7 +48,8 @@ var ScopeType = { Global: 0,
With: 2,
Closure: 3,
Catch: 4,
Block: 5 };
Block: 5,
Script: 6};
var f1 = (function F1(x) {
function F2(y) {
......@@ -68,21 +69,23 @@ var f1 = (function F1(x) {
var mirror = Debug.MakeMirror(f1);
assertEquals(5, mirror.scopeCount());
assertEquals(6, mirror.scopeCount());
CheckScope(mirror.scope(0), { a: 4, b: 5 }, ScopeType.Closure);
CheckScope(mirror.scope(1), { w: 5, v: "Capybara" }, ScopeType.With);
CheckScope(mirror.scope(2), { y: 17, z: 22 }, ScopeType.Closure);
CheckScope(mirror.scope(3), { x: 5 }, ScopeType.Closure);
CheckScope(mirror.scope(4), {}, ScopeType.Global);
CheckScope(mirror.scope(4), {}, ScopeType.Script);
CheckScope(mirror.scope(5), {}, ScopeType.Global);
var f2 = function() { return 5; }
var mirror = Debug.MakeMirror(f2);
assertEquals(1, mirror.scopeCount());
assertEquals(2, mirror.scopeCount());
CheckScope(mirror.scope(0), {}, ScopeType.Global);
CheckScope(mirror.scope(0), {}, ScopeType.Script);
CheckScope(mirror.scope(1), {}, ScopeType.Global);
var f3 = (function F1(invisible_parameter) {
var invisible1 = 1;
......@@ -99,11 +102,12 @@ var f3 = (function F1(invisible_parameter) {
var mirror = Debug.MakeMirror(f3);
assertEquals(3, mirror.scopeCount());
assertEquals(4, mirror.scopeCount());
CheckScope(mirror.scope(0), { visible2: 20 }, ScopeType.Closure);
CheckScope(mirror.scope(1), { visible1: 10 }, ScopeType.Closure);
CheckScope(mirror.scope(2), {}, ScopeType.Global);
CheckScope(mirror.scope(2), {}, ScopeType.Script);
CheckScope(mirror.scope(3), {}, ScopeType.Global);
var f4 = (function One() {
......@@ -122,11 +126,12 @@ var f4 = (function One() {
var mirror = Debug.MakeMirror(f4);
assertEquals(3, mirror.scopeCount());
assertEquals(4, mirror.scopeCount());
CheckScope(mirror.scope(0), { e2: "I'm error 2" }, ScopeType.Catch);
CheckScope(mirror.scope(1), { e1: "I'm error 1" }, ScopeType.Catch);
CheckScope(mirror.scope(2), {}, ScopeType.Global);
CheckScope(mirror.scope(2), {}, ScopeType.Script);
CheckScope(mirror.scope(3), {}, ScopeType.Global);
var f5 = (function Raz(p1, p2) {
......@@ -141,11 +146,12 @@ var f5 = (function Raz(p1, p2) {
var mirror = Debug.MakeMirror(f5);
assertEquals(3, mirror.scopeCount());
assertEquals(4, mirror.scopeCount());
CheckScope(mirror.scope(0), { p4: 20, p6: 22 }, ScopeType.Closure);
CheckScope(mirror.scope(1), { p1: 1 }, ScopeType.Closure);
CheckScope(mirror.scope(2), {}, ScopeType.Global);
CheckScope(mirror.scope(2), {}, ScopeType.Script);
CheckScope(mirror.scope(3), {}, ScopeType.Global);
function CheckNoScopeVisible(f) {
......
This diff is collapsed.
......@@ -97,6 +97,7 @@ function CheckScopeChain(scopes, exec_state) {
assertEquals(i, response.body.scopes[i].index);
assertEquals(scopes[i], response.body.scopes[i].type);
if (scopes[i] == debug.ScopeType.Local ||
scopes[i] == debug.ScopeType.Script ||
scopes[i] == debug.ScopeType.Closure) {
assertTrue(response.body.scopes[i].object.ref < 0);
} else {
......@@ -159,6 +160,7 @@ function CheckScopeContent(content, number, exec_state) {
assertEquals(scope.scopeType(), response.body.type);
assertEquals(number, response.body.index);
if (scope.scopeType() == debug.ScopeType.Local ||
scope.scopeType() == debug.ScopeType.Script ||
scope.scopeType() == debug.ScopeType.Closure) {
assertTrue(response.body.object.ref < 0);
} else {
......@@ -178,6 +180,7 @@ RunTest("Local 1",
[],
function (exec_state) {
CheckScopeChain([debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({}, 0, exec_state);
});
......@@ -188,6 +191,7 @@ RunTest("Local 2",
[1],
function (exec_state) {
CheckScopeChain([debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({a:1}, 0, exec_state);
});
......@@ -198,6 +202,7 @@ RunTest("Local 3",
[1],
function (exec_state) {
CheckScopeChain([debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({a:1,x:3}, 0, exec_state);
});
......@@ -208,6 +213,7 @@ RunTest("Local 4",
[1, 2],
function (exec_state) {
CheckScopeChain([debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
});
......@@ -218,6 +224,7 @@ RunTest("Local 5",
[],
function (exec_state) {
CheckScopeChain([debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({}, 0, exec_state);
});
......@@ -228,6 +235,7 @@ RunTest("Local 6",
[],
function (exec_state) {
CheckScopeChain([debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({i:5}, 0, exec_state);
});
......@@ -242,6 +250,7 @@ RunTest("Local 7",
[1, 2],
function (exec_state) {
CheckScopeChain([debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 0, exec_state);
});
......@@ -254,6 +263,7 @@ RunTest("With",
CheckScopeChain([debug.ScopeType.With,
debug.ScopeType.With,
debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({}, 0, exec_state);
CheckScopeContent({}, 1, exec_state);
......@@ -267,6 +277,7 @@ RunTest("Closure 1",
function (exec_state) {
CheckScopeChain([debug.ScopeType.Local,
debug.ScopeType.Closure,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({a:1}, 1, exec_state);
},
......@@ -305,6 +316,7 @@ RunTest("The full monty",
debug.ScopeType.With,
debug.ScopeType.Closure,
debug.ScopeType.Closure,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({b:16}, 0, exec_state);
CheckScopeContent({a:15}, 1, exec_state);
......@@ -321,6 +333,7 @@ RunTest("Catch block 1",
function (exec_state) {
CheckScopeChain([debug.ScopeType.Catch,
debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({e:'Exception'}, 0, exec_state);
});
......@@ -73,7 +73,7 @@ function BeginTest(name) {
// Check result of a test.
function EndTest() {
assertTrue(listener_called, "listerner not called for " + test_name);
assertNull(exception, test_name);
assertNull(exception, test_name, exception);
end_test_count++;
}
......@@ -108,6 +108,7 @@ function CheckScopeChain(scopes, exec_state) {
assertEquals(i, response.body.scopes[i].index);
assertEquals(scopes[i], response.body.scopes[i].type);
if (scopes[i] == debug.ScopeType.Local ||
scopes[i] == debug.ScopeType.Script ||
scopes[i] == debug.ScopeType.Closure) {
assertTrue(response.body.scopes[i].object.ref < 0);
} else {
......@@ -197,6 +198,7 @@ function local_block_1() {
listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({}, 0, exec_state);
};
......@@ -215,6 +217,7 @@ function local_2(a) {
listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({a:1}, 0, exec_state);
};
......@@ -232,6 +235,7 @@ function local_3(a) {
listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({a:1,x:3}, 0, exec_state);
};
......@@ -250,6 +254,7 @@ function local_4(a, b) {
listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
};
......@@ -270,6 +275,7 @@ function local_5(a) {
listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Block,
debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({x:5}, 0, exec_state);
CheckScopeContent({a:1}, 1, exec_state);
......@@ -292,6 +298,7 @@ function local_6(a) {
listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Block,
debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({x:6,y:7}, 0, exec_state);
CheckScopeContent({a:1}, 1, exec_state);
......@@ -315,6 +322,7 @@ function local_7(a) {
listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Block,
debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({x:8}, 0, exec_state);
CheckScopeContent({a:1}, 1, exec_state);
......@@ -344,6 +352,7 @@ listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Local,
debug.ScopeType.Block,
debug.ScopeType.Closure,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({}, 0, exec_state);
CheckScopeContent({a:1,x:2,y:3}, 2, exec_state);
......@@ -364,6 +373,7 @@ function for_loop_1() {
listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Block,
debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({x:'y'}, 0, exec_state);
// The function scope contains a temporary iteration variable, but it is
......@@ -389,6 +399,7 @@ listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Block,
debug.ScopeType.Block,
debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({x:3}, 0, exec_state);
CheckScopeContent({x:'y'}, 1, exec_state);
......@@ -413,6 +424,7 @@ listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Block,
debug.ScopeType.Block,
debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({x:3}, 0, exec_state);
CheckScopeContent({x:3}, 1, exec_state);
......@@ -437,6 +449,7 @@ listener_delegate = function(exec_state) {
debug.ScopeType.Block,
debug.ScopeType.Block,
debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({x:5}, 0, exec_state);
CheckScopeContent({x:3}, 1, exec_state);
......@@ -460,6 +473,7 @@ listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Block,
debug.ScopeType.Block,
debug.ScopeType.Local,
debug.ScopeType.Script,
debug.ScopeType.Global], exec_state);
CheckScopeContent({x:3,y:5}, 0, exec_state);
CheckScopeContent({x:3,y:5}, 1, exec_state);
......
......@@ -28,6 +28,7 @@
// Flags: --expose-debug-as debug --harmony-scoping
"use strict";
let top_level_let = 255;
// Get the Debug object exposed from the debug context global object.
var Debug = debug.Debug;
......@@ -50,7 +51,8 @@ var ScopeType = { Global: 0,
With: 2,
Closure: 3,
Catch: 4,
Block: 5 };
Block: 5,
Script: 6};
var f1 = (function F1(x) {
function F2(y) {
......@@ -72,12 +74,13 @@ var f1 = (function F1(x) {
var mirror = Debug.MakeMirror(f1);
assertEquals(4, mirror.scopeCount());
assertEquals(5, mirror.scopeCount());
CheckScope(mirror.scope(0), { a: 4, b: 5 }, ScopeType.Closure);
CheckScope(mirror.scope(1), { z: 22, w: 5, v: "Capybara" }, ScopeType.Closure);
CheckScope(mirror.scope(2), { x: 5 }, ScopeType.Closure);
CheckScope(mirror.scope(3), {}, ScopeType.Global);
CheckScope(mirror.scope(3), { top_level_let: 255 }, ScopeType.Script);
CheckScope(mirror.scope(4), {}, ScopeType.Global);
var f2 = (function() {
var v1 = 3;
......@@ -104,7 +107,7 @@ var f2 = (function() {
var mirror = Debug.MakeMirror(f2);
assertEquals(5, mirror.scopeCount());
assertEquals(6, mirror.scopeCount());
// Implementation artifact: l4 isn't used in closure, but still it is saved.
CheckScope(mirror.scope(0), { l4: 11 }, ScopeType.Block);
......@@ -112,4 +115,5 @@ CheckScope(mirror.scope(0), { l4: 11 }, ScopeType.Block);
CheckScope(mirror.scope(1), { l3: 9 }, ScopeType.Block);
CheckScope(mirror.scope(2), { l1: 6, l2: 7 }, ScopeType.Block);
CheckScope(mirror.scope(3), { v1:3, l0: 0, v3: 5, v6: 11 }, ScopeType.Closure);
CheckScope(mirror.scope(4), {}, ScopeType.Global);
CheckScope(mirror.scope(4), { top_level_let: 255 }, ScopeType.Script);
CheckScope(mirror.scope(5), {}, ScopeType.Global);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment