diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/inspector/InspectorValues.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/JavaScriptCore/inspector/InspectorValues.cpp')
-rw-r--r-- | Source/JavaScriptCore/inspector/InspectorValues.cpp | 491 |
1 files changed, 238 insertions, 253 deletions
diff --git a/Source/JavaScriptCore/inspector/InspectorValues.cpp b/Source/JavaScriptCore/inspector/InspectorValues.cpp index 4cdf71e92..14fb7e70d 100644 --- a/Source/JavaScriptCore/inspector/InspectorValues.cpp +++ b/Source/JavaScriptCore/inspector/InspectorValues.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2010 Google Inc. All rights reserved. + * Copyright (C) 2014 University of Washington. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -63,8 +64,10 @@ const char* const falseString = "false"; bool parseConstToken(const UChar* start, const UChar* end, const UChar** tokenEnd, const char* token) { while (start < end && *token != '\0' && *start++ == *token++) { } + if (*token != '\0') return false; + *tokenEnd = start; return true; } @@ -73,16 +76,20 @@ bool readInt(const UChar* start, const UChar* end, const UChar** tokenEnd, bool { if (start == end) return false; + bool haveLeadingZero = '0' == *start; int length = 0; while (start < end && '0' <= *start && *start <= '9') { ++start; ++length; } + if (!length) return false; + if (!canHaveLeadingZeros && length > 1 && haveLeadingZero) return false; + *tokenEnd = start; return true; } @@ -93,12 +100,14 @@ bool parseNumberToken(const UChar* start, const UChar* end, const UChar** tokenE // According to RFC4627, a valid number is: [minus] int [frac] [exp] if (start == end) return false; + UChar c = *start; if ('-' == c) ++start; if (!readInt(start, end, &start, false)) return false; + if (start == end) { *tokenEnd = start; return true; @@ -140,11 +149,12 @@ bool readHexDigits(const UChar* start, const UChar* end, const UChar** tokenEnd, { if (end - start < digits) return false; + for (int i = 0; i < digits; ++i) { - UChar c = *start++; - if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'))) + if (!isASCIIHexDigit(*start++)) return false; } + *tokenEnd = start; return true; } @@ -183,6 +193,7 @@ bool parseStringToken(const UChar* start, const UChar* end, const UChar** tokenE return true; } } + return false; } @@ -246,27 +257,16 @@ Token parseToken(const UChar* start, const UChar* end, const UChar** tokenStart, return STRING; break; } - return INVALID_TOKEN; -} -inline int hexToInt(UChar c) -{ - if ('0' <= c && c <= '9') - return c - '0'; - if ('A' <= c && c <= 'F') - return c - 'A' + 10; - if ('a' <= c && c <= 'f') - return c - 'a' + 10; - ASSERT_NOT_REACHED(); - return 0; + return INVALID_TOKEN; } -bool decodeString(const UChar* start, const UChar* end, StringBuilder* output) +bool decodeString(const UChar* start, const UChar* end, StringBuilder& output) { while (start < end) { UChar c = *start++; if ('\\' != c) { - output->append(c); + output.append(c); continue; } c = *start++; @@ -294,45 +294,45 @@ bool decodeString(const UChar* start, const UChar* end, StringBuilder* output) c = '\v'; break; case 'x': - c = (hexToInt(*start) << 4) + - hexToInt(*(start + 1)); + c = toASCIIHexValue(start[0], start[1]); start += 2; break; case 'u': - c = (hexToInt(*start) << 12) + - (hexToInt(*(start + 1)) << 8) + - (hexToInt(*(start + 2)) << 4) + - hexToInt(*(start + 3)); + c = toASCIIHexValue(start[0], start[1]) << 8 | toASCIIHexValue(start[2], start[3]); start += 4; break; default: return false; } - output->append(c); + output.append(c); } + return true; } -bool decodeString(const UChar* start, const UChar* end, String* output) +bool decodeString(const UChar* start, const UChar* end, String& output) { if (start == end) { - *output = ""; + output = emptyString(); return true; } + if (start > end) return false; + StringBuilder buffer; buffer.reserveCapacity(end - start); - if (!decodeString(start, end, &buffer)) + if (!decodeString(start, end, buffer)) return false; - *output = buffer.toString(); + + output = buffer.toString(); return true; } -PassRefPtr<InspectorValue> buildValue(const UChar* start, const UChar* end, const UChar** valueTokenEnd, int depth) +RefPtr<InspectorValue> buildValue(const UChar* start, const UChar* end, const UChar** valueTokenEnd, int depth) { if (depth > stackLimit) - return 0; + return nullptr; RefPtr<InspectorValue> result; const UChar* tokenStart; @@ -340,41 +340,41 @@ PassRefPtr<InspectorValue> buildValue(const UChar* start, const UChar* end, cons Token token = parseToken(start, end, &tokenStart, &tokenEnd); switch (token) { case INVALID_TOKEN: - return 0; + return nullptr; case NULL_TOKEN: result = InspectorValue::null(); break; case BOOL_TRUE: - result = InspectorBasicValue::create(true); + result = InspectorValue::create(true); break; case BOOL_FALSE: - result = InspectorBasicValue::create(false); + result = InspectorValue::create(false); break; case NUMBER: { bool ok; double value = charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok); if (!ok) - return 0; - result = InspectorBasicValue::create(value); + return nullptr; + result = InspectorValue::create(value); break; } case STRING: { String value; - bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value); + bool ok = decodeString(tokenStart + 1, tokenEnd - 1, value); if (!ok) - return 0; - result = InspectorString::create(value); + return nullptr; + result = InspectorValue::create(value); break; } case ARRAY_BEGIN: { - RefPtr<InspectorArray> array = InspectorArray::create(); + Ref<InspectorArray> array = InspectorArray::create(); start = tokenEnd; token = parseToken(start, end, &tokenStart, &tokenEnd); while (token != ARRAY_END) { RefPtr<InspectorValue> arrayNode = buildValue(start, end, &tokenEnd, depth + 1); if (!arrayNode) - return 0; - array->pushValue(arrayNode); + return nullptr; + array->pushValue(WTFMove(arrayNode)); // After a list value, we expect a comma or the end of the list. start = tokenEnd; @@ -383,38 +383,38 @@ PassRefPtr<InspectorValue> buildValue(const UChar* start, const UChar* end, cons start = tokenEnd; token = parseToken(start, end, &tokenStart, &tokenEnd); if (token == ARRAY_END) - return 0; + return nullptr; } else if (token != ARRAY_END) { // Unexpected value after list value. Bail out. - return 0; + return nullptr; } } if (token != ARRAY_END) - return 0; - result = array.release(); + return nullptr; + result = WTFMove(array); break; } case OBJECT_BEGIN: { - RefPtr<InspectorObject> object = InspectorObject::create(); + Ref<InspectorObject> object = InspectorObject::create(); start = tokenEnd; token = parseToken(start, end, &tokenStart, &tokenEnd); while (token != OBJECT_END) { if (token != STRING) - return 0; + return nullptr; String key; - if (!decodeString(tokenStart + 1, tokenEnd - 1, &key)) - return 0; + if (!decodeString(tokenStart + 1, tokenEnd - 1, key)) + return nullptr; start = tokenEnd; token = parseToken(start, end, &tokenStart, &tokenEnd); if (token != OBJECT_PAIR_SEPARATOR) - return 0; + return nullptr; start = tokenEnd; RefPtr<InspectorValue> value = buildValue(start, end, &tokenEnd, depth + 1); if (!value) - return 0; - object->setValue(key, value); + return nullptr; + object->setValue(key, WTFMove(value)); start = tokenEnd; // After a key/value pair, we expect a comma or the end of the @@ -424,45 +424,45 @@ PassRefPtr<InspectorValue> buildValue(const UChar* start, const UChar* end, cons start = tokenEnd; token = parseToken(start, end, &tokenStart, &tokenEnd); if (token == OBJECT_END) - return 0; + return nullptr; } else if (token != OBJECT_END) { // Unexpected value after last object value. Bail out. - return 0; + return nullptr; } } if (token != OBJECT_END) - return 0; - result = object.release(); + return nullptr; + result = WTFMove(object); break; } default: // We got a token that's not a value. - return 0; + return nullptr; } *valueTokenEnd = tokenEnd; - return result.release(); + return result; } -inline bool escapeChar(UChar c, StringBuilder* dst) +inline bool escapeChar(UChar c, StringBuilder& dst) { switch (c) { - case '\b': dst->append("\\b", 2); break; - case '\f': dst->append("\\f", 2); break; - case '\n': dst->append("\\n", 2); break; - case '\r': dst->append("\\r", 2); break; - case '\t': dst->append("\\t", 2); break; - case '\\': dst->append("\\\\", 2); break; - case '"': dst->append("\\\"", 2); break; + case '\b': dst.appendLiteral("\\b"); break; + case '\f': dst.appendLiteral("\\f"); break; + case '\n': dst.appendLiteral("\\n"); break; + case '\r': dst.appendLiteral("\\r"); break; + case '\t': dst.appendLiteral("\\t"); break; + case '\\': dst.appendLiteral("\\\\"); break; + case '"': dst.appendLiteral("\\\""); break; default: return false; } return true; } -inline void doubleQuoteString(const String& str, StringBuilder* dst) +inline void doubleQuoteString(const String& str, StringBuilder& dst) { - dst->append('"'); + dst.append('"'); for (unsigned i = 0; i < str.length(); ++i) { UChar c = str[i]; if (!escapeChar(c, dst)) { @@ -470,285 +470,306 @@ inline void doubleQuoteString(const String& str, StringBuilder* dst) // 1. Escaping <, > to prevent script execution. // 2. Technically, we could also pass through c > 126 as UTF8, but this // is also optional. It would also be a pain to implement here. - unsigned int symbol = static_cast<unsigned int>(c); - String symbolCode = String::format("\\u%04X", symbol); - dst->append(symbolCode.deprecatedCharacters(), symbolCode.length()); + dst.append(String::format("\\u%04X", c)); } else - dst->append(c); + dst.append(c); } } - dst->append('"'); + dst.append('"'); } } // anonymous namespace -bool InspectorValue::asBoolean(bool*) const +Ref<InspectorValue> InspectorValue::null() { - return false; + return adoptRef(*new InspectorValue); } -bool InspectorValue::asNumber(double*) const +Ref<InspectorValue> InspectorValue::create(bool value) { - return false; + return adoptRef(*new InspectorValue(value)); } -bool InspectorValue::asNumber(long*) const +Ref<InspectorValue> InspectorValue::create(int value) { - return false; + return adoptRef(*new InspectorValue(value)); } -bool InspectorValue::asNumber(int*) const +Ref<InspectorValue> InspectorValue::create(double value) { - return false; + return adoptRef(*new InspectorValue(value)); } -bool InspectorValue::asNumber(unsigned long*) const +Ref<InspectorValue> InspectorValue::create(const String& value) { - return false; + return adoptRef(*new InspectorValue(value)); } -bool InspectorValue::asNumber(unsigned int*) const +Ref<InspectorValue> InspectorValue::create(const char* value) { - return false; + return adoptRef(*new InspectorValue(value)); } -bool InspectorValue::asString(String*) const +bool InspectorValue::asValue(RefPtr<Inspector::InspectorValue> & value) { - return false; + value = this; + return true; } -bool InspectorValue::asValue(RefPtr<InspectorValue>* output) +bool InspectorValue::asObject(RefPtr<InspectorObject>&) { - *output = this; - return true; + return false; } -bool InspectorValue::asObject(RefPtr<InspectorObject>*) +bool InspectorValue::asArray(RefPtr<InspectorArray>&) { return false; } -bool InspectorValue::asArray(RefPtr<InspectorArray>*) +bool InspectorValue::parseJSON(const String& jsonInput, RefPtr<InspectorValue>& output) { - return false; + // FIXME: This whole file should just use StringView instead of UChar/length and avoid upconverting. + auto characters = StringView(jsonInput).upconvertedCharacters(); + const UChar* start = characters; + const UChar* end = start + jsonInput.length(); + const UChar* tokenEnd; + auto result = buildValue(start, end, &tokenEnd, 0); + if (!result || tokenEnd != end) + return false; + + output = WTFMove(result); + return true; } -PassRefPtr<InspectorObject> InspectorValue::asObject() +String InspectorValue::toJSONString() const { - return 0; + StringBuilder result; + result.reserveCapacity(512); + writeJSON(result); + return result.toString(); } -PassRefPtr<InspectorArray> InspectorValue::asArray() +bool InspectorValue::asBoolean(bool& output) const { - return 0; + if (type() != Type::Boolean) + return false; + + output = m_value.boolean; + return true; } -PassRefPtr<InspectorValue> InspectorValue::parseJSON(const String& json) +bool InspectorValue::asDouble(double& output) const { - const UChar* start = json.deprecatedCharacters(); - const UChar* end = json.deprecatedCharacters() + json.length(); - const UChar *tokenEnd; - RefPtr<InspectorValue> value = buildValue(start, end, &tokenEnd, 0); - if (!value || tokenEnd != end) - return 0; - return value.release(); + if (type() != Type::Double) + return false; + + output = m_value.number; + return true; } -String InspectorValue::toJSONString() const +bool InspectorValue::asDouble(float& output) const { - StringBuilder result; - result.reserveCapacity(512); - writeJSON(&result); - return result.toString(); + if (type() != Type::Double) + return false; + + output = static_cast<float>(m_value.number); + return true; } -void InspectorValue::writeJSON(StringBuilder* output) const +bool InspectorValue::asInteger(int& output) const { - ASSERT(m_type == TypeNull); - output->append(nullString, 4); + if (type() != Type::Integer && type() != Type::Double) + return false; + + output = static_cast<int>(m_value.number); + return true; } -bool InspectorBasicValue::asBoolean(bool* output) const +bool InspectorValue::asInteger(unsigned& output) const { - if (type() != TypeBoolean) + if (type() != Type::Integer && type() != Type::Double) return false; - *output = m_boolValue; + + output = static_cast<unsigned>(m_value.number); return true; } -bool InspectorBasicValue::asNumber(double* output) const +bool InspectorValue::asInteger(long& output) const { - if (type() != TypeNumber) + if (type() != Type::Integer && type() != Type::Double) return false; - *output = m_doubleValue; + + output = static_cast<long>(m_value.number); return true; } -bool InspectorBasicValue::asNumber(long* output) const +bool InspectorValue::asInteger(long long& output) const { - if (type() != TypeNumber) + if (type() != Type::Integer && type() != Type::Double) return false; - *output = static_cast<long>(m_doubleValue); + + output = static_cast<long long>(m_value.number); return true; } -bool InspectorBasicValue::asNumber(int* output) const +bool InspectorValue::asInteger(unsigned long& output) const { - if (type() != TypeNumber) + if (type() != Type::Integer && type() != Type::Double) return false; - *output = static_cast<int>(m_doubleValue); + + output = static_cast<unsigned long>(m_value.number); return true; } -bool InspectorBasicValue::asNumber(unsigned long* output) const +bool InspectorValue::asInteger(unsigned long long& output) const { - if (type() != TypeNumber) + if (type() != Type::Integer && type() != Type::Double) return false; - *output = static_cast<unsigned long>(m_doubleValue); + + output = static_cast<unsigned long long>(m_value.number); return true; } -bool InspectorBasicValue::asNumber(unsigned int* output) const +bool InspectorValue::asString(String& output) const { - if (type() != TypeNumber) + if (type() != Type::String) return false; - *output = static_cast<unsigned int>(m_doubleValue); + + output = m_value.string; return true; } -void InspectorBasicValue::writeJSON(StringBuilder* output) const +void InspectorValue::writeJSON(StringBuilder& output) const { - ASSERT(type() == TypeBoolean || type() == TypeNumber); - if (type() == TypeBoolean) { - if (m_boolValue) - output->append(trueString, 4); + switch (m_type) { + case Type::Null: + output.appendLiteral("null"); + break; + case Type::Boolean: + if (m_value.boolean) + output.appendLiteral("true"); else - output->append(falseString, 5); - } else if (type() == TypeNumber) { + output.appendLiteral("false"); + break; + case Type::String: + doubleQuoteString(m_value.string, output); + break; + case Type::Double: + case Type::Integer: { NumberToLStringBuffer buffer; - if (!std::isfinite(m_doubleValue)) { - output->append(nullString, 4); + if (!std::isfinite(m_value.number)) { + output.appendLiteral("null"); return; } - DecimalNumber decimal = m_doubleValue; + DecimalNumber decimal = m_value.number; unsigned length = 0; if (decimal.bufferLengthForStringDecimal() > WTF::NumberToStringBufferLength) { // Not enough room for decimal. Use exponential format. if (decimal.bufferLengthForStringExponential() > WTF::NumberToStringBufferLength) { // Fallback for an abnormal case if it's too little even for exponential. - output->append("NaN", 3); + output.appendLiteral("NaN"); return; } length = decimal.toStringExponential(buffer, WTF::NumberToStringBufferLength); } else length = decimal.toStringDecimal(buffer, WTF::NumberToStringBufferLength); - output->append(buffer, length); + output.append(buffer, length); + break; + } + default: + ASSERT_NOT_REACHED(); } -} - -bool InspectorString::asString(String* output) const -{ - *output = m_stringValue; - return true; -} - -void InspectorString::writeJSON(StringBuilder* output) const -{ - ASSERT(type() == TypeString); - doubleQuoteString(m_stringValue, output); } InspectorObjectBase::~InspectorObjectBase() { } -bool InspectorObjectBase::asObject(RefPtr<InspectorObject>* output) +bool InspectorObjectBase::asObject(RefPtr<InspectorObject>& output) { COMPILE_ASSERT(sizeof(InspectorObject) == sizeof(InspectorObjectBase), cannot_cast); - *output = static_cast<InspectorObject*>(this); - return true; -} -PassRefPtr<InspectorObject> InspectorObjectBase::asObject() -{ - return openAccessors(); + output = static_cast<InspectorObject*>(this); + return true; } InspectorObject* InspectorObjectBase::openAccessors() { COMPILE_ASSERT(sizeof(InspectorObject) == sizeof(InspectorObjectBase), cannot_cast); + return static_cast<InspectorObject*>(this); } -bool InspectorObjectBase::getBoolean(const String& name, bool* output) const +bool InspectorObjectBase::getBoolean(const String& name, bool& output) const { - RefPtr<InspectorValue> value = get(name); - if (!value) + RefPtr<InspectorValue> value; + if (!getValue(name, value)) return false; + return value->asBoolean(output); } -bool InspectorObjectBase::getString(const String& name, String* output) const +bool InspectorObjectBase::getString(const String& name, String& output) const { - RefPtr<InspectorValue> value = get(name); - if (!value) + RefPtr<InspectorValue> value; + if (!getValue(name, value)) return false; + return value->asString(output); } -PassRefPtr<InspectorObject> InspectorObjectBase::getObject(const String& name) const +bool InspectorObjectBase::getObject(const String& name, RefPtr<InspectorObject>& output) const { - PassRefPtr<InspectorValue> value = get(name); - if (!value) - return 0; - return value->asObject(); + RefPtr<InspectorValue> value; + if (!getValue(name, value)) + return false; + + return value->asObject(output); } -PassRefPtr<InspectorArray> InspectorObjectBase::getArray(const String& name) const +bool InspectorObjectBase::getArray(const String& name, RefPtr<InspectorArray>& output) const { - PassRefPtr<InspectorValue> value = get(name); - if (!value) - return 0; - return value->asArray(); + RefPtr<InspectorValue> value; + if (!getValue(name, value)) + return false; + + return value->asArray(output); } -PassRefPtr<InspectorValue> InspectorObjectBase::get(const String& name) const +bool InspectorObjectBase::getValue(const String& name, RefPtr<InspectorValue>& output) const { - Dictionary::const_iterator it = m_data.find(name); - if (it == m_data.end()) - return 0; - return it->value; + Dictionary::const_iterator findResult = m_map.find(name); + if (findResult == m_map.end()) + return false; + + output = findResult->value; + return true; } void InspectorObjectBase::remove(const String& name) { - m_data.remove(name); - for (size_t i = 0; i < m_order.size(); ++i) { - if (m_order[i] == name) { - m_order.remove(i); - break; - } - } + m_map.remove(name); + m_order.removeFirst(name); } -void InspectorObjectBase::writeJSON(StringBuilder* output) const +void InspectorObjectBase::writeJSON(StringBuilder& output) const { - output->append('{'); + output.append('{'); for (size_t i = 0; i < m_order.size(); ++i) { - Dictionary::const_iterator it = m_data.find(m_order[i]); - ASSERT(it != m_data.end()); + auto findResult = m_map.find(m_order[i]); + ASSERT(findResult != m_map.end()); if (i) - output->append(','); - doubleQuoteString(it->key, output); - output->append(':'); - it->value->writeJSON(output); + output.append(','); + doubleQuoteString(findResult->key, output); + output.append(':'); + findResult->value->writeJSON(output); } - output->append('}'); + output.append('}'); } InspectorObjectBase::InspectorObjectBase() - : InspectorValue(TypeObject) - , m_data() + : Inspector::InspectorValue(Type::Object) + , m_map() , m_order() { } @@ -757,80 +778,44 @@ InspectorArrayBase::~InspectorArrayBase() { } -bool InspectorArrayBase::asArray(RefPtr<InspectorArray>* output) +bool InspectorArrayBase::asArray(RefPtr<InspectorArray>& output) { COMPILE_ASSERT(sizeof(InspectorArrayBase) == sizeof(InspectorArray), cannot_cast); - *output = static_cast<InspectorArray*>(this); + output = static_cast<InspectorArray*>(this); return true; } -PassRefPtr<InspectorArray> InspectorArrayBase::asArray() -{ - COMPILE_ASSERT(sizeof(InspectorArrayBase) == sizeof(InspectorArray), cannot_cast); - return static_cast<InspectorArray*>(this); -} - -void InspectorArrayBase::writeJSON(StringBuilder* output) const +void InspectorArrayBase::writeJSON(StringBuilder& output) const { - output->append('['); - for (Vector<RefPtr<InspectorValue>>::const_iterator it = m_data.begin(); it != m_data.end(); ++it) { - if (it != m_data.begin()) - output->append(','); + output.append('['); + for (Vector<RefPtr<InspectorValue>>::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { + if (it != m_map.begin()) + output.append(','); (*it)->writeJSON(output); } - output->append(']'); + output.append(']'); } InspectorArrayBase::InspectorArrayBase() - : InspectorValue(TypeArray) - , m_data() -{ -} - -PassRefPtr<InspectorValue> InspectorArrayBase::get(size_t index) -{ - ASSERT_WITH_SECURITY_IMPLICATION(index < m_data.size()); - return m_data[index]; -} - -PassRefPtr<InspectorObject> InspectorObject::create() -{ - return adoptRef(new InspectorObject); -} - -PassRefPtr<InspectorArray> InspectorArray::create() -{ - return adoptRef(new InspectorArray); -} - -PassRefPtr<InspectorValue> InspectorValue::null() -{ - return adoptRef(new InspectorValue); -} - -PassRefPtr<InspectorString> InspectorString::create(const String& value) -{ - return adoptRef(new InspectorString(value)); -} - -PassRefPtr<InspectorString> InspectorString::create(const char* value) + : InspectorValue(Type::Array) + , m_map() { - return adoptRef(new InspectorString(value)); } -PassRefPtr<InspectorBasicValue> InspectorBasicValue::create(bool value) +RefPtr<InspectorValue> InspectorArrayBase::get(size_t index) const { - return adoptRef(new InspectorBasicValue(value)); + ASSERT_WITH_SECURITY_IMPLICATION(index < m_map.size()); + return m_map[index]; } -PassRefPtr<InspectorBasicValue> InspectorBasicValue::create(int value) +Ref<InspectorObject> InspectorObject::create() { - return adoptRef(new InspectorBasicValue(value)); + return adoptRef(*new InspectorObject); } -PassRefPtr<InspectorBasicValue> InspectorBasicValue::create(double value) +Ref<InspectorArray> InspectorArray::create() { - return adoptRef(new InspectorBasicValue(value)); + return adoptRef(*new InspectorArray); } } // namespace Inspector |