X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/81345200c95645a1b0d2635520f96ad55dfde63f..ed1e77d3adeb83d26fd1dfb16dd84cabdcefd250:/runtime/JSONObject.cpp diff --git a/runtime/JSONObject.cpp b/runtime/JSONObject.cpp index 87b9237..61dc046 100644 --- a/runtime/JSONObject.cpp +++ b/runtime/JSONObject.cpp @@ -45,8 +45,8 @@ namespace JSC { STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSONObject); -static EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState*); -static EncodedJSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState*); +EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState*); +EncodedJSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState*); } @@ -107,8 +107,6 @@ private: friend class Holder; - static void appendQuotedString(StringBuilder&, const String&); - JSValue toJSON(JSValue, const PropertyNameForFunctionCall&); enum StringifyResult { StringifyFailed, StringifySucceeded, StringifyFailedDueToUndefinedValue }; @@ -226,9 +224,10 @@ Stringifier::Stringifier(ExecState* exec, const Local& replacer, const if (name.isObject()) { if (!asObject(name)->inherits(NumberObject::info()) && !asObject(name)->inherits(StringObject::info())) continue; - } + } else if (!name.isNumber() && !name.isString()) + continue; - m_arrayReplacerPropertyNames.add(Identifier(exec, name.toString(exec)->value(exec))); + m_arrayReplacerPropertyNames.add(name.toString(exec)->toIdentifier(exec)); } return; } @@ -254,77 +253,6 @@ Local Stringifier::stringify(Handle value) return Local(m_exec->vm(), jsString(m_exec, result.toString())); } -template -static void appendStringToStringBuilder(StringBuilder& builder, const CharType* data, int length) -{ - for (int i = 0; i < length; ++i) { - int start = i; - while (i < length && (data[i] > 0x1F && data[i] != '"' && data[i] != '\\')) - ++i; - builder.append(data + start, i - start); - if (i >= length) - break; - switch (data[i]) { - case '\t': - builder.append('\\'); - builder.append('t'); - break; - case '\r': - builder.append('\\'); - builder.append('r'); - break; - case '\n': - builder.append('\\'); - builder.append('n'); - break; - case '\f': - builder.append('\\'); - builder.append('f'); - break; - case '\b': - builder.append('\\'); - builder.append('b'); - break; - case '"': - builder.append('\\'); - builder.append('"'); - break; - case '\\': - builder.append('\\'); - builder.append('\\'); - break; - default: - static const char hexDigits[] = "0123456789abcdef"; - UChar ch = data[i]; - LChar hex[] = { '\\', 'u', static_cast(hexDigits[(ch >> 12) & 0xF]), static_cast(hexDigits[(ch >> 8) & 0xF]), static_cast(hexDigits[(ch >> 4) & 0xF]), static_cast(hexDigits[ch & 0xF]) }; - builder.append(hex, WTF_ARRAY_LENGTH(hex)); - break; - } - } -} - -void escapeStringToBuilder(StringBuilder& builder, const String& message) -{ - if (message.is8Bit()) - appendStringToStringBuilder(builder, message.characters8(), message.length()); - else - appendStringToStringBuilder(builder, message.characters16(), message.length()); -} - -void Stringifier::appendQuotedString(StringBuilder& builder, const String& value) -{ - int length = value.length(); - - builder.append('"'); - - if (value.is8Bit()) - appendStringToStringBuilder(builder, value.characters8(), length); - else - appendStringToStringBuilder(builder, value.characters16(), length); - - builder.append('"'); -} - inline JSValue Stringifier::toJSON(JSValue value, const PropertyNameForFunctionCall& propertyName) { ASSERT(!m_exec->hadException()); @@ -387,18 +315,21 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder& return StringifySucceeded; } - String stringValue; - if (value.getString(m_exec, stringValue)) { - appendQuotedString(builder, stringValue); + if (value.isString()) { + builder.appendQuotedJSONString(asString(value)->value(m_exec)); return StringifySucceeded; } if (value.isNumber()) { - double number = value.asNumber(); - if (!std::isfinite(number)) - builder.appendLiteral("null"); - else - builder.append(String::numberToStringECMAScript(number)); + if (value.isInt32()) + builder.appendNumber(value.asInt32()); + else { + double number = value.asNumber(); + if (!std::isfinite(number)) + builder.appendLiteral("null"); + else + builder.appendECMAScriptNumber(number); + } return StringifySucceeded; } @@ -487,14 +418,17 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBui if (!m_index) { if (m_isArray) { m_isJSArray = isJSArray(m_object.get()); - m_size = m_object->get(exec, exec->vm().propertyNames->length).toUInt32(exec); + if (m_isJSArray) + m_size = asArray(m_object.get())->length(); + else + m_size = m_object->get(exec, exec->vm().propertyNames->length).toUInt32(exec); builder.append('['); } else { if (stringifier.m_usingArrayReplacer) m_propertyNames = stringifier.m_arrayReplacerPropertyNames.data(); else { PropertyNameArray objectPropertyNames(exec); - m_object->methodTable()->getOwnPropertyNames(m_object.get(), exec, objectPropertyNames, ExcludeDontEnumProperties); + m_object->methodTable()->getOwnPropertyNames(m_object.get(), exec, objectPropertyNames, EnumerationMode()); m_propertyNames = objectPropertyNames.releaseData(); } m_size = m_propertyNames->propertyNameVector().size(); @@ -556,7 +490,7 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBui stringifier.startNewLine(builder); // Append the property name. - appendQuotedString(builder, propertyName.string()); + builder.appendQuotedJSONString(propertyName.string()); builder.append(':'); if (stringifier.willIndent()) builder.append(' '); @@ -588,7 +522,7 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBui // ------------------------------ JSONObject -------------------------------- -const ClassInfo JSONObject::s_info = { "JSON", &JSNonFinalObject::s_info, 0, ExecState::jsonTable, CREATE_METHOD_TABLE(JSONObject) }; +const ClassInfo JSONObject::s_info = { "JSON", &JSNonFinalObject::s_info, &jsonTable, CREATE_METHOD_TABLE(JSONObject) }; /* Source for JSONObject.lut.h @begin jsonTable @@ -601,7 +535,7 @@ const ClassInfo JSONObject::s_info = { "JSON", &JSNonFinalObject::s_info, 0, Exe bool JSONObject::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { - return getStaticFunctionSlot(exec, ExecState::jsonTable(exec->vm()), jsCast(object), propertyName, slot); + return getStaticFunctionSlot(exec, jsonTable, jsCast(object), propertyName, slot); } class Walker { @@ -711,7 +645,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered) objectStack.push(object); indexStack.append(0); propertyStack.append(PropertyNameArray(m_exec)); - object->methodTable()->getOwnPropertyNames(object, m_exec, propertyStack.last(), ExcludeDontEnumProperties); + object->methodTable()->getOwnPropertyNames(object, m_exec, propertyStack.last(), EnumerationMode()); } objectStartVisitMember: FALLTHROUGH; @@ -785,7 +719,7 @@ EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState* exec) { if (!exec->argumentCount()) return throwVMError(exec, createError(exec, ASCIILiteral("JSON.parse requires at least one parameter"))); - String source = exec->uncheckedArgument(0).toString(exec)->value(exec); + StringView source = exec->uncheckedArgument(0).toString(exec)->view(exec); if (exec->hadException()) return JSValue::encode(jsNull());