static PassRefPtr<InspectorValue> jsToInspectorValue(ScriptState* scriptState, JSValue value)
{
    if (!value) {
        ASSERT_NOT_REACHED();
        return 0;
    }
    if (value.isNull() || value.isUndefined())
        return InspectorValue::null();
    if (value.isBoolean())
        return InspectorBasicValue::create(value.getBoolean());
    if (value.isNumber())
        return InspectorBasicValue::create(value.uncheckedGetNumber());
    if (value.isString()) {
        UString s = value.getString(scriptState);
        return InspectorString::create(String(s.characters(), s.length()));
    }
    if (value.isObject()) {
        if (isJSArray(&scriptState->globalData(), value)) {
            RefPtr<InspectorArray> inspectorArray = InspectorArray::create();
            JSArray* array = asArray(value);
            unsigned length = array->length();
            for (unsigned i = 0; i < length; i++) {
                JSValue element = array->getIndex(i);
                RefPtr<InspectorValue> elementValue = jsToInspectorValue(scriptState, element);
                if (!elementValue) {
                    ASSERT_NOT_REACHED();
                    elementValue = InspectorValue::null();
                }
                inspectorArray->pushValue(elementValue);
            }
            return inspectorArray;
        }
        RefPtr<InspectorObject> inspectorObject = InspectorObject::create();
        JSObject* object = value.getObject();
        PropertyNameArray propertyNames(scriptState);
        object->getOwnPropertyNames(scriptState, propertyNames);
        for (size_t i = 0; i < propertyNames.size(); i++) {
            const Identifier& name =  propertyNames[i];
            JSValue propertyValue = object->get(scriptState, name);
            RefPtr<InspectorValue> inspectorValue = jsToInspectorValue(scriptState, propertyValue);
            if (!inspectorValue) {
                ASSERT_NOT_REACHED();
                inspectorValue = InspectorValue::null();
            }
            inspectorObject->setValue(String(name.characters(), name.length()), inspectorValue);
        }
        return inspectorObject;
    }
    ASSERT_NOT_REACHED();
    return 0;
}
Example #2
0
void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
    getOwnPropertyNames(exec, propertyNames, mode);

    if (prototype().isNull())
        return;

    JSObject* prototype = asObject(this->prototype());
    while(1) {
        if (prototype->structure()->typeInfo().overridesGetPropertyNames()) {
            prototype->getPropertyNames(exec, propertyNames, mode);
            break;
        }
        prototype->getOwnPropertyNames(exec, propertyNames, mode);
        JSValue nextProto = prototype->prototype();
        if (nextProto.isNull())
            break;
        prototype = asObject(nextProto);
    }
}
Example #3
0
void Structure::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject)
{
    bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || isDictionary());

    if (shouldCache && m_cachedPropertyNameArrayData) {
        if (m_cachedPropertyNameArrayData->cachedPrototypeChain() == prototypeChain(exec)) {
            propertyNames.setData(m_cachedPropertyNameArrayData);
            return;
        }
        clearEnumerationCache();
    }

    baseObject->getOwnPropertyNames(exec, propertyNames);

    if (m_prototype.isObject()) {
        propertyNames.setShouldCache(false); // No need for our prototypes to waste memory on caching, since they're not being enumerated directly.
        JSObject* prototype = asObject(m_prototype);
        while(1) {
            if (!prototype->structure()->typeInfo().hasDefaultGetPropertyNames()) {
                prototype->getPropertyNames(exec, propertyNames);
                break;
            }
            prototype->getOwnPropertyNames(exec, propertyNames);
            JSValue nextProto = prototype->prototype();
            if (!nextProto.isObject())
                break;
            prototype = asObject(nextProto);
        }
    }

    if (shouldCache) {
        StructureChain* protoChain = prototypeChain(exec);
        m_cachedPropertyNameArrayData = propertyNames.data();
        if (!protoChain->isCacheable())
            return;
        m_cachedPropertyNameArrayData->setCachedPrototypeChain(protoChain);
        m_cachedPropertyNameArrayData->setCachedStructure(this);
    }
}