Changeset 81188 in webkit for trunk/Source/JavaScriptCore/runtime/JSONObject.cpp
- Timestamp:
- Mar 15, 2011, 4:12:36 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/runtime/JSONObject.cpp
r79240 r81188 33 33 #include "JSGlobalObject.h" 34 34 #include "LiteralParser.h" 35 #include "Local.h" 36 #include "LocalScope.h" 35 37 #include "Lookup.h" 36 38 #include "PropertyNameArray.h" … … 75 77 WTF_MAKE_NONCOPYABLE(Stringifier); 76 78 public: 77 Stringifier(ExecState*, JSValue replacer, JSValue space); 78 ~Stringifier(); 79 JSValue stringify(JSValue); 79 Stringifier(ExecState*, const Local<Unknown>& replacer, const Local<Unknown>& space); 80 Local<Unknown> stringify(Handle<Unknown>); 80 81 81 82 void markAggregate(MarkStack&); … … 84 85 class Holder { 85 86 public: 86 Holder(JS Object*);87 Holder(JSGlobalData&, JSObject*); 87 88 88 89 JSObject* object() const { return m_object.get(); } 89 DeprecatedPtr<JSObject>* objectSlot() { return &m_object; }90 90 91 91 bool appendNextProperty(Stringifier&, UStringBuilder&); 92 92 93 93 private: 94 DeprecatedPtr<JSObject> m_object;94 Local<JSObject> m_object; 95 95 const bool m_isArray; 96 96 bool m_isJSArray; … … 114 114 void startNewLine(UStringBuilder&) const; 115 115 116 Stringifier* const m_nextStringifierToMark;117 116 ExecState* const m_exec; 118 const JSValuem_replacer;117 const Local<Unknown> m_replacer; 119 118 bool m_usingArrayReplacer; 120 119 PropertyNameArray m_arrayReplacerPropertyNames; … … 123 122 const UString m_gap; 124 123 125 HashSet<JSObject*> m_holderCycleDetector;126 124 Vector<Holder, 16> m_holderStack; 127 125 UString m_repeatedGap; … … 200 198 // ------------------------------ Stringifier -------------------------------- 201 199 202 Stringifier::Stringifier(ExecState* exec, JSValue replacer, JSValue space) 203 : m_nextStringifierToMark(exec->globalData().firstStringifierToMark) 204 , m_exec(exec) 200 Stringifier::Stringifier(ExecState* exec, const Local<Unknown>& replacer, const Local<Unknown>& space) 201 : m_exec(exec) 205 202 , m_replacer(replacer) 206 203 , m_usingArrayReplacer(false) 207 204 , m_arrayReplacerPropertyNames(exec) 208 205 , m_replacerCallType(CallTypeNone) 209 , m_gap(gap(exec, space)) 210 { 211 exec->globalData().firstStringifierToMark = this; 212 206 , m_gap(gap(exec, space.get())) 207 { 213 208 if (!m_replacer.isObject()) 214 209 return; 215 210 216 if ( asObject(m_replacer)->inherits(&JSArray::s_info)) {211 if (m_replacer.asObject()->inherits(&JSArray::s_info)) { 217 212 m_usingArrayReplacer = true; 218 JSObject* array = asObject(m_replacer);213 Handle<JSObject> array = m_replacer.asObject(); 219 214 unsigned length = array->get(exec, exec->globalData().propertyNames->length).toUInt32(exec); 220 215 for (unsigned i = 0; i < length; ++i) { … … 247 242 } 248 243 249 m_replacerCallType = asObject(m_replacer)->getCallData(m_replacerCallData); 250 } 251 252 Stringifier::~Stringifier() 253 { 254 ASSERT(m_exec->globalData().firstStringifierToMark == this); 255 m_exec->globalData().firstStringifierToMark = m_nextStringifierToMark; 256 } 257 258 void Stringifier::markAggregate(MarkStack& markStack) 259 { 260 for (Stringifier* stringifier = this; stringifier; stringifier = stringifier->m_nextStringifierToMark) { 261 size_t size = m_holderStack.size(); 262 for (size_t i = 0; i < size; ++i) 263 markStack.append(m_holderStack[i].objectSlot()); 264 } 265 } 266 267 JSValue Stringifier::stringify(JSValue value) 244 m_replacerCallType = m_replacer.asObject()->getCallData(m_replacerCallData); 245 } 246 247 Local<Unknown> Stringifier::stringify(Handle<Unknown> value) 268 248 { 269 249 JSObject* object = constructEmptyObject(m_exec); 270 250 if (m_exec->hadException()) 271 return jsNull();251 return Local<Unknown>(m_exec->globalData(), jsNull()); 272 252 273 253 PropertyNameForFunctionCall emptyPropertyName(m_exec->globalData().propertyNames->emptyIdentifier); 274 object->putDirect(m_exec->globalData(), m_exec->globalData().propertyNames->emptyIdentifier, value );254 object->putDirect(m_exec->globalData(), m_exec->globalData().propertyNames->emptyIdentifier, value.get()); 275 255 276 256 UStringBuilder result; 277 if (appendStringifiedValue(result, value , object, emptyPropertyName) != StringifySucceeded)278 return jsUndefined();257 if (appendStringifiedValue(result, value.get(), object, emptyPropertyName) != StringifySucceeded) 258 return Local<Unknown>(m_exec->globalData(), jsUndefined()); 279 259 if (m_exec->hadException()) 280 return jsNull();281 282 return jsString(m_exec, result.toUString());260 return Local<Unknown>(m_exec->globalData(), jsNull()); 261 262 return Local<Unknown>(m_exec->globalData(), jsString(m_exec, result.toUString())); 283 263 } 284 264 … … 373 353 JSValue list[] = { propertyName.value(m_exec), value }; 374 354 ArgList args(list, WTF_ARRAY_LENGTH(list)); 375 value = call(m_exec, m_replacer , m_replacerCallType, m_replacerCallData, holder, args);355 value = call(m_exec, m_replacer.get(), m_replacerCallType, m_replacerCallData, holder, args); 376 356 if (m_exec->hadException()) 377 357 return StringifyFailed; … … 426 406 427 407 // Handle cycle detection, and put the holder on the stack. 428 if (!m_holderCycleDetector.add(object).second) { 429 throwError(m_exec, createTypeError(m_exec, "JSON.stringify cannot serialize cyclic structures.")); 430 return StringifyFailed; 408 for (unsigned i = 0; i < m_holderStack.size(); i++) { 409 if (m_holderStack[i].object() == object) { 410 throwError(m_exec, createTypeError(m_exec, "JSON.stringify cannot serialize cyclic structures.")); 411 return StringifyFailed; 412 } 431 413 } 432 414 bool holderStackWasEmpty = m_holderStack.isEmpty(); 433 m_holderStack.append( object);415 m_holderStack.append(Holder(m_exec->globalData(), object)); 434 416 if (!holderStackWasEmpty) 435 417 return StringifySucceeded; … … 451 433 } 452 434 } 453 m_holderCycleDetector.remove(m_holderStack.last().object());454 435 m_holderStack.removeLast(); 455 436 } while (!m_holderStack.isEmpty()); … … 486 467 } 487 468 488 inline Stringifier::Holder::Holder(JS Object* object)489 : m_object( object)469 inline Stringifier::Holder::Holder(JSGlobalData& globalData, JSObject* object) 470 : m_object(globalData, object) 490 471 , m_isArray(object->inherits(&JSArray::s_info)) 491 472 , m_index(0) … … 624 605 } 625 606 626 void JSONObject::markStringifiers(MarkStack& markStack, Stringifier* stringifier)627 {628 stringifier->markAggregate(markStack);629 }630 631 607 class Walker { 632 608 public: 633 Walker(ExecState* exec, JSObject*function, CallType callType, CallData callData)609 Walker(ExecState* exec, Handle<JSObject> function, CallType callType, CallData callData) 634 610 : m_exec(exec) 635 , m_function( function)611 , m_function(exec->globalData(), function) 636 612 , m_callType(callType) 637 613 , m_callData(callData) … … 650 626 651 627 ExecState* m_exec; 652 DeprecatedPtr<JSObject> m_function;628 Local<JSObject> m_function; 653 629 CallType m_callType; 654 630 CallData m_callData; … … 664 640 Vector<PropertyNameArray, 16> propertyStack; 665 641 Vector<uint32_t, 16> indexStack; 666 Vector<JSObject*, 16> objectStack;667 Vector<JSArray*, 16> arrayStack;642 LocalStack<JSObject, 16> objectStack(m_exec->globalData()); 643 LocalStack<JSArray, 16> arrayStack(m_exec->globalData()); 668 644 669 645 Vector<WalkerState, 16> stateStack; … … 685 661 686 662 JSArray* array = asArray(inValue); 687 arrayStack. append(array);663 arrayStack.push(array); 688 664 indexStack.append(0); 689 665 // fallthrough … … 697 673 } 698 674 699 JSArray* array = arrayStack. last();675 JSArray* array = arrayStack.peek(); 700 676 uint32_t index = indexStack.last(); 701 677 if (index == array->length()) { 702 678 outValue = array; 703 arrayStack. removeLast();679 arrayStack.pop(); 704 680 indexStack.removeLast(); 705 681 break; … … 723 699 } 724 700 case ArrayEndVisitMember: { 725 JSArray* array = arrayStack. last();701 JSArray* array = arrayStack.peek(); 726 702 JSValue filteredValue = callReviver(array, jsString(m_exec, UString::number(indexStack.last())), outValue); 727 703 if (filteredValue.isUndefined()) … … 746 722 747 723 JSObject* object = asObject(inValue); 748 objectStack. append(object);724 objectStack.push(object); 749 725 indexStack.append(0); 750 726 propertyStack.append(PropertyNameArray(m_exec)); … … 760 736 } 761 737 762 JSObject* object = objectStack. last();738 JSObject* object = objectStack.peek(); 763 739 uint32_t index = indexStack.last(); 764 740 PropertyNameArray& properties = propertyStack.last(); 765 741 if (index == properties.size()) { 766 742 outValue = object; 767 objectStack. removeLast();743 objectStack.pop(); 768 744 indexStack.removeLast(); 769 745 propertyStack.removeLast(); … … 788 764 } 789 765 case ObjectEndVisitMember: { 790 JSObject* object = objectStack. last();766 JSObject* object = objectStack.peek(); 791 767 Identifier prop = propertyStack.last()[indexStack.last()]; 792 768 PutPropertySlot slot; … … 839 815 if (exec->hadException()) 840 816 return JSValue::encode(jsNull()); 841 817 818 LocalScope scope(exec->globalData()); 842 819 LiteralParser jsonParser(exec, source, LiteralParser::StrictJSON); 843 820 JSValue unfiltered = jsonParser.tryLiteralParse(); … … 853 830 if (callType == CallTypeNone) 854 831 return JSValue::encode(unfiltered); 855 return JSValue::encode(Walker(exec, asObject(function), callType, callData).walk(unfiltered));832 return JSValue::encode(Walker(exec, Local<JSObject>(exec->globalData(), asObject(function)), callType, callData).walk(unfiltered)); 856 833 } 857 834 … … 861 838 if (!exec->argumentCount()) 862 839 return throwVMError(exec, createError(exec, "No input to stringify")); 863 JSValue value = exec->argument(0); 864 JSValue replacer = exec->argument(1); 865 JSValue space = exec->argument(2); 866 return JSValue::encode(Stringifier(exec, replacer, space).stringify(value)); 840 LocalScope scope(exec->globalData()); 841 Local<Unknown> value(exec->globalData(), exec->argument(0)); 842 Local<Unknown> replacer(exec->globalData(), exec->argument(1)); 843 Local<Unknown> space(exec->globalData(), exec->argument(2)); 844 return JSValue::encode(Stringifier(exec, replacer, space).stringify(value).get()); 867 845 } 868 846 869 847 UString JSONStringify(ExecState* exec, JSValue value, unsigned indent) 870 848 { 871 JSValue result = Stringifier(exec, jsNull(), jsNumber(indent)).stringify(value); 849 LocalScope scope(exec->globalData()); 850 Local<Unknown> result = Stringifier(exec, Local<Unknown>(exec->globalData(), jsNull()), Local<Unknown>(exec->globalData(), jsNumber(indent))).stringify(Local<Unknown>(exec->globalData(), value)); 872 851 if (result.isUndefinedOrNull()) 873 852 return UString();
Note:
See TracChangeset
for help on using the changeset viewer.