internal Precache some info
| 1603 | // internal |
| 1604 | // Precache some info |
| 1605 | void CScriptArray::Precache() |
| 1606 | { |
| 1607 | subTypeId = objType->GetSubTypeId(); |
| 1608 | |
| 1609 | // Check if it is an array of objects. Only for these do we need to cache anything |
| 1610 | // Type ids for primitives and enums only has the sequence number part |
| 1611 | if (!(subTypeId & ~asTYPEID_MASK_SEQNBR)) { |
| 1612 | return; |
| 1613 | } |
| 1614 | |
| 1615 | // The opCmp and opEquals methods are cached because the searching for the |
| 1616 | // methods is quite time consuming if a lot of array objects are created. |
| 1617 | |
| 1618 | // First check if a cache already exists for this array type |
| 1619 | SArrayCache* cache = static_cast<SArrayCache*>(objType->GetUserData(ARRAY_CACHE)); |
| 1620 | if (cache != nullptr) return; |
| 1621 | |
| 1622 | // We need to make sure the cache is created only once, even |
| 1623 | // if multiple threads reach the same point at the same time |
| 1624 | asAcquireExclusiveLock(); |
| 1625 | |
| 1626 | // Now that we got the lock, we need to check again to make sure the |
| 1627 | // cache wasn't created while we were waiting for the lock |
| 1628 | cache = static_cast<SArrayCache*>(objType->GetUserData(ARRAY_CACHE)); |
| 1629 | if (cache != nullptr) { |
| 1630 | asReleaseExclusiveLock(); |
| 1631 | return; |
| 1632 | } |
| 1633 | |
| 1634 | // Create the cache |
| 1635 | cache = static_cast<SArrayCache*>(asAllocMem(sizeof(SArrayCache))); |
| 1636 | if (cache == nullptr) { |
| 1637 | asIScriptContext* ctx = asGetActiveContext(); |
| 1638 | if (ctx != nullptr) { |
| 1639 | ctx->SetException("Out of memory"); |
| 1640 | } |
| 1641 | asReleaseExclusiveLock(); |
| 1642 | return; |
| 1643 | } |
| 1644 | std::memset(cache, 0, sizeof(SArrayCache)); |
| 1645 | |
| 1646 | // If the sub type is a handle to const, then the methods must be const too |
| 1647 | bool mustBeConst = (subTypeId & asTYPEID_HANDLETOCONST) ? true : false; |
| 1648 | |
| 1649 | asITypeInfo* subType = objType->GetEngine()->GetTypeInfoById(subTypeId); |
| 1650 | if (subType != nullptr) { |
| 1651 | for (std::uint32_t i = 0; i < subType->GetMethodCount(); i++) { |
| 1652 | asIScriptFunction* func = subType->GetMethodByIndex(i); |
| 1653 | |
| 1654 | if (func->GetParamCount() == 1 && (!mustBeConst || func->IsReadOnly())) { |
| 1655 | asDWORD flags = 0; |
| 1656 | std::int32_t returnTypeId = func->GetReturnTypeId(&flags); |
| 1657 | |
| 1658 | // The method must not return a reference |
| 1659 | if (flags != asTM_NONE) { |
| 1660 | continue; |
| 1661 | } |
| 1662 |
nothing calls this directly
no test coverage detected