Пример #1
0
InvokeEntry* lookupInvokeEntry(ObjectPtr callable,
                               llvm::ArrayRef<TypePtr> argsKey,
                               llvm::ArrayRef<ValueTempness> argsTempness,
                               MatchFailureError &failures)
{
    InvokeSet* invokeSet = lookupInvokeSet(callable, argsKey);

    map<vector<ValueTempness>,InvokeEntry*>::iterator iter =
        invokeSet->tempnessMap.find(argsTempness);
    if (iter != invokeSet->tempnessMap.end())
        return iter->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) {
        if (matchTempness(match->code,
                          argsTempness,
                          match->callByName,
                          tempnessKey,
                          forwardedRValueFlags))
        {
            break;
        }
        ++i;
    }
    if (!match)
        return NULL;

    iter = invokeSet->tempnessMap2.find(tempnessKey);
    if (iter != invokeSet->tempnessMap2.end()) {
        invokeSet->tempnessMap[argsTempness] = iter->second;
        return iter->second;
    }

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

    return entry;
}
Пример #2
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;
}