void TypeInference::inferTypes( const list<ClassDefBasePtr>& classes, const StaticContextPtr& pRootCtx, const LogPtr& pLog) { list<ClassDefBasePtr>::const_iterator cit; for (cit = classes.begin(); cit != classes.end(); cit++) { const ClassDefBasePtr& pClassDefBase = *cit; if (pClassDefBase->getASTNodeType() == ASTN_INTERFACE) { continue; } StaticContextPtr pClassCtx; StaticContextHelper::newClassContext(pClassCtx, pClassDefBase, pRootCtx, pLog); StaticContextPtr pInstanceCtx; StaticContextHelper::newInstanceContext(pInstanceCtx, pClassDefBase, pRootCtx, pLog); const list<VariableDeclDefPtr>& variables = pClassDefBase->getVariableDecls(); list<VariableDeclDefPtr>::const_iterator vit; for (vit = variables.begin(); vit != variables.end(); vit++) { const VariableDeclDefPtr& pVariable = *vit; const ValueDefPtr& pValueDef = pVariable->getValue(); if (pValueDef.get() == NULL) { // this is reported by ClassCheck continue; } StaticContextPtr& pParentCtx = (pVariable->isStatic() ? pClassCtx : pInstanceCtx); StaticContextPtr pMemberCtx(new StaticContext(pParentCtx, pVariable->isStatic())); inferTypes(*pValueDef, pMemberCtx, pLog); StaticContextEntryPtr pEntry(new StaticContextEntry(pVariable)); pParentCtx->addEntry(pEntry); } } }
void dvmCompilerRegAlloc(CompilationUnit *cUnit) { int i; int seqNum = 0; LiveRange *ranges; RegLocation *loc; int *ssaToDalvikMap = (int *) cUnit->ssaToDalvikMap->elemList; /* Allocate the location map */ loc = (RegLocation*)dvmCompilerNew(cUnit->numSSARegs * sizeof(*loc), true); for (i=0; i< cUnit->numSSARegs; i++) { loc[i] = freshLoc; loc[i].sRegLow = i; } cUnit->regLocation = loc; /* Do type inference pass */ for (i=0; i < cUnit->numBlocks; i++) { inferTypes(cUnit, cUnit->blockList[i]); } if (simpleTrace(cUnit)) { /* * Just rename everything back to subscript 0 names and don't do * any explicit promotion. Local allocator will opportunistically * promote on the fly. */ for (i=0; i < cUnit->numSSARegs; i++) { cUnit->regLocation[i].sRegLow = DECODE_REG(dvmConvertSSARegToDalvik(cUnit, loc[i].sRegLow)); } } else { // Compute live ranges ranges = dvmCompilerNew(cUnit->numSSARegs * sizeof(*ranges), true); for (i=0; i < cUnit->numSSARegs; i++) ranges[i].active = false; seqNum = computeLiveRange(ranges, cUnit->blockList[i], seqNum); //TODO: phi squash & linear scan promotion } }
void TypeInference::inferTypes( ValueDef& valueDef, StaticContextPtr& pMemberCtx, const LogPtr& pLog) { switch (valueDef.getValueType()) { case OBJECT_INIT: { const ObjectInitValueDef& objectInitDef = static_cast<const ObjectInitValueDef&>(valueDef); TypePtr pType = TypePtr( new ReferenceType(OBJECT_REF_TYPE, objectInitDef.getClassName())); valueDef.setInferredType(pType); const map<const wstring, ActualParamDefPtr>& actualParamsMap = objectInitDef.getActualParamsMap(); map<const wstring, ActualParamDefPtr>::const_iterator it; for (it = actualParamsMap.begin(); it != actualParamsMap.end(); it++) { const ActualParamDefPtr& pActualParamDef = (*it).second; const ValueDefPtr& pParamValueDef = pActualParamDef->getValue(); inferTypes(*pParamValueDef, pMemberCtx, pLog); } } break; case ARRAY_INIT: { const ArrayInitValueDef& arrayInitDef = static_cast<const ArrayInitValueDef&>(valueDef); valueDef.setInferredType(arrayInitDef.getDeclaredType()); const list<ValueDefPtr>& arrayValues = arrayInitDef.getValues(); list<ValueDefPtr>::const_iterator it; for (it = arrayValues.begin(); it != arrayValues.end(); it++) { const ValueDefPtr& pArrayValue = *it; inferTypes(*pArrayValue, pMemberCtx, pLog); } } break; case LITERAL: { const LiteralValueDef& literalDef = static_cast<const LiteralValueDef&>(valueDef); switch (literalDef.getLiteralType()) { case INTEGER_LITERAL: valueDef.setInferredType(P_INTEGER_TYPE); break; case FLOAT_LITERAL: valueDef.setInferredType(P_FLOAT_TYPE); break; case STRING_LITERAL: valueDef.setInferredType(P_STRING_TYPE); break; default: assert(false); break; } } break; case REFERENCE_PATH: { const ReferencePathValueDef& referencePathDef = static_cast<const ReferencePathValueDef&>(valueDef); const list<const wstring>& path = referencePathDef.getReferencePath(); StaticContextEntryPtr pEntry; TypePtr pCurrentType; list<const wstring>::const_iterator it; wstring parentPath(L""); for (it = path.begin(); it != path.end(); it++) { const wstring& pathElement = *it; if (it == path.begin()) { CStaticContextEntryPtr pEntry; if (!pMemberCtx->lookup(pathElement, pEntry)) { boost::wformat f(L"Unable to resolve name %1%"); f % pathElement; pLog->log(referencePathDef, msg::ErrAnaTypeInfer_NameNotInContext, f.str()); return; } else { switch (pEntry->getStaticEntryType()) { case CLASS_DEF_CTX_ENTRY: { TypePtr pType(new ReferenceType(CLASS_REF_TYPE, pEntry->getName())); pCurrentType = pType; } break; case INTERFACE_DEF_CTX_ENTRY: { TypePtr pType(new ReferenceType(CLASS_REF_TYPE, pEntry->getName())); pCurrentType = pType; } break; case VARIABLE_DEF_CTX_ENTRY: { VariableDeclDefPtr pVariableDef; pEntry->getVariable(pVariableDef); if (pMemberCtx->isStatic() && !pVariableDef->isStatic()) { boost::wformat f(L"Cannot refer to a non static variable from an static context: %1%"); f % pathElement; pLog->log(referencePathDef, msg::ErrAnaTypeInfer_NonStaticVarRef, f.str()); return; } else { pCurrentType = pVariableDef->getDeclaredType(); } } break; case FORMAL_PARAM_DEF_CTX_ENTRY: { if (pMemberCtx->isStatic()) { boost::wformat f(L"Cannot refer to a class parameter from an static context: %1%"); f % pathElement; pLog->log(referencePathDef, msg::ErrAnaTypeInfer_NonStaticParamRef, f.str()); return; } FormalParamDefPtr pFormalParamDef; pEntry->getFormalParam(pFormalParamDef); pCurrentType = pFormalParamDef->getType(); } break; default: assert(false); return; } } } else { assert(pCurrentType.get() != NULL); StaticContextPtr pRootCtx; pMemberCtx->getRootContext(pRootCtx); if (!followPathElement( *pCurrentType, *pRootCtx, pathElement, pCurrentType)) { boost::wformat f(L"%1% is not a member of %2%"); f % pathElement % parentPath; pLog->log(referencePathDef, msg::ErrAnaTypeInfer_NotAMember, f.str()); return; } } if (parentPath.size()) { parentPath.append(L"."); } parentPath.append(pathElement); } assert(pCurrentType.get() != NULL); valueDef.setInferredType(pCurrentType); } break; default: assert(false); break; } }