Index: src/inspector/v8-value-copier.cc |
diff --git a/src/inspector/v8-value-copier.cc b/src/inspector/v8-value-copier.cc |
index 09d86b7b98501679f672b6872763ed06ed725ad6..fcaeb618ca2316940379c0d1b7b2ef25aec762fc 100644 |
--- a/src/inspector/v8-value-copier.cc |
+++ b/src/inspector/v8-value-copier.cc |
@@ -73,6 +73,96 @@ class V8ValueCopier { |
int m_calls; |
}; |
+protocol::Response toProtocolValue(v8::Local<v8::Context> context, |
+ v8::Local<v8::Value> value, int maxDepth, |
+ std::unique_ptr<protocol::Value>* result) { |
+ using protocol::Response; |
+ if (value.IsEmpty()) { |
+ UNREACHABLE(); |
+ return Response::InternalError(); |
+ } |
+ |
+ if (!maxDepth) return Response::Error("Object reference chain is too long"); |
+ maxDepth--; |
+ |
+ if (value->IsNull() || value->IsUndefined()) { |
+ *result = protocol::Value::null(); |
+ return Response::OK(); |
+ } |
+ if (value->IsBoolean()) { |
+ *result = |
+ protocol::FundamentalValue::create(value.As<v8::Boolean>()->Value()); |
+ return Response::OK(); |
+ } |
+ if (value->IsNumber()) { |
+ double doubleValue = value.As<v8::Number>()->Value(); |
+ int intValue = static_cast<int>(doubleValue); |
+ if (intValue == doubleValue) { |
+ *result = protocol::FundamentalValue::create(intValue); |
+ return Response::OK(); |
+ } |
+ *result = protocol::FundamentalValue::create(doubleValue); |
+ return Response::OK(); |
+ } |
+ if (value->IsString()) { |
+ *result = |
+ protocol::StringValue::create(toProtocolString(value.As<v8::String>())); |
+ return Response::OK(); |
+ } |
+ if (value->IsArray()) { |
+ v8::Local<v8::Array> array = value.As<v8::Array>(); |
+ std::unique_ptr<protocol::ListValue> inspectorArray = |
+ protocol::ListValue::create(); |
+ uint32_t length = array->Length(); |
+ for (uint32_t i = 0; i < length; i++) { |
+ v8::Local<v8::Value> value; |
+ if (!array->Get(context, i).ToLocal(&value)) |
+ return Response::InternalError(); |
+ std::unique_ptr<protocol::Value> element; |
+ Response response = toProtocolValue(context, value, maxDepth, &element); |
+ if (!response.isSuccess()) return response; |
+ inspectorArray->pushValue(std::move(element)); |
+ } |
+ *result = std::move(inspectorArray); |
+ return Response::OK(); |
+ } |
+ if (value->IsObject()) { |
+ std::unique_ptr<protocol::DictionaryValue> jsonObject = |
+ protocol::DictionaryValue::create(); |
+ v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value); |
+ v8::Local<v8::Array> propertyNames; |
+ if (!object->GetPropertyNames(context).ToLocal(&propertyNames)) |
+ return Response::InternalError(); |
+ uint32_t length = propertyNames->Length(); |
+ for (uint32_t i = 0; i < length; i++) { |
+ v8::Local<v8::Value> name; |
+ if (!propertyNames->Get(context, i).ToLocal(&name)) |
+ return Response::InternalError(); |
+ // FIXME(yurys): v8::Object should support GetOwnPropertyNames |
+ if (name->IsString()) { |
+ v8::Maybe<bool> hasRealNamedProperty = object->HasRealNamedProperty( |
+ context, v8::Local<v8::String>::Cast(name)); |
+ if (!hasRealNamedProperty.IsJust() || !hasRealNamedProperty.FromJust()) |
+ continue; |
+ } |
+ v8::Local<v8::String> propertyName; |
+ if (!name->ToString(context).ToLocal(&propertyName)) continue; |
+ v8::Local<v8::Value> property; |
+ if (!object->Get(context, name).ToLocal(&property)) |
+ return Response::InternalError(); |
+ std::unique_ptr<protocol::Value> propertyValue; |
+ Response response = |
+ toProtocolValue(context, property, maxDepth, &propertyValue); |
+ if (!response.isSuccess()) return response; |
+ jsonObject->setValue(toProtocolString(propertyName), |
+ std::move(propertyValue)); |
+ } |
+ *result = std::move(jsonObject); |
+ return Response::OK(); |
+ } |
+ return Response::Error("Object couldn't be returned by value"); |
+} |
+ |
} // namespace |
v8::MaybeLocal<v8::Value> copyValueFromDebuggerContext( |
@@ -107,4 +197,10 @@ v8::Maybe<bool> createDataProperty(v8::Local<v8::Context> context, |
return array->CreateDataProperty(context, index, value); |
} |
+protocol::Response toProtocolValue(v8::Local<v8::Context> context, |
+ v8::Local<v8::Value> value, |
+ std::unique_ptr<protocol::Value>* result) { |
+ return toProtocolValue(context, value, 1000, result); |
+} |
+ |
} // namespace v8_inspector |