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; }
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; }
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; }