1f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===- RpnEvaluator.cpp ---------------------------------------------------===// 2f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// 3f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// The MCLinker Project 4f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// 5f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// This file is distributed under the University of Illinois Open Source 6f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// License. See LICENSE.TXT for details. 7f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// 8f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 9f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Support/MsgHandling.h> 10f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/LD/LDSymbol.h> 11f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Script/RpnExpr.h> 12f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Script/RpnEvaluator.h> 13f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Script/ExprToken.h> 14f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Script/Operator.h> 15f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Script/Operand.h> 16f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Module.h> 17f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <llvm/Support/Casting.h> 18f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <llvm/Support/DataTypes.h> 19f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <stack> 20f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <cassert> 21f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 22f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesusing namespace mcld; 23f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 24f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesRpnEvaluator::RpnEvaluator(const Module& pModule, 25f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const TargetLDBackend& pBackend) 26f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines : m_Module(pModule), 27f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_Backend(pBackend) 28f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 29f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 30f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 31f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool RpnEvaluator::eval(const RpnExpr& pExpr, uint64_t& pResult) 32f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 33f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines std::stack<Operand*> operandStack; 34f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (RpnExpr::const_iterator it = pExpr.begin(), ie = pExpr.end(); it != ie; 35f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ++it) { 36f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines switch((*it)->kind()) { 37f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case ExprToken::OPERATOR: { 38f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Operator* op = llvm::cast<Operator>(*it); 39f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines switch (op->arity()) { 40f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case Operator::NULLARY: { 41f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines operandStack.push(op->eval(m_Module, m_Backend)); 42f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 43f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 44f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case Operator::UNARY: { 45f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Operand* opd = operandStack.top(); 46f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines operandStack.pop(); 47f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines op->appendOperand(opd); 48f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines operandStack.push(op->eval(m_Module, m_Backend)); 49f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 50f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 51f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case Operator::BINARY: { 52f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Operand* opd2 = operandStack.top(); 53f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines operandStack.pop(); 54f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Operand* opd1 = operandStack.top(); 55f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines operandStack.pop(); 56f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines op->appendOperand(opd1); 57f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines op->appendOperand(opd2); 58f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines operandStack.push(op->eval(m_Module, m_Backend)); 59f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 60f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 61f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case Operator::TERNARY: { 62f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Operand* opd3 = operandStack.top(); 63f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines operandStack.pop(); 64f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Operand* opd2 = operandStack.top(); 65f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines operandStack.pop(); 66f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Operand* opd1 = operandStack.top(); 67f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines operandStack.pop(); 68f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines op->appendOperand(opd1); 69f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines op->appendOperand(opd2); 70f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines op->appendOperand(opd3); 71f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines operandStack.push(op->eval(m_Module, m_Backend)); 72f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 73f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 74f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } // end of switch operator arity 75f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 76f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 77f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 78f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case ExprToken::OPERAND: { 79f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Operand* opd = llvm::cast<Operand>(*it); 80f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines switch (opd->type()) { 81f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case Operand::SYMBOL: { 82f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // It's possible that there are no operators in an expression, so 83f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // we set up symbol operand here. 84f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!opd->isDot()) { 85f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines SymOperand* sym_opd = llvm::cast<SymOperand>(opd); 86f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const LDSymbol* symbol = 87f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_Module.getNamePool().findSymbol(sym_opd->name()); 88f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (symbol == NULL) { 89f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines fatal(diag::fail_sym_resolution) << __FILE__ << __LINE__ 90f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines << "mclinker@googlegroups.com"; 91f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 92f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines sym_opd->setValue(symbol->value()); 93f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 94f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines operandStack.push(opd); 95f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 96f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 97f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines default: 98f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines operandStack.push(opd); 99f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 100f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } // end of switch operand type 101f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 102f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 103f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 104f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } // end of switch 105f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } // end of for 106f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 107f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // stack top is result 108f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines assert(operandStack.top()->type() == Operand::SYMBOL || 109f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines operandStack.top()->type() == Operand::INTEGER || 110f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines operandStack.top()->type() == Operand::FRAGMENT); 111f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pResult = operandStack.top()->value(); 112f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return true; 113f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 114f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 115