예제 #1
0
InvokeSetPtr lookupInvokeSet(ObjectPtr callable,
                             const vector<TypePtr> &argsKey)
{
    if (!invokeTablesInitialized)
        initInvokeTables();
    int h = objectHash(callable) + objectVectorHash(argsKey);
    h &= (invokeTable.size() - 1);
    vector<InvokeSetPtr> &bucket = invokeTable[h];
    for (unsigned i = 0; i < bucket.size(); ++i) {
        InvokeSetPtr invokeSet = bucket[i];
        if (objectEquals(invokeSet->callable, callable) &&
            objectVectorEquals(invokeSet->argsKey, argsKey))
        {
            return invokeSet;
        }
    }
    OverloadPtr interface = callableInterface(callable);
    const vector<OverloadPtr> &overloads = callableOverloads(callable);
    InvokeSetPtr invokeSet = new InvokeSet(callable, argsKey, interface, overloads);
    bucket.push_back(invokeSet);
    return invokeSet;
}
예제 #2
0
InvokeSet* lookupInvokeSet(ObjectPtr callable,
                             llvm::ArrayRef<TypePtr> argsKey)
{
    if (!invokeTablesInitialized)
        initInvokeTables();
    int h = objectHash(callable) + objectVectorHash(argsKey);
    h &= (invokeTable.size() - 1);
    llvm::SmallVector<InvokeSet*, 2> &bucket = invokeTable[h];
    for (unsigned i = 0; i < bucket.size(); ++i) {
        InvokeSet* invokeSet = bucket[i];
        if (objectEquals(invokeSet->callable, callable) &&
            objectVectorEquals(invokeSet->argsKey, argsKey))
        {
            return invokeSet;
        }
    }
    OverloadPtr interface = callableInterface(callable);
    llvm::ArrayRef<OverloadPtr> overloads = callableOverloads(callable);
    InvokeSet* invokeSet = new InvokeSet(callable, argsKey, interface, overloads);
    invokeSet->shouldLog = shouldLogCallable(callable);

    bucket.push_back(invokeSet);
    return invokeSet;
}
예제 #3
0
InvokeEntry* lookupInvokeEntry(ObjectPtr callable,
                               llvm::ArrayRef<PVData> args,
                               MatchFailureError &failures)
{
    vector<TypePtr> argTypes;
    vector<bool> argRValues;

    argTypes.reserve(args.size());
    argRValues.reserve(args.size());

    for (llvm::ArrayRef<PVData>::const_iterator arg = args.begin(); arg != args.end(); ++arg) {
        argTypes.push_back(arg->type);
        argRValues.push_back(arg->isRValue);
    }

    InvokeSet* invokeSet = lookupInvokeSet(callable, argTypes);

    if (invokeSet->evaluatingPredicate) {
        // matchInvoke calls the same lookupInvokeEntry
        error("predicate evaluation loop");
    }

    invokeSet->evaluatingPredicate = true;
    FinallyClearEvaluatingPredicate FinallyClearEvaluatingPredicate(invokeSet);

    map<vector<bool>, InvokeEntry*>::iterator iter1 =
        invokeSet->tempnessMap.find(argRValues);
    if (iter1 != invokeSet->tempnessMap.end())
        return iter1->second;
    
    MatchResultPtr interfaceResult;
    if (invokeSet->interface != NULL) {
        interfaceResult = matchInvoke(invokeSet->interface,
                                                     invokeSet->callable,
                                                     invokeSet->argsKey);
        if (interfaceResult->matchCode != MATCH_SUCCESS) {
            failures.failedInterface = true;
            failures.failures.push_back(make_pair(invokeSet->interface, interfaceResult));
            return NULL;
        }
    }

    MatchSuccessPtr match;
    vector<ValueTempness> tempnessKey;
    vector<uint8_t> forwardedRValueFlags;
    
    unsigned i = 0;
    while ((match = getMatch(invokeSet,i,failures)).ptr() != NULL) {
        tempnessKey.clear();
        forwardedRValueFlags.clear();
        if (matchTempness(match->overload->code,
                          argRValues,
                          match->overload->callByName,
                          tempnessKey,
                          forwardedRValueFlags))
        {
            break;
        }
        ++i;
    }
    if (!match)
        return NULL;

    map<vector<ValueTempness>, InvokeEntry*>::iterator iter2 =
            invokeSet->tempnessMap2.find(tempnessKey);
    if (iter2 != invokeSet->tempnessMap2.end()) {
        invokeSet->tempnessMap[argRValues] = iter2->second;
        return iter2->second;
    }

    InvokeEntry* entry = newInvokeEntry(invokeSet, match,
        (MatchSuccess*)interfaceResult.ptr());
    entry->forwardedRValueFlags = forwardedRValueFlags;
    
    invokeSet->tempnessMap2[tempnessKey] = entry;
    invokeSet->tempnessMap[argRValues] = entry;

    if (_finalOverloadsEnabled) {
        MatchSuccessPtr match2;
        vector<ValueTempness> tempnessKey2;
        vector<uint8_t> forwardedRValueFlags2;
        unsigned j = invokeSet->nextOverloadIndex;
        while ((match2 = findMatchingInvoke(callableOverloads(callable),
                                           j,
                                           callable,
                                           argTypes,
                                           failures)).ptr() != NULL) {
            if (matchTempness(match2->overload->code,
                              argRValues,
                              match2->overload->callByName,
                              tempnessKey2,
                              forwardedRValueFlags2))
            {
                break;
            }
            ++j;
        }

        if (match2 != NULL && !match2->overload->isDefault) {
            failures.ambiguousMatch = true;
            return NULL;    
        }
    }

    return entry;
}