Commit 5870529d authored by kozyatinskiy's avatar kozyatinskiy Committed by Commit bot

[inspector] introduced debug::GeneratorObject

- removed getGeneratorObjectLocation from debugger-script.js,
- one more step to remove all debugger context usages in inspector.

BUG=v8:5510
R=yangguo@chromium.org,jgruber@chromium.org,alph@chromium.org

Review-Url: https://codereview.chromium.org/2678143002
Cr-Commit-Position: refs/heads/master@{#43018}
parent e7b78ac2
......@@ -9290,7 +9290,9 @@ debug::Location::Location(int line_number, int column_number)
CHECK(column_number >= 0);
}
debug::Location::Location() : line_number_(-1), column_number_(-1) {}
debug::Location::Location()
: line_number_(v8::Function::kLineOffsetNotFound),
column_number_(v8::Function::kLineOffsetNotFound) {}
int debug::Location::GetLineNumber() const {
CHECK(line_number_ >= 0);
......@@ -9414,6 +9416,41 @@ v8::MaybeLocal<v8::Array> debug::EntriesPreview(Isolate* v8_isolate,
return v8::MaybeLocal<v8::Array>();
}
MaybeLocal<debug::Script> debug::GeneratorObject::Script() {
i::Handle<i::JSGeneratorObject> obj = Utils::OpenHandle(this);
i::Object* maybe_script = obj->function()->shared()->script();
if (!maybe_script->IsScript()) return MaybeLocal<debug::Script>();
i::Handle<i::Script> script(i::Script::cast(maybe_script), obj->GetIsolate());
return ToApiHandle<debug::Script>(script);
}
Local<Function> debug::GeneratorObject::Function() {
i::Handle<i::JSGeneratorObject> obj = Utils::OpenHandle(this);
return Utils::ToLocal(handle(obj->function()));
}
debug::Location debug::GeneratorObject::SuspendedLocation() {
i::Handle<i::JSGeneratorObject> obj = Utils::OpenHandle(this);
CHECK(obj->is_suspended());
i::Object* maybe_script = obj->function()->shared()->script();
if (!maybe_script->IsScript()) return debug::Location();
i::Handle<i::Script> script(i::Script::cast(maybe_script), obj->GetIsolate());
i::Script::PositionInfo info;
i::Script::GetPositionInfo(script, obj->source_position(), &info,
i::Script::WITH_OFFSET);
return debug::Location(info.line, info.column);
}
bool debug::GeneratorObject::IsSuspended() {
return Utils::OpenHandle(this)->is_suspended();
}
v8::Local<debug::GeneratorObject> debug::GeneratorObject::Cast(
v8::Local<v8::Value> value) {
CHECK(value->IsGeneratorObject());
return ToApiHandle<debug::GeneratorObject>(Utils::OpenHandle(*value));
}
Local<String> CpuProfileNode::GetFunctionName() const {
const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
i::Isolate* isolate = node->isolate();
......
......@@ -69,46 +69,47 @@ class RegisteredExtension {
static RegisteredExtension* first_extension_;
};
#define OPEN_HANDLE_LIST(V) \
V(Template, TemplateInfo) \
V(FunctionTemplate, FunctionTemplateInfo) \
V(ObjectTemplate, ObjectTemplateInfo) \
V(Signature, FunctionTemplateInfo) \
V(AccessorSignature, FunctionTemplateInfo) \
V(Data, Object) \
V(RegExp, JSRegExp) \
V(Object, JSReceiver) \
V(Array, JSArray) \
V(Map, JSMap) \
V(Set, JSSet) \
V(ArrayBuffer, JSArrayBuffer) \
V(ArrayBufferView, JSArrayBufferView) \
V(TypedArray, JSTypedArray) \
V(Uint8Array, JSTypedArray) \
V(Uint8ClampedArray, JSTypedArray) \
V(Int8Array, JSTypedArray) \
V(Uint16Array, JSTypedArray) \
V(Int16Array, JSTypedArray) \
V(Uint32Array, JSTypedArray) \
V(Int32Array, JSTypedArray) \
V(Float32Array, JSTypedArray) \
V(Float64Array, JSTypedArray) \
V(DataView, JSDataView) \
V(SharedArrayBuffer, JSArrayBuffer) \
V(Name, Name) \
V(String, String) \
V(Symbol, Symbol) \
V(Script, JSFunction) \
V(UnboundScript, SharedFunctionInfo) \
V(Module, Module) \
V(Function, JSReceiver) \
V(Message, JSMessageObject) \
V(Context, Context) \
V(External, Object) \
V(StackTrace, JSArray) \
V(StackFrame, JSObject) \
V(Proxy, JSProxy) \
V(NativeWeakMap, JSWeakMap) \
#define OPEN_HANDLE_LIST(V) \
V(Template, TemplateInfo) \
V(FunctionTemplate, FunctionTemplateInfo) \
V(ObjectTemplate, ObjectTemplateInfo) \
V(Signature, FunctionTemplateInfo) \
V(AccessorSignature, FunctionTemplateInfo) \
V(Data, Object) \
V(RegExp, JSRegExp) \
V(Object, JSReceiver) \
V(Array, JSArray) \
V(Map, JSMap) \
V(Set, JSSet) \
V(ArrayBuffer, JSArrayBuffer) \
V(ArrayBufferView, JSArrayBufferView) \
V(TypedArray, JSTypedArray) \
V(Uint8Array, JSTypedArray) \
V(Uint8ClampedArray, JSTypedArray) \
V(Int8Array, JSTypedArray) \
V(Uint16Array, JSTypedArray) \
V(Int16Array, JSTypedArray) \
V(Uint32Array, JSTypedArray) \
V(Int32Array, JSTypedArray) \
V(Float32Array, JSTypedArray) \
V(Float64Array, JSTypedArray) \
V(DataView, JSDataView) \
V(SharedArrayBuffer, JSArrayBuffer) \
V(Name, Name) \
V(String, String) \
V(Symbol, Symbol) \
V(Script, JSFunction) \
V(UnboundScript, SharedFunctionInfo) \
V(Module, Module) \
V(Function, JSReceiver) \
V(Message, JSMessageObject) \
V(Context, Context) \
V(External, Object) \
V(StackTrace, JSArray) \
V(StackFrame, JSObject) \
V(Proxy, JSProxy) \
V(NativeWeakMap, JSWeakMap) \
V(debug::GeneratorObject, JSGeneratorObject) \
V(debug::Script, Script)
class Utils {
......
......@@ -182,6 +182,19 @@ v8::MaybeLocal<v8::Array> EntriesPreview(Isolate* isolate,
v8::Local<v8::Value> value,
bool* is_key_value);
/**
* Native wrapper around v8::internal::JSGeneratorObject object.
*/
class GeneratorObject {
public:
v8::MaybeLocal<debug::Script> Script();
v8::Local<v8::Function> Function();
debug::Location SuspendedLocation();
bool IsSuspended();
static v8::Local<debug::GeneratorObject> Cast(v8::Local<v8::Value> value);
};
} // namespace debug
} // namespace v8
......
......@@ -101,31 +101,6 @@ DebuggerScript.getGeneratorScopes = function(gen)
return result;
}
/**
* @param {Object} object
* @return {?RawLocation}
*/
DebuggerScript.getGeneratorObjectLocation = function(object)
{
var mirror = MakeMirror(object);
if (!mirror.isGenerator())
return null;
var generatorMirror = /** @type {!GeneratorMirror} */(mirror);
var funcMirror = generatorMirror.func();
if (!funcMirror.resolved())
return null;
var location = generatorMirror.sourceLocation() || funcMirror.sourceLocation();
var script = funcMirror.script();
if (script && location) {
return {
scriptId: "" + script.id(),
lineNumber: location.line,
columnNumber: location.column
};
}
return null;
}
/**
* @param {!ExecutionState} execState
* @param {!BreakpointInfo} info
......
......@@ -306,15 +306,6 @@ function UnresolvedFunctionMirror(value) {}
*/
function GeneratorMirror () {}
/** @return {string} */
GeneratorMirror.prototype.status = function() {}
/** @return {!SourceLocation|undefined} */
GeneratorMirror.prototype.sourceLocation = function() {}
/** @return {!FunctionMirror} */
GeneratorMirror.prototype.func = function() {}
/** @return {number} */
GeneratorMirror.prototype.scopeCount = function() {}
......
......@@ -80,6 +80,62 @@ v8::MaybeLocal<v8::Array> collectionsEntries(v8::Local<v8::Context> context,
return wrappedEntries;
}
v8::MaybeLocal<v8::Object> buildLocation(v8::Local<v8::Context> context,
int scriptId, int lineNumber,
int columnNumber) {
if (scriptId == v8::UnboundScript::kNoScriptId)
return v8::MaybeLocal<v8::Object>();
if (lineNumber == v8::Function::kLineOffsetNotFound ||
columnNumber == v8::Function::kLineOffsetNotFound) {
return v8::MaybeLocal<v8::Object>();
}
v8::Isolate* isolate = context->GetIsolate();
v8::Local<v8::Object> location = v8::Object::New(isolate);
if (!location->SetPrototype(context, v8::Null(isolate)).FromMaybe(false)) {
return v8::MaybeLocal<v8::Object>();
}
if (!createDataProperty(context, location,
toV8StringInternalized(isolate, "scriptId"),
toV8String(isolate, String16::fromInteger(scriptId)))
.FromMaybe(false)) {
return v8::MaybeLocal<v8::Object>();
}
if (!createDataProperty(context, location,
toV8StringInternalized(isolate, "lineNumber"),
v8::Integer::New(isolate, lineNumber))
.FromMaybe(false)) {
return v8::MaybeLocal<v8::Object>();
}
if (!createDataProperty(context, location,
toV8StringInternalized(isolate, "columnNumber"),
v8::Integer::New(isolate, columnNumber))
.FromMaybe(false)) {
return v8::MaybeLocal<v8::Object>();
}
if (!markAsInternal(context, location, V8InternalValueType::kLocation)) {
return v8::MaybeLocal<v8::Object>();
}
return location;
}
v8::MaybeLocal<v8::Object> generatorObjectLocation(
v8::Local<v8::Context> context, v8::Local<v8::Value> value) {
if (!value->IsGeneratorObject()) return v8::MaybeLocal<v8::Object>();
v8::Local<v8::debug::GeneratorObject> generatorObject =
v8::debug::GeneratorObject::Cast(value);
if (!generatorObject->IsSuspended()) {
v8::Local<v8::Function> func = generatorObject->Function();
return buildLocation(context, func->ScriptId(), func->GetScriptLineNumber(),
func->GetScriptColumnNumber());
}
v8::Local<v8::debug::Script> script;
if (!generatorObject->Script().ToLocal(&script))
return v8::MaybeLocal<v8::Object>();
v8::debug::Location suspendedLocation = generatorObject->SuspendedLocation();
return buildLocation(context, script->Id(), suspendedLocation.GetLineNumber(),
suspendedLocation.GetColumnNumber());
}
} // namespace
static bool inLiveEditScope = false;
......@@ -707,8 +763,11 @@ v8::MaybeLocal<v8::Array> V8Debugger::internalProperties(
return v8::MaybeLocal<v8::Array>();
if (value->IsFunction()) {
v8::Local<v8::Function> function = value.As<v8::Function>();
v8::Local<v8::Value> location = functionLocation(context, function);
if (location->IsObject()) {
v8::Local<v8::Object> location;
if (buildLocation(context, function->ScriptId(),
function->GetScriptLineNumber(),
function->GetScriptColumnNumber())
.ToLocal(&location)) {
createDataProperty(
context, properties, properties->Length(),
toV8StringInternalized(m_isolate, "[[FunctionLocation]]"));
......@@ -727,16 +786,15 @@ v8::MaybeLocal<v8::Array> V8Debugger::internalProperties(
toV8StringInternalized(m_isolate, "[[Entries]]"));
createDataProperty(context, properties, properties->Length(), entries);
}
if (!enabled()) return properties;
if (value->IsGeneratorObject()) {
v8::Local<v8::Value> location =
generatorObjectLocation(context, v8::Local<v8::Object>::Cast(value));
if (location->IsObject()) {
v8::Local<v8::Object> location;
if (generatorObjectLocation(context, value).ToLocal(&location)) {
createDataProperty(
context, properties, properties->Length(),
toV8StringInternalized(m_isolate, "[[GeneratorLocation]]"));
createDataProperty(context, properties, properties->Length(), location);
}
if (!enabled()) return properties;
v8::Local<v8::Value> scopes;
if (generatorScopes(context, value).ToLocal(&scopes)) {
createDataProperty(context, properties, properties->Length(),
......@@ -744,6 +802,7 @@ v8::MaybeLocal<v8::Array> V8Debugger::internalProperties(
createDataProperty(context, properties, properties->Length(), scopes);
}
}
if (!enabled()) return properties;
if (value->IsFunction()) {
v8::Local<v8::Function> function = value.As<v8::Function>();
v8::Local<v8::Value> boundFunction = function->GetBoundFunction();
......@@ -758,60 +817,6 @@ v8::MaybeLocal<v8::Array> V8Debugger::internalProperties(
return properties;
}
v8::Local<v8::Value> V8Debugger::generatorObjectLocation(
v8::Local<v8::Context> context, v8::Local<v8::Object> object) {
if (!enabled()) {
UNREACHABLE();
return v8::Null(m_isolate);
}
v8::Local<v8::Value> argv[] = {object};
v8::Local<v8::Value> location;
v8::Local<v8::Value> copied;
if (!callDebuggerMethod("getGeneratorObjectLocation", 1, argv, true)
.ToLocal(&location) ||
!copyValueFromDebuggerContext(m_isolate, debuggerContext(), context,
location)
.ToLocal(&copied) ||
!copied->IsObject())
return v8::Null(m_isolate);
if (!markAsInternal(context, v8::Local<v8::Object>::Cast(copied),
V8InternalValueType::kLocation))
return v8::Null(m_isolate);
return copied;
}
v8::Local<v8::Value> V8Debugger::functionLocation(
v8::Local<v8::Context> context, v8::Local<v8::Function> function) {
int scriptId = function->ScriptId();
if (scriptId == v8::UnboundScript::kNoScriptId) return v8::Null(m_isolate);
int lineNumber = function->GetScriptLineNumber();
int columnNumber = function->GetScriptColumnNumber();
if (lineNumber == v8::Function::kLineOffsetNotFound ||
columnNumber == v8::Function::kLineOffsetNotFound)
return v8::Null(m_isolate);
v8::Local<v8::Object> location = v8::Object::New(m_isolate);
if (!location->SetPrototype(context, v8::Null(m_isolate)).FromMaybe(false))
return v8::Null(m_isolate);
if (!createDataProperty(
context, location, toV8StringInternalized(m_isolate, "scriptId"),
toV8String(m_isolate, String16::fromInteger(scriptId)))
.FromMaybe(false))
return v8::Null(m_isolate);
if (!createDataProperty(context, location,
toV8StringInternalized(m_isolate, "lineNumber"),
v8::Integer::New(m_isolate, lineNumber))
.FromMaybe(false))
return v8::Null(m_isolate);
if (!createDataProperty(context, location,
toV8StringInternalized(m_isolate, "columnNumber"),
v8::Integer::New(m_isolate, columnNumber))
.FromMaybe(false))
return v8::Null(m_isolate);
if (!markAsInternal(context, location, V8InternalValueType::kLocation))
return v8::Null(m_isolate);
return location;
}
std::unique_ptr<V8StackTraceImpl> V8Debugger::createStackTrace(
v8::Local<v8::StackTrace> stackTrace) {
int contextGroupId =
......
......@@ -113,11 +113,6 @@ class V8Debugger : public v8::debug::DebugDelegate {
bool isPromiseRejection = false,
bool isUncaught = false);
v8::Local<v8::Value> generatorObjectLocation(v8::Local<v8::Context>,
v8::Local<v8::Object>);
v8::Local<v8::Value> functionLocation(v8::Local<v8::Context>,
v8::Local<v8::Function>);
enum ScopeTargetKind {
FUNCTION,
GENERATOR,
......
......@@ -184,7 +184,7 @@ expression: new Promise(() => undefined)
}
Running test: generatorObject
expression: (function* foo() { yield 1 })()
expression: gen1
{
id : <messageId>
result : {
......@@ -200,7 +200,7 @@ expression: (function* foo() { yield 1 })()
name : [[GeneratorFunction]]
value : {
className : GeneratorFunction
description : function* foo() { yield 1 }
description : function* foo() { yield 1; }
objectId : <objectId>
type : function
}
......@@ -221,8 +221,120 @@ expression: (function* foo() { yield 1 })()
subtype : internal#location
type : object
value : {
columnNumber : 14
lineNumber : 0
columnNumber : 13
lineNumber : 8
scriptId : <scriptId>
}
}
}
[4] : {
name : [[Scopes]]
value : {
className : Array
description : Scopes[2]
objectId : <objectId>
subtype : internal#scopeList
type : object
}
}
]
}
}
expression: gen1.next();gen1
{
id : <messageId>
result : {
internalProperties : [
[0] : {
name : [[GeneratorStatus]]
value : {
type : string
value : suspended
}
}
[1] : {
name : [[GeneratorFunction]]
value : {
className : GeneratorFunction
description : function* foo() { yield 1; }
objectId : <objectId>
type : function
}
}
[2] : {
name : [[GeneratorReceiver]]
value : {
className : global
description : global
objectId : <objectId>
type : object
}
}
[3] : {
name : [[GeneratorLocation]]
value : {
description : Object
subtype : internal#location
type : object
value : {
columnNumber : 2
lineNumber : 9
scriptId : <scriptId>
}
}
}
[4] : {
name : [[Scopes]]
value : {
className : Array
description : Scopes[2]
objectId : <objectId>
subtype : internal#scopeList
type : object
}
}
]
}
}
expression: gen1.next();gen1
{
id : <messageId>
result : {
internalProperties : [
[0] : {
name : [[GeneratorStatus]]
value : {
type : string
value : closed
}
}
[1] : {
name : [[GeneratorFunction]]
value : {
className : GeneratorFunction
description : function* foo() { yield 1; }
objectId : <objectId>
type : function
}
}
[2] : {
name : [[GeneratorReceiver]]
value : {
className : global
description : global
objectId : <objectId>
type : object
}
}
[3] : {
name : [[GeneratorLocation]]
value : {
description : Object
subtype : internal#location
type : object
value : {
columnNumber : 13
lineNumber : 8
scriptId : <scriptId>
}
}
......@@ -241,6 +353,146 @@ expression: (function* foo() { yield 1 })()
}
}
Running test: generatorObjectDebuggerDisabled
expression: gen2
{
id : <messageId>
result : {
internalProperties : [
[0] : {
name : [[GeneratorStatus]]
value : {
type : string
value : suspended
}
}
[1] : {
name : [[GeneratorFunction]]
value : {
className : GeneratorFunction
description : function* foo() { yield 1; }
objectId : <objectId>
type : function
}
}
[2] : {
name : [[GeneratorReceiver]]
value : {
className : global
description : global
objectId : <objectId>
type : object
}
}
[3] : {
name : [[GeneratorLocation]]
value : {
description : Object
subtype : internal#location
type : object
value : {
columnNumber : 13
lineNumber : 8
scriptId : <scriptId>
}
}
}
]
}
}
expression: gen2.next();gen2
{
id : <messageId>
result : {
internalProperties : [
[0] : {
name : [[GeneratorStatus]]
value : {
type : string
value : suspended
}
}
[1] : {
name : [[GeneratorFunction]]
value : {
className : GeneratorFunction
description : function* foo() { yield 1; }
objectId : <objectId>
type : function
}
}
[2] : {
name : [[GeneratorReceiver]]
value : {
className : global
description : global
objectId : <objectId>
type : object
}
}
[3] : {
name : [[GeneratorLocation]]
value : {
description : Object
subtype : internal#location
type : object
value : {
columnNumber : 2
lineNumber : 9
scriptId : <scriptId>
}
}
}
]
}
}
expression: gen2.next();gen2
{
id : <messageId>
result : {
internalProperties : [
[0] : {
name : [[GeneratorStatus]]
value : {
type : string
value : closed
}
}
[1] : {
name : [[GeneratorFunction]]
value : {
className : GeneratorFunction
description : function* foo() { yield 1; }
objectId : <objectId>
type : function
}
}
[2] : {
name : [[GeneratorReceiver]]
value : {
className : global
description : global
objectId : <objectId>
type : object
}
}
[3] : {
name : [[GeneratorLocation]]
value : {
description : Object
subtype : internal#location
type : object
value : {
columnNumber : 13
lineNumber : 8
scriptId : <scriptId>
}
}
}
]
}
}
Running test: iteratorObject
expression: (new Map([[1,2]])).entries()
{
......
......@@ -4,6 +4,14 @@
print('Checks internal properties in Runtime.getProperties output');
InspectorTest.addScript(`
function* foo() {
yield 1;
}
var gen1 = foo();
var gen2 = foo();
//# sourceURL=test.js`, 7, 26);
Protocol.Runtime.enable();
Protocol.Debugger.enable();
......@@ -31,7 +39,17 @@ InspectorTest.runTestSuite([
},
function generatorObject(next) {
checkExpression('(function* foo() { yield 1 })()')
checkExpression('gen1')
.then(() => checkExpression('gen1.next();gen1'))
.then(() => checkExpression('gen1.next();gen1'))
.then(next);
},
function generatorObjectDebuggerDisabled(next) {
Protocol.Debugger.disable()
.then(() => checkExpression('gen2'))
.then(() => checkExpression('gen2.next();gen2'))
.then(() => checkExpression('gen2.next();gen2'))
.then(next);
},
......
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