diff --git a/include/inference.h b/include/inference.h index b116fa7..2979934 100644 --- a/include/inference.h +++ b/include/inference.h @@ -387,7 +387,7 @@ struct TContextStack { class TypeSystem { public: - TypeSystem(SmalltalkVM& vm) : m_vm(vm), m_lastContextIndex(0) {} + TypeSystem(SmalltalkVM& vm) : m_vm(vm), m_lastContextIndex(1) {} typedef TSymbol* TSelector; diff --git a/include/types.h b/include/types.h index 0116758..44720f1 100644 --- a/include/types.h +++ b/include/types.h @@ -70,6 +70,8 @@ struct TInteger { int32_t operator -(int32_t right) const { return getValue() - right; } operator TObject*() const { return reinterpret_cast(m_value); } + void setRawValue(int32_t value) { m_value = value; } + private: int32_t m_value; protected: diff --git a/src/ControlGraph.cpp b/src/ControlGraph.cpp index 5250735..5530e2c 100644 --- a/src/ControlGraph.cpp +++ b/src/ControlGraph.cpp @@ -190,9 +190,13 @@ void GraphConstructor::processNode(InstructionNode* node) if (instruction.getArgument() == 0) m_graph->getMeta().usesSelf = true; ControlGraph::TMetaInfo::insertIndex(instruction.getArgument(), m_graph->getMeta().readsArguments); + m_currentDomain->pushValue(node); + break; case opcode::pushInstance: m_graph->getMeta().readsFields = true; + m_currentDomain->pushValue(node); + break; case opcode::pushTemporary: ControlGraph::TMetaInfo::insertIndex(instruction.getArgument(), m_graph->getMeta().readsTemporaries); diff --git a/src/JITRuntime.cpp b/src/JITRuntime.cpp index 0369e88..baacd50 100644 --- a/src/JITRuntime.cpp +++ b/src/JITRuntime.cpp @@ -226,7 +226,7 @@ TBlock* JITRuntime::createBlock(TContext* callingContext, uint8_t argLocation, u // NOTE This field is used by JIT VM to aid specialization lookup // See MethodCompiler::getClosureMask() and lookupBlockFunctionInCache() - newBlock->stackTop = stackTop; + newBlock->stackTop.setRawValue(stackTop); // Assigning creatingContext depending on the hierarchy // Nested blocks inherit the outer creating context @@ -557,6 +557,7 @@ void JITRuntime::updateBlockFunctionCache(TBlock* block, TBlockFunction function // We have found a slot that may be used fillBlockSlot(slot, block, function); + return; } // It seem that all slots are occupied by the friendly specializations. diff --git a/src/MethodCompiler.cpp b/src/MethodCompiler.cpp index 90656ad..916ba0b 100644 --- a/src/MethodCompiler.cpp +++ b/src/MethodCompiler.cpp @@ -928,7 +928,7 @@ void createBlockTypes( blockArguments.set(globals.arrayClass, type::Type::tkArray); - TObjectArray& temporaries = * block->creatingContext->temporaries; + TObjectArray& temporaries = * block->temporaries; const uint32_t argumentLocation = block->argumentLocation; const st::ControlGraph::TMetaInfo::TIndexList& readsTemporaries = blockGraph.getMeta().readsTemporaries; @@ -943,14 +943,13 @@ void createBlockTypes( TClass* const klass = isSmallInteger(argument) ? globals.smallIntClass : argument->getClass(); const type::Type newType(klass); - if (readsTemporaries[index] < argumentLocation) + if (readsTemporaries[index] < argumentLocation) { closureTypes[tempIndex] = newType; - else blockTemps.pushSubType(newType); - - // We're interested only in temporaries from lexical context, not block arguments - if (readsTemporaries[index] < argumentLocation) - readIndices.pushSubType(type::Type(TInteger(readsTemporaries[index]))); + readIndices.pushSubType(type::Type(TInteger(tempIndex))); + } else { + blockArguments.pushSubType(newType); + } } for (std::size_t index = 0; index < writesTemporaries.size(); index++) { @@ -1308,10 +1307,13 @@ void MethodCompiler::doSendBinary(TJITContext& jit) const type::Type& resultType = jit.inferContext[*jit.currentNode]; if (leftType.isLiteral() && rightType.isLiteral()) { - ConstantInt* const rawResult = jit.builder->getInt32(TInteger(resultType.getValue())); - Value* const result = jit.builder->CreateCall(m_baseFunctions.newInteger, rawResult); - setNodeValue(jit, jit.currentNode, result); - return; + // TODO Extend to all literals + if (isSmallInteger(resultType.getValue())) { + ConstantInt* const rawResult = jit.builder->getInt32(TInteger(resultType.getValue())); + Value* const result = jit.builder->CreateCall(m_baseFunctions.newInteger, rawResult); + setNodeValue(jit, jit.currentNode, result); + return; + } } // Literal int or (SmallInt) monotype diff --git a/src/TypeAnalyzer.cpp b/src/TypeAnalyzer.cpp index 8b29892..f559eb2 100644 --- a/src/TypeAnalyzer.cpp +++ b/src/TypeAnalyzer.cpp @@ -202,6 +202,7 @@ void TypeAnalyzer::run(const Type* blockType /*= 0*/) { m_baseRun = true; m_literalBranch = true; + m_tauLinker.reset(); m_tauLinker.run(); bool singleReturn = basicRun(); @@ -564,6 +565,8 @@ void TypeAnalyzer::doPushTemporary(const InstructionNode& instruction) { InferContext::TVariableMap& closureTypes = methodContext->getBlockClosures()[captureIndex]; m_context[instruction] = closureTypes[tempIndex]; + } else { + std::cout << "Could not find method context for block " << m_blockType->toString() << std::endl; } } } else {