⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jsarray.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    unsigned vectorLength = storage->m_vectorLength;    Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength));    if (newNumValuesInVector == storage->m_numValuesInVector + 1) {        for (unsigned j = vectorLength; j < newVectorLength; ++j)            storage->m_vector[j] = noValue();        if (i > MIN_SPARSE_ARRAY_INDEX)            map->remove(i);    } else {        for (unsigned j = vectorLength; j < max(vectorLength, MIN_SPARSE_ARRAY_INDEX); ++j)            storage->m_vector[j] = noValue();        for (unsigned j = max(vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j)            storage->m_vector[j] = map->take(j);    }    storage->m_vector[i] = value;    storage->m_vectorLength = newVectorLength;    storage->m_numValuesInVector = newNumValuesInVector;    m_storage = storage;    checkConsistency();}bool JSArray::deleteProperty(ExecState* exec, const Identifier& propertyName){    bool isArrayIndex;    unsigned i = propertyName.toArrayIndex(&isArrayIndex);    if (isArrayIndex)        return deleteProperty(exec, i);    if (propertyName == exec->propertyNames().length)        return false;    return JSObject::deleteProperty(exec, propertyName);}bool JSArray::deleteProperty(ExecState* exec, unsigned i){    checkConsistency();    ArrayStorage* storage = m_storage;    if (i < storage->m_vectorLength) {        JSValuePtr& valueSlot = storage->m_vector[i];        if (!valueSlot) {            checkConsistency();            return false;        }        valueSlot = noValue();        --storage->m_numValuesInVector;        if (m_fastAccessCutoff > i)            m_fastAccessCutoff = i;        checkConsistency();        return true;    }    if (SparseArrayValueMap* map = storage->m_sparseValueMap) {        if (i >= MIN_SPARSE_ARRAY_INDEX) {            SparseArrayValueMap::iterator it = map->find(i);            if (it != map->end()) {                map->remove(it);                checkConsistency();                return true;            }        }    }    checkConsistency();    if (i > MAX_ARRAY_INDEX)        return deleteProperty(exec, Identifier::from(exec, i));    return false;}void JSArray::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames){    // FIXME: Filling PropertyNameArray with an identifier for every integer    // is incredibly inefficient for large arrays. We need a different approach,    // which almost certainly means a different structure for PropertyNameArray.    ArrayStorage* storage = m_storage;    unsigned usedVectorLength = min(storage->m_length, storage->m_vectorLength);    for (unsigned i = 0; i < usedVectorLength; ++i) {        if (storage->m_vector[i])            propertyNames.add(Identifier::from(exec, i));    }    if (SparseArrayValueMap* map = storage->m_sparseValueMap) {        SparseArrayValueMap::iterator end = map->end();        for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it)            propertyNames.add(Identifier::from(exec, it->first));    }    JSObject::getPropertyNames(exec, propertyNames);}bool JSArray::increaseVectorLength(unsigned newLength){    // This function leaves the array in an internally inconsistent state, because it does not move any values from sparse value map    // to the vector. Callers have to account for that, because they can do it more efficiently.    ArrayStorage* storage = m_storage;    unsigned vectorLength = storage->m_vectorLength;    ASSERT(newLength > vectorLength);    ASSERT(newLength <= MAX_STORAGE_VECTOR_INDEX);    unsigned newVectorLength = increasedVectorLength(newLength);    storage = static_cast<ArrayStorage*>(tryFastRealloc(storage, storageSize(newVectorLength)));    if (!storage)        return false;    Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength));    storage->m_vectorLength = newVectorLength;    for (unsigned i = vectorLength; i < newVectorLength; ++i)        storage->m_vector[i] = noValue();    m_storage = storage;    return true;}void JSArray::setLength(unsigned newLength){    checkConsistency();    ArrayStorage* storage = m_storage;    unsigned length = m_storage->m_length;    if (newLength < length) {        if (m_fastAccessCutoff > newLength)            m_fastAccessCutoff = newLength;        unsigned usedVectorLength = min(length, storage->m_vectorLength);        for (unsigned i = newLength; i < usedVectorLength; ++i) {            JSValuePtr& valueSlot = storage->m_vector[i];            bool hadValue = valueSlot;            valueSlot = noValue();            storage->m_numValuesInVector -= hadValue;        }        if (SparseArrayValueMap* map = storage->m_sparseValueMap) {            SparseArrayValueMap copy = *map;            SparseArrayValueMap::iterator end = copy.end();            for (SparseArrayValueMap::iterator it = copy.begin(); it != end; ++it) {                if (it->first >= newLength)                    map->remove(it->first);            }            if (map->isEmpty()) {                delete map;                storage->m_sparseValueMap = 0;            }        }    }    m_storage->m_length = newLength;    checkConsistency();}JSValuePtr JSArray::pop(){    checkConsistency();    unsigned length = m_storage->m_length;    if (!length)        return jsUndefined();    --length;    JSValuePtr result;    if (m_fastAccessCutoff > length) {        JSValuePtr& valueSlot = m_storage->m_vector[length];        result = valueSlot;        ASSERT(result);        valueSlot = noValue();        --m_storage->m_numValuesInVector;        m_fastAccessCutoff = length;    } else if (length < m_storage->m_vectorLength) {        JSValuePtr& valueSlot = m_storage->m_vector[length];        result = valueSlot;        valueSlot = noValue();        if (result)            --m_storage->m_numValuesInVector;        else            result = jsUndefined();    } else {        result = jsUndefined();        if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) {            SparseArrayValueMap::iterator it = map->find(length);            if (it != map->end()) {                result = it->second;                map->remove(it);                if (map->isEmpty()) {                    delete map;                    m_storage->m_sparseValueMap = 0;                }            }        }    }    m_storage->m_length = length;    checkConsistency();    return result;}void JSArray::push(ExecState* exec, JSValuePtr value){    checkConsistency();    if (m_storage->m_length < m_storage->m_vectorLength) {        ASSERT(!m_storage->m_vector[m_storage->m_length]);        m_storage->m_vector[m_storage->m_length] = value;        if (++m_storage->m_numValuesInVector == ++m_storage->m_length)            m_fastAccessCutoff = m_storage->m_length;        checkConsistency();        return;    }    if (m_storage->m_length < MIN_SPARSE_ARRAY_INDEX) {        SparseArrayValueMap* map = m_storage->m_sparseValueMap;        if (!map || map->isEmpty()) {            if (increaseVectorLength(m_storage->m_length + 1)) {                m_storage->m_vector[m_storage->m_length] = value;                if (++m_storage->m_numValuesInVector == ++m_storage->m_length)                    m_fastAccessCutoff = m_storage->m_length;                checkConsistency();                return;            }            checkConsistency();            throwOutOfMemoryError(exec);            return;        }    }    putSlowCase(exec, m_storage->m_length++, value);}void JSArray::mark(){    JSObject::mark();    ArrayStorage* storage = m_storage;    unsigned usedVectorLength = min(storage->m_length, storage->m_vectorLength);    for (unsigned i = 0; i < usedVectorLength; ++i) {        JSValuePtr value = storage->m_vector[i];        if (value && !value.marked())            value.mark();    }    if (SparseArrayValueMap* map = storage->m_sparseValueMap) {        SparseArrayValueMap::iterator end = map->end();        for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) {            JSValuePtr value = it->second;            if (!value.marked())                value.mark();        }    }}static int compareNumbersForQSort(const void* a, const void* b){    double da = static_cast<const JSValuePtr*>(a)->uncheckedGetNumber();    double db = static_cast<const JSValuePtr*>(b)->uncheckedGetNumber();    return (da > db) - (da < db);}typedef std::pair<JSValuePtr, UString> ValueStringPair;static int compareByStringPairForQSort(const void* a, const void* b){    const ValueStringPair* va = static_cast<const ValueStringPair*>(a);    const ValueStringPair* vb = static_cast<const ValueStringPair*>(b);    return compare(va->second, vb->second);}void JSArray::sortNumeric(ExecState* exec, JSValuePtr compareFunction, CallType callType, const CallData& callData){    unsigned lengthNotIncludingUndefined = compactForSorting();    if (m_storage->m_sparseValueMap) {        throwOutOfMemoryError(exec);        return;    }    if (!lengthNotIncludingUndefined)        return;            bool allValuesAreNumbers = true;    size_t size = m_storage->m_numValuesInVector;    for (size_t i = 0; i < size; ++i) {        if (!m_storage->m_vector[i].isNumber()) {            allValuesAreNumbers = false;            break;        }    }    if (!allValuesAreNumbers)        return sort(exec, compareFunction, callType, callData);    // For numeric comparison, which is fast, qsort is faster than mergesort. We    // also don't require mergesort's stability, since there's no user visible    // side-effect from swapping the order of equal primitive values.    qsort(m_storage->m_vector, size, sizeof(JSValuePtr), compareNumbersForQSort);    checkConsistency(SortConsistencyCheck);}void JSArray::sort(ExecState* exec){    unsigned lengthNotIncludingUndefined = compactForSorting();    if (m_storage->m_sparseValueMap) {        throwOutOfMemoryError(exec);        return;    }    if (!lengthNotIncludingUndefined)        return;    // Converting JavaScript values to strings can be expensive, so we do it once up front and sort based on that.    // This is a considerable improvement over doing it twice per comparison, though it requires a large temporary    // buffer. Besides, this protects us from crashing if some objects have custom toString methods that return    // random or otherwise changing results, effectively making compare function inconsistent.    Vector<ValueStringPair> values(lengthNotIncludingUndefined);    if (!values.begin()) {        throwOutOfMemoryError(exec);        return;    }    for (size_t i = 0; i < lengthNotIncludingUndefined; i++) {        JSValuePtr value = m_storage->m_vector[i];        ASSERT(!value.isUndefined());        values[i].first = value;    }    // FIXME: While calling these toString functions, the array could be mutated.    // In that case, objects pointed to by values in this vector might get garbage-collected!    // FIXME: The following loop continues to call toString on subsequent values even after

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -