OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/inspector/v8-value-copier.h" | 5 #include "src/inspector/v8-value-copier.h" |
6 | 6 |
7 namespace v8_inspector { | 7 namespace v8_inspector { |
8 | 8 |
9 namespace { | 9 namespace { |
10 | 10 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 v8::Maybe<bool> createDataProperty(v8::Local<v8::Context> context, | 100 v8::Maybe<bool> createDataProperty(v8::Local<v8::Context> context, |
101 v8::Local<v8::Array> array, int index, | 101 v8::Local<v8::Array> array, int index, |
102 v8::Local<v8::Value> value) { | 102 v8::Local<v8::Value> value) { |
103 v8::TryCatch tryCatch(context->GetIsolate()); | 103 v8::TryCatch tryCatch(context->GetIsolate()); |
104 v8::Isolate::DisallowJavascriptExecutionScope throwJs( | 104 v8::Isolate::DisallowJavascriptExecutionScope throwJs( |
105 context->GetIsolate(), | 105 context->GetIsolate(), |
106 v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE); | 106 v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE); |
107 return array->CreateDataProperty(context, index, value); | 107 return array->CreateDataProperty(context, index, value); |
108 } | 108 } |
109 | 109 |
| 110 protocol::Response toProtocolValue(v8::Local<v8::Context> context, |
| 111 v8::Local<v8::Value> value, int maxDepth, |
| 112 std::unique_ptr<protocol::Value>& result) { |
| 113 using protocol::Response; |
| 114 if (value.IsEmpty()) { |
| 115 UNREACHABLE(); |
| 116 return Response::InternalError(); |
| 117 } |
| 118 |
| 119 if (!maxDepth) return Response::Error("Object reference chain is too long"); |
| 120 maxDepth--; |
| 121 |
| 122 if (value->IsNull() || value->IsUndefined()) { |
| 123 result = protocol::Value::null(); |
| 124 return Response::OK(); |
| 125 } |
| 126 if (value->IsBoolean()) { |
| 127 result = |
| 128 protocol::FundamentalValue::create(value.As<v8::Boolean>()->Value()); |
| 129 return Response::OK(); |
| 130 } |
| 131 if (value->IsNumber()) { |
| 132 double doubleValue = value.As<v8::Number>()->Value(); |
| 133 int intValue = static_cast<int>(doubleValue); |
| 134 if (intValue == doubleValue) { |
| 135 result = protocol::FundamentalValue::create(intValue); |
| 136 return Response::OK(); |
| 137 } |
| 138 result = protocol::FundamentalValue::create(doubleValue); |
| 139 return Response::OK(); |
| 140 } |
| 141 if (value->IsString()) { |
| 142 result = |
| 143 protocol::StringValue::create(toProtocolString(value.As<v8::String>())); |
| 144 return Response::OK(); |
| 145 } |
| 146 if (value->IsArray()) { |
| 147 v8::Local<v8::Array> array = value.As<v8::Array>(); |
| 148 std::unique_ptr<protocol::ListValue> inspectorArray = |
| 149 protocol::ListValue::create(); |
| 150 uint32_t length = array->Length(); |
| 151 for (uint32_t i = 0; i < length; i++) { |
| 152 v8::Local<v8::Value> value; |
| 153 if (!array->Get(context, i).ToLocal(&value)) |
| 154 return Response::InternalError(); |
| 155 std::unique_ptr<protocol::Value> element; |
| 156 Response response = toProtocolValue(context, value, maxDepth, element); |
| 157 if (!response.isSuccess()) return response; |
| 158 inspectorArray->pushValue(std::move(element)); |
| 159 } |
| 160 result = std::move(inspectorArray); |
| 161 return Response::OK(); |
| 162 } |
| 163 if (value->IsObject()) { |
| 164 std::unique_ptr<protocol::DictionaryValue> jsonObject = |
| 165 protocol::DictionaryValue::create(); |
| 166 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value); |
| 167 v8::Local<v8::Array> propertyNames; |
| 168 if (!object->GetPropertyNames(context).ToLocal(&propertyNames)) |
| 169 return Response::InternalError(); |
| 170 uint32_t length = propertyNames->Length(); |
| 171 for (uint32_t i = 0; i < length; i++) { |
| 172 v8::Local<v8::Value> name; |
| 173 if (!propertyNames->Get(context, i).ToLocal(&name)) |
| 174 return Response::InternalError(); |
| 175 // FIXME(yurys): v8::Object should support GetOwnPropertyNames |
| 176 if (name->IsString()) { |
| 177 v8::Maybe<bool> hasRealNamedProperty = object->HasRealNamedProperty( |
| 178 context, v8::Local<v8::String>::Cast(name)); |
| 179 if (!hasRealNamedProperty.IsJust() || !hasRealNamedProperty.FromJust()) |
| 180 continue; |
| 181 } |
| 182 v8::Local<v8::String> propertyName; |
| 183 if (!name->ToString(context).ToLocal(&propertyName)) continue; |
| 184 v8::Local<v8::Value> property; |
| 185 if (!object->Get(context, name).ToLocal(&property)) |
| 186 return Response::InternalError(); |
| 187 std::unique_ptr<protocol::Value> propertyValue; |
| 188 Response response = |
| 189 toProtocolValue(context, property, maxDepth, propertyValue); |
| 190 if (!response.isSuccess()) return response; |
| 191 jsonObject->setValue(toProtocolString(propertyName), |
| 192 std::move(propertyValue)); |
| 193 } |
| 194 result = std::move(jsonObject); |
| 195 return Response::OK(); |
| 196 } |
| 197 return Response::Error("Object couldn't be returned by value"); |
| 198 } |
| 199 |
110 } // namespace v8_inspector | 200 } // namespace v8_inspector |
OLD | NEW |