void Value::toLLVMValue(Builder *builder) { if (isConstant()) { mValue = builder->llvmValue(constant()); mConstant = ConstantValue(); mType = tNormalValue; } }
Value NullValueType::generateOperation(Builder *builder, int opType, const Value &operand1, const Value &operand2, OperationFlags &operationFlags) const { assert(operand1.valueType() == this); switch (opType) { case ast::ExpressionNode::opEqual: if (operand2.isConstant()) { const ConstantValue &val = operand2.constant(); switch (val.type()) { case ConstantValue::Byte: case ConstantValue::Short: case ConstantValue::Integer: case ConstantValue::Boolean: return Value(ConstantValue::equal(ConstantValue(0), val, operationFlags), mRuntime); case ConstantValue::Float: return Value(ConstantValue::equal(ConstantValue(0.0), val, operationFlags), mRuntime); case ConstantValue::String: return Value(ConstantValue::equal(ConstantValue(""), val, operationFlags), mRuntime); case ConstantValue::Null: return Value(ConstantValue(true), mRuntime); default: break; } break; } return operand2.valueType()->generateOperation(builder, opType, builder->defaultValue(operand2.valueType()), operand2, operationFlags); case ast::ExpressionNode::opNotEqual: if (operand2.isConstant()) { const ConstantValue &val = operand2.constant(); switch (val.type()) { case ConstantValue::Byte: case ConstantValue::Short: case ConstantValue::Integer: case ConstantValue::Boolean: return Value(ConstantValue::notEqual(ConstantValue(0), val, operationFlags), mRuntime); case ConstantValue::Float: return Value(ConstantValue::notEqual(ConstantValue(0.0), val, operationFlags), mRuntime); case ConstantValue::String: return Value(ConstantValue::notEqual(ConstantValue(""), val, operationFlags), mRuntime); case ConstantValue::Null: return Value(ConstantValue(true), mRuntime); default: break; } break; } return operand2.valueType()->generateOperation(builder, opType, builder->defaultValue(operand2.valueType()), operand2, operationFlags); } operationFlags |= OperationFlag::NoSuchOperation; return Value(); }
ScriptContext::ScriptContext() : m_VariableIndex(0) , m_DataIndex(0) { m_Functions.push_back(Function("+",OP_ADD,12,2,scriptAddOperation)); m_Functions.push_back(Function("*",OP_MUL,16,2,scriptMul)); //m_Functions.push_back(Function("/",OP_DIV,16,2)); //m_Functions.push_back(Function("-",OP_SUB,12,2)); //m_Functions.push_back(Function("sin",OP_SIN,17,1)); //m_Functions.push_back(Function("cos",OP_COS,17,1)); m_Functions.push_back(Function("=",OP_ASSIGN,1,1,scriptAssign)); m_Functions.push_back(Function("random",OP_RND,20,2,scriptRandom)); m_Functions.push_back(Function("print",OP_RND,19,1,scriptPrint)); m_Functions.push_back(Function("vector2",OP_NEW_VEC2,20,2,scriptNewVec2)); m_Constants.push_back(ConstantValue("PI",3.14159265359f)); m_Declarations.push_back(TypeDeclaration("int",DT_INT)); m_Declarations.push_back(TypeDeclaration("float",DT_FLOAT)); m_Declarations.push_back(TypeDeclaration("vec2",DT_VEC2)); m_Declarations.push_back(TypeDeclaration("vec3",DT_VEC3)); m_Declarations.push_back(TypeDeclaration("color",DT_COLOR)); }
void TypeAnalyzer::analyze(const BinaryOperator *binary) { /* Be careful: these pointers become kinda invalid after doing unionSet(). */ Type *type = types().getType(binary); Type *leftType = types().getType(binary->left()); Type *rightType = types().getType(binary->right()); const dflow::Value *value = dataflow().getValue(binary->left()); const dflow::Value *leftValue = dataflow().getValue(binary->left()); const dflow::Value *rightValue = dataflow().getValue(binary->right()); switch (binary->operatorKind()) { case BinaryOperator::ADD: if (leftType->isInteger() && rightType->isInteger()) { type->makeInteger(); } if ((leftType->isInteger() && rightType->isPointer()) || (leftType->isPointer() && rightType->isInteger())) { type->makePointer(); } if (type->isInteger()) { leftType->makeInteger(); rightType->makeInteger(); } if (type->isPointer()) { if (leftType->isInteger()) { rightType->makePointer(); } if (rightType->isInteger()) { leftType->makePointer(); } if (leftType->isPointer()) { rightType->makeInteger(); } if (rightType->isPointer()) { leftType->makeInteger(); } if (!leftType->isPointer() && !rightType->isPointer()) { if (leftValue->isMultiplication()) { rightType->makePointer(); } else if (rightValue->isMultiplication()) { leftType->makePointer(); } else if (leftValue->isConstant()) { if (leftValue->constantValue().value() < 4096) { leftType->makeInteger(); } else { leftType->makePointer(); } } else if (rightValue->isConstant()) { if (rightValue->constantValue().value() < 4096) { rightType->makeInteger(); } else { rightType->makePointer(); } } } } if (leftType->isUnsigned() || rightType->isUnsigned()) { type->makeUnsigned(); } if (leftType->isSigned() && rightType->isSigned()) { type->makeSigned(); } if (type->isSigned()) { leftType->makeSigned(); rightType->makeSigned(); } if (type->isUnsigned()) { if (leftType->isSigned()) { rightType->makeUnsigned(); } if (rightType->isSigned()) { rightType->makeUnsigned(); } } if (rightValue->isConstant()) { if (type == leftType) { type->updateFactor(rightValue->constantValue().absoluteValue()); } else { #ifdef NC_STRUCT_RECOVERY if (!value->isStackOffset()) { leftType->addOffset(rightValue->constantValue().signedValue(), type); } #endif } } if (leftValue->isConstant()) { if (type == rightType) { type->updateFactor(leftValue->constantValue().absoluteValue()); } else { #ifdef NC_STRUCT_RECOVERY if (!value->isStackOffset()) { rightType->addOffset(leftValue->constantValue().signedValue(), type); } #endif } } if (leftType->isPointer() && rightValue->isMultiplication()) { type->makePointer(leftType->pointee()); } if (rightType->isPointer() && leftValue->isMultiplication()) { type->makePointer(rightType->pointee()); } break; case BinaryOperator::SUB: if (leftType->isInteger() && rightType->isInteger()) { type->makeInteger(); } if (leftType->isPointer() && rightType->isInteger()) { type->makePointer(); } if (type->isPointer()) { leftType->makePointer(); rightType->makeInteger(); } if (leftType->isUnsigned() || rightType->isUnsigned()) { type->makeUnsigned(); } if (leftType->isSigned() && rightType->isSigned()) { type->makeSigned(); } if (type->isSigned()) { leftType->makeSigned(); rightType->makeSigned(); } if (type->isUnsigned()) { if (leftType->isSigned()) { rightType->makeUnsigned(); } if (rightType->isSigned()) { rightType->makeUnsigned(); } } if (rightValue->isConstant()) { if (type == leftType) { type->updateFactor(rightValue->constantValue().absoluteValue()); } else { #ifdef NC_STRUCT_RECOVERY if (!value->isStackOffset()) { leftType->addOffset(-rightValue->constantValue().signedValue(), type); } #endif } } if (leftType->isPointer() && rightValue->isMultiplication()) { type->makePointer(leftType->pointee()); } break; case BinaryOperator::MUL: type->makeInteger(); leftType->makeInteger(); rightType->makeInteger(); if (leftType->isUnsigned() || rightType->isUnsigned()) { type->makeUnsigned(); } if (leftType->isSigned() && rightType->isSigned()) { type->makeSigned(); } if (type->isSigned()) { leftType->makeSigned(); rightType->makeSigned(); } if (type->isUnsigned()) { if (leftType->isSigned()) { rightType->makeUnsigned(); } if (rightType->isSigned()) { rightType->makeUnsigned(); } } if (rightValue->isConstant()) { type->updateFactor(leftType->factor() * rightValue->constantValue().value()); } if (leftValue->isConstant()) { type->updateFactor(rightType->factor() * leftValue->constantValue().value()); } break; case BinaryOperator::SIGNED_DIV: leftType->makeInteger(); rightType->makeInteger(); type->makeInteger(); leftType->makeSigned(); rightType->makeSigned(); type->makeSigned(); break; case BinaryOperator::UNSIGNED_DIV: type->makeInteger(); leftType->makeInteger(); rightType->makeInteger(); if (leftType->isSigned()) { rightType->makeUnsigned(); } if (rightType->isUnsigned()) { leftType->makeSigned(); } type->makeUnsigned(); break; case BinaryOperator::SIGNED_REM: leftType->makeInteger(); rightType->makeInteger(); type->makeInteger(); leftType->makeSigned(); rightType->makeSigned(); type->makeSigned(); break; case BinaryOperator::UNSIGNED_REM: type->makeInteger(); leftType->makeInteger(); rightType->makeInteger(); if (leftType->isSigned()) { rightType->makeUnsigned(); } if (rightType->isUnsigned()) { leftType->makeSigned(); } type->makeUnsigned(); break; case BinaryOperator::BITWISE_AND: /* FALLTHROUGH */ case BinaryOperator::LOGICAL_AND: /* FALLTHROUGH */ case BinaryOperator::BITWISE_OR: /* FALLTHROUGH */ case BinaryOperator::LOGICAL_OR: /* FALLTHROUGH */ case BinaryOperator::BITWISE_XOR: leftType->makeInteger(); rightType->makeInteger(); type->makeInteger(); leftType->makeUnsigned(); rightType->makeUnsigned(); type->makeUnsigned(); break; case BinaryOperator::SHL: leftType->makeInteger(); rightType->makeInteger(); type->makeInteger(); rightType->makeUnsigned(); if (leftType->isSigned()) { type->makeSigned(); } if (leftType->isUnsigned()) { type->makeUnsigned(); } if (type->isSigned()) { leftType->makeSigned(); } if (type->isUnsigned()) { leftType->makeUnsigned(); } if (rightValue->isConstant()) { type->updateFactor(leftType->factor() * (ConstantValue(1) << rightValue->constantValue().value())); } break; case BinaryOperator::SHR: leftType->makeInteger(); rightType->makeInteger(); type->makeInteger(); leftType->makeUnsigned(); type->makeUnsigned(); break; case BinaryOperator::SAR: leftType->makeInteger(); rightType->makeInteger(); type->makeInteger(); leftType->makeSigned(); type->makeSigned(); break; case BinaryOperator::EQUAL: leftType->unionSet(rightType); break; case BinaryOperator::SIGNED_LESS: /* FALLTHROUGH */ case BinaryOperator::SIGNED_LESS_OR_EQUAL: /* FALLTHROUGH */ case BinaryOperator::SIGNED_GREATER: /* FALLTHROUGH */ case BinaryOperator::SIGNED_GREATER_OR_EQUAL: leftType->makeSigned(); rightType->makeSigned(); leftType->unionSet(rightType); break; case BinaryOperator::UNSIGNED_LESS: /* FALLTHROUGH */ case BinaryOperator::UNSIGNED_LESS_OR_EQUAL: /* FALLTHROUGH */ case BinaryOperator::UNSIGNED_GREATER: /* FALLTHROUGH */ case BinaryOperator::UNSIGNED_GREATER_OR_EQUAL: if (rightType->isSigned()) { leftType->makeUnsigned(); } else if (leftType->isSigned()) { rightType->makeUnsigned(); } else { leftType->makeUnsigned(); rightType->makeUnsigned(); } leftType->unionSet(rightType); break; default: unreachable(); break; } }