Line data Source code
1 : // Copyright 2016 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/inspector/v8-value-utils.h"
6 :
7 : namespace v8_inspector {
8 :
9 : namespace {
10 :
11 28053482 : protocol::Response toProtocolValue(v8::Local<v8::Context> context,
12 : v8::Local<v8::Value> value, int maxDepth,
13 : std::unique_ptr<protocol::Value>* result) {
14 : using protocol::Response;
15 28053482 : if (value.IsEmpty()) {
16 0 : UNREACHABLE();
17 : }
18 :
19 28053482 : if (!maxDepth) return Response::Error("Object reference chain is too long");
20 28053482 : maxDepth--;
21 :
22 56104397 : if (value->IsNull() || value->IsUndefined()) {
23 : *result = protocol::Value::null();
24 2572 : return Response::OK();
25 : }
26 28050910 : if (value->IsBoolean()) {
27 18936098 : *result =
28 9468049 : protocol::FundamentalValue::create(value.As<v8::Boolean>()->Value());
29 9468049 : return Response::OK();
30 : }
31 18582861 : if (value->IsNumber()) {
32 141604 : double doubleValue = value.As<v8::Number>()->Value();
33 141604 : int intValue = static_cast<int>(doubleValue);
34 141604 : if (intValue == doubleValue) {
35 248970 : *result = protocol::FundamentalValue::create(intValue);
36 124485 : return Response::OK();
37 : }
38 34238 : *result = protocol::FundamentalValue::create(doubleValue);
39 17119 : return Response::OK();
40 : }
41 18441257 : if (value->IsString()) {
42 39433125 : *result =
43 : protocol::StringValue::create(toProtocolString(value.As<v8::String>()));
44 13144375 : return Response::OK();
45 : }
46 5296882 : if (value->IsArray()) {
47 : v8::Local<v8::Array> array = value.As<v8::Array>();
48 : std::unique_ptr<protocol::ListValue> inspectorArray =
49 67801 : protocol::ListValue::create();
50 67801 : uint32_t length = array->Length();
51 2432231 : for (uint32_t i = 0; i < length; i++) {
52 : v8::Local<v8::Value> value;
53 4728860 : if (!array->Get(context, i).ToLocal(&value))
54 0 : return Response::InternalError();
55 2364430 : std::unique_ptr<protocol::Value> element;
56 2364430 : Response response = toProtocolValue(context, value, maxDepth, &element);
57 2364430 : if (!response.isSuccess()) return response;
58 4728860 : inspectorArray->pushValue(std::move(element));
59 : }
60 : *result = std::move(inspectorArray);
61 67801 : return Response::OK();
62 : }
63 5229081 : if (value->IsObject()) {
64 : std::unique_ptr<protocol::DictionaryValue> jsonObject =
65 5229076 : protocol::DictionaryValue::create();
66 : v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value);
67 : v8::Local<v8::Array> propertyNames;
68 10458152 : if (!object->GetPropertyNames(context).ToLocal(&propertyNames))
69 0 : return Response::InternalError();
70 5229076 : uint32_t length = propertyNames->Length();
71 47553484 : for (uint32_t i = 0; i < length; i++) {
72 : v8::Local<v8::Value> name;
73 84648826 : if (!propertyNames->Get(context, i).ToLocal(&name))
74 5 : return Response::InternalError();
75 : // FIXME(yurys): v8::Object should support GetOwnPropertyNames
76 42324413 : if (name->IsString()) {
77 : v8::Maybe<bool> hasRealNamedProperty = object->HasRealNamedProperty(
78 42324413 : context, v8::Local<v8::String>::Cast(name));
79 84648826 : if (!hasRealNamedProperty.IsJust() || !hasRealNamedProperty.FromJust())
80 17185266 : continue;
81 : }
82 : v8::Local<v8::String> propertyName;
83 50278294 : if (!name->ToString(context).ToLocal(&propertyName)) continue;
84 : v8::Local<v8::Value> property;
85 50278294 : if (!object->Get(context, name).ToLocal(&property))
86 0 : return Response::InternalError();
87 25139147 : std::unique_ptr<protocol::Value> propertyValue;
88 : Response response =
89 25139147 : toProtocolValue(context, property, maxDepth, &propertyValue);
90 25139147 : if (!response.isSuccess()) return response;
91 : jsonObject->setValue(toProtocolString(propertyName),
92 100556568 : std::move(propertyValue));
93 : }
94 : *result = std::move(jsonObject);
95 5229071 : return Response::OK();
96 : }
97 10 : return Response::Error("Object couldn't be returned by value");
98 : }
99 :
100 : } // namespace
101 :
102 58343 : v8::Maybe<bool> createDataProperty(v8::Local<v8::Context> context,
103 : v8::Local<v8::Object> object,
104 : v8::Local<v8::Name> key,
105 : v8::Local<v8::Value> value) {
106 58343 : v8::TryCatch tryCatch(context->GetIsolate());
107 : v8::Isolate::DisallowJavascriptExecutionScope throwJs(
108 : context->GetIsolate(),
109 116686 : v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
110 116686 : return object->CreateDataProperty(context, key, value);
111 : }
112 :
113 11456 : v8::Maybe<bool> createDataProperty(v8::Local<v8::Context> context,
114 : v8::Local<v8::Array> array, int index,
115 : v8::Local<v8::Value> value) {
116 11456 : v8::TryCatch tryCatch(context->GetIsolate());
117 : v8::Isolate::DisallowJavascriptExecutionScope throwJs(
118 : context->GetIsolate(),
119 22912 : v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
120 34368 : return array->CreateDataProperty(context, index, value);
121 : }
122 :
123 549905 : protocol::Response toProtocolValue(v8::Local<v8::Context> context,
124 : v8::Local<v8::Value> value,
125 : std::unique_ptr<protocol::Value>* result) {
126 549905 : return toProtocolValue(context, value, 1000, result);
127 : }
128 :
129 : } // namespace v8_inspector
|