Ignore:
Timestamp:
Mar 15, 2011, 4:12:36 PM (14 years ago)
Author:
[email protected]
Message:

2011-03-15 Oliver Hunt <[email protected]>

Reviewed by Geoffrey Garen.

Introduce Local<T> to allow us to start moving to precise marking of locals
https://bugs.webkit.org/show_bug.cgi?id=56394

Introduce a new handle type, Local<T> and a scoping mechanism
LocalScope to allow us to start moving towards precise marking
of temporaries and local variables.

We also start to use the new Local<> type in the JSON stringifier
so that we can have some coverage of their behaviour in the initial
checkin.

  • GNUmakefile.am:
  • JavaScriptCore.gypi:
  • JavaScriptCore.pro:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • collector/handles/Handle.h: (JSC::::asObject):
  • collector/handles/HandleStack.cpp: Added. (JSC::HandleStack::HandleStack): (JSC::HandleStack::mark): (JSC::HandleStack::grow):
  • collector/handles/HandleStack.h: Added. (JSC::HandleStack::enterScope): (JSC::HandleStack::zapTo): (JSC::HandleStack::leaveScope): (JSC::HandleStack::push):
  • collector/handles/Local.h: Added. (JSC::Local::internalSet): (JSC::::Local): (JSC::::operator): (JSC::LocalStack::LocalStack): (JSC::LocalStack::peek): (JSC::LocalStack::pop): (JSC::LocalStack::push): (JSC::LocalStack::isEmpty): (JSC::LocalStack::size):
  • collector/handles/LocalScope.h: Added. (JSC::LocalScope::LocalScope): (JSC::LocalScope::~LocalScope): (JSC::LocalScope::release):
  • runtime/Heap.cpp: (JSC::Heap::markRoots):
  • runtime/Heap.h: (JSC::Heap::allocateLocalHandle): (JSC::Heap::handleStack):
  • runtime/JSCell.h: (JSC::JSCell::::getString):
  • runtime/JSGlobalData.cpp: (JSC::JSGlobalData::JSGlobalData):
  • runtime/JSGlobalData.h: (JSC::JSGlobalData::allocateLocalHandle):
  • runtime/JSONObject.cpp: (JSC::Stringifier::Stringifier): (JSC::Stringifier::stringify): (JSC::Stringifier::appendStringifiedValue): (JSC::Stringifier::Holder::Holder): (JSC::Walker::Walker): (JSC::Walker::walk): (JSC::JSONProtoFuncParse): (JSC::JSONProtoFuncStringify): (JSC::JSONStringify):
  • runtime/JSONObject.h:
  • runtime/MarkStack.h: (JSC::MarkStack::appendValues): (JSC::MarkStack::appendSlots):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/JSONObject.cpp

    r79240 r81188  
    3333#include "JSGlobalObject.h"
    3434#include "LiteralParser.h"
     35#include "Local.h"
     36#include "LocalScope.h"
    3537#include "Lookup.h"
    3638#include "PropertyNameArray.h"
     
    7577    WTF_MAKE_NONCOPYABLE(Stringifier);
    7678public:
    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>);
    8081
    8182    void markAggregate(MarkStack&);
     
    8485    class Holder {
    8586    public:
    86         Holder(JSObject*);
     87        Holder(JSGlobalData&, JSObject*);
    8788
    8889        JSObject* object() const { return m_object.get(); }
    89         DeprecatedPtr<JSObject>* objectSlot() { return &m_object; }
    9090
    9191        bool appendNextProperty(Stringifier&, UStringBuilder&);
    9292
    9393    private:
    94         DeprecatedPtr<JSObject> m_object;
     94        Local<JSObject> m_object;
    9595        const bool m_isArray;
    9696        bool m_isJSArray;
     
    114114    void startNewLine(UStringBuilder&) const;
    115115
    116     Stringifier* const m_nextStringifierToMark;
    117116    ExecState* const m_exec;
    118     const JSValue m_replacer;
     117    const Local<Unknown> m_replacer;
    119118    bool m_usingArrayReplacer;
    120119    PropertyNameArray m_arrayReplacerPropertyNames;
     
    123122    const UString m_gap;
    124123
    125     HashSet<JSObject*> m_holderCycleDetector;
    126124    Vector<Holder, 16> m_holderStack;
    127125    UString m_repeatedGap;
     
    200198// ------------------------------ Stringifier --------------------------------
    201199
    202 Stringifier::Stringifier(ExecState* exec, JSValue replacer, JSValue space)
    203     : m_nextStringifierToMark(exec->globalData().firstStringifierToMark)
    204     , m_exec(exec)
     200Stringifier::Stringifier(ExecState* exec, const Local<Unknown>& replacer, const Local<Unknown>& space)
     201    : m_exec(exec)
    205202    , m_replacer(replacer)
    206203    , m_usingArrayReplacer(false)
    207204    , m_arrayReplacerPropertyNames(exec)
    208205    , m_replacerCallType(CallTypeNone)
    209     , m_gap(gap(exec, space))
    210 {
    211     exec->globalData().firstStringifierToMark = this;
    212 
     206    , m_gap(gap(exec, space.get()))
     207{
    213208    if (!m_replacer.isObject())
    214209        return;
    215210
    216     if (asObject(m_replacer)->inherits(&JSArray::s_info)) {
     211    if (m_replacer.asObject()->inherits(&JSArray::s_info)) {
    217212        m_usingArrayReplacer = true;
    218         JSObject* array = asObject(m_replacer);
     213        Handle<JSObject> array = m_replacer.asObject();
    219214        unsigned length = array->get(exec, exec->globalData().propertyNames->length).toUInt32(exec);
    220215        for (unsigned i = 0; i < length; ++i) {
     
    247242    }
    248243
    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
     247Local<Unknown> Stringifier::stringify(Handle<Unknown> value)
    268248{
    269249    JSObject* object = constructEmptyObject(m_exec);
    270250    if (m_exec->hadException())
    271         return jsNull();
     251        return Local<Unknown>(m_exec->globalData(), jsNull());
    272252
    273253    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());
    275255
    276256    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());
    279259    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()));
    283263}
    284264
     
    373353        JSValue list[] = { propertyName.value(m_exec), value };
    374354        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);
    376356        if (m_exec->hadException())
    377357            return StringifyFailed;
     
    426406
    427407    // 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        }
    431413    }
    432414    bool holderStackWasEmpty = m_holderStack.isEmpty();
    433     m_holderStack.append(object);
     415    m_holderStack.append(Holder(m_exec->globalData(), object));
    434416    if (!holderStackWasEmpty)
    435417        return StringifySucceeded;
     
    451433            }
    452434        }
    453         m_holderCycleDetector.remove(m_holderStack.last().object());
    454435        m_holderStack.removeLast();
    455436    } while (!m_holderStack.isEmpty());
     
    486467}
    487468
    488 inline Stringifier::Holder::Holder(JSObject* object)
    489     : m_object(object)
     469inline Stringifier::Holder::Holder(JSGlobalData& globalData, JSObject* object)
     470    : m_object(globalData, object)
    490471    , m_isArray(object->inherits(&JSArray::s_info))
    491472    , m_index(0)
     
    624605}
    625606
    626 void JSONObject::markStringifiers(MarkStack& markStack, Stringifier* stringifier)
    627 {
    628     stringifier->markAggregate(markStack);
    629 }
    630 
    631607class Walker {
    632608public:
    633     Walker(ExecState* exec, JSObject* function, CallType callType, CallData callData)
     609    Walker(ExecState* exec, Handle<JSObject> function, CallType callType, CallData callData)
    634610        : m_exec(exec)
    635         , m_function(function)
     611        , m_function(exec->globalData(), function)
    636612        , m_callType(callType)
    637613        , m_callData(callData)
     
    650626
    651627    ExecState* m_exec;
    652     DeprecatedPtr<JSObject> m_function;
     628    Local<JSObject> m_function;
    653629    CallType m_callType;
    654630    CallData m_callData;
     
    664640    Vector<PropertyNameArray, 16> propertyStack;
    665641    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());
    668644   
    669645    Vector<WalkerState, 16> stateStack;
     
    685661
    686662                JSArray* array = asArray(inValue);
    687                 arrayStack.append(array);
     663                arrayStack.push(array);
    688664                indexStack.append(0);
    689665                // fallthrough
     
    697673                }
    698674
    699                 JSArray* array = arrayStack.last();
     675                JSArray* array = arrayStack.peek();
    700676                uint32_t index = indexStack.last();
    701677                if (index == array->length()) {
    702678                    outValue = array;
    703                     arrayStack.removeLast();
     679                    arrayStack.pop();
    704680                    indexStack.removeLast();
    705681                    break;
     
    723699            }
    724700            case ArrayEndVisitMember: {
    725                 JSArray* array = arrayStack.last();
     701                JSArray* array = arrayStack.peek();
    726702                JSValue filteredValue = callReviver(array, jsString(m_exec, UString::number(indexStack.last())), outValue);
    727703                if (filteredValue.isUndefined())
     
    746722
    747723                JSObject* object = asObject(inValue);
    748                 objectStack.append(object);
     724                objectStack.push(object);
    749725                indexStack.append(0);
    750726                propertyStack.append(PropertyNameArray(m_exec));
     
    760736                }
    761737
    762                 JSObject* object = objectStack.last();
     738                JSObject* object = objectStack.peek();
    763739                uint32_t index = indexStack.last();
    764740                PropertyNameArray& properties = propertyStack.last();
    765741                if (index == properties.size()) {
    766742                    outValue = object;
    767                     objectStack.removeLast();
     743                    objectStack.pop();
    768744                    indexStack.removeLast();
    769745                    propertyStack.removeLast();
     
    788764            }
    789765            case ObjectEndVisitMember: {
    790                 JSObject* object = objectStack.last();
     766                JSObject* object = objectStack.peek();
    791767                Identifier prop = propertyStack.last()[indexStack.last()];
    792768                PutPropertySlot slot;
     
    839815    if (exec->hadException())
    840816        return JSValue::encode(jsNull());
    841    
     817
     818    LocalScope scope(exec->globalData());
    842819    LiteralParser jsonParser(exec, source, LiteralParser::StrictJSON);
    843820    JSValue unfiltered = jsonParser.tryLiteralParse();
     
    853830    if (callType == CallTypeNone)
    854831        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));
    856833}
    857834
     
    861838    if (!exec->argumentCount())
    862839        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());
    867845}
    868846
    869847UString JSONStringify(ExecState* exec, JSValue value, unsigned indent)
    870848{
    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));
    872851    if (result.isUndefinedOrNull())
    873852        return UString();
Note: See TracChangeset for help on using the changeset viewer.