Beispiel #1
0
void MultiVarAssi::codeGen(AstContext &astContext) {
	vector<AValue> vars;
	for (unsigned i = 0; i < leftExprList.size(); i++) {
		LeftValueExpr *leftExpr = leftExprList[i];
		if (leftExpr == NULL) {
			vars.push_back(AValue());
		} else {
			AValue var = leftExpr->lvalueGen(astContext);
			vars.push_back(var);
		}
	}

	vector<AValue> values = funcInvoke->multiCodeGen(astContext);

	if (values.size() < vars.size()) {
		errorMsg = "too few values returned from function '"
				+ funcInvoke->funcName + "'";
		throwError(funcInvoke);
	}
	for (unsigned i = 0; i < vars.size(); i++) {
		if (vars[i].llvmValue == NULL) {
			continue;
		}
		AValue v = values[i];
		if (!v.castTo(vars[i].clazz)) {
			throwError(this);
		}
		builder.CreateStore(v.llvmValue, vars[i].llvmValue);
	}
}
Beispiel #2
0
AValue InstanceOf::gen(AstContext &astContext) {
	AValue v = expr->codeGen(astContext);
	ClassInfo *destClass = typeDecl->getClassInfo();
	if (v.clazz == nilClass
			&& (destClass->isObjectType() || destClass->isArrayType())) {
		return AValue(bool_true, boolClass);
	} else if (v.clazz->isSubClassOf(destClass)) {
		return AValue(bool_true, boolClass);
	} else if (destClass->isObjectType() && v.isObject()) {
		Value *res = builder.CreateCall2(sysInstanceOf, v.llvmValue,
				destClass->info);
		res = builder.CreateTrunc(res, boolType);
		return AValue(res, boolClass);
	} else {
		return AValue(bool_false, boolClass);
	}
}
Beispiel #3
0
AValue ThisExpr::gen(AstContext &astContext) {
	if (astContext.classContext == NULL) {
		errorMsg = "invalid use of 'this' outside of a class method";
		throwError(this);
	}
	if (astContext.classContext->thisObject == NULL) {
		errorMsg = "invalid use of 'this' before current object create";
		throwError(this);
	}
	return AValue(astContext.classContext->thisObject,
			astContext.classContext->currentClass);
}
Beispiel #4
0
AValue String::gen(AstContext &astContext) {
	vector<Constant*> unicodes;
	for (unsigned i = 0; i < data->size(); i++) {
		int32_t unicode = data->at(i);
		unicodes.push_back(ConstantInt::get(int32Type, unicode));
	}
	if (unicodes.size() > 0) {
		ArrayType *arrayType = ArrayType::get(int32Type, unicodes.size());
		GlobalVariable *array = new GlobalVariable(module, arrayType, true,
				GlobalValue::PrivateLinkage,
				ConstantArray::get(arrayType, ArrayRef<Constant*>(unicodes)));
		Value *str = builder.CreateCall3(sysArrayAlloca,
				builder.getInt64(unicodes.size()),
				builder.getInt8(dataLayout->getTypeStoreSize(int32Type)),
				builder.CreateBitCast(array, ptrType));
		return AValue(str, charClass->getArrayClass());
	} else {
		Value *str = builder.CreateCall3(sysArrayAlloca, int64_0,
				builder.getInt8(dataLayout->getTypeStoreSize(int32Type)),
				ptr_null);
		return AValue(str, charClass->getArrayClass());
	}
}
Beispiel #5
0
void VarDef::globalGen() {
	ClassInfo *classInfo = typeDecl->getClassInfo();
	Constant *initial = classInfo->getInitial();
	for (unsigned i = 0; i < varInitList.size(); i++) {
		VarInit *varInit = varInitList[i];
		Value *llvmVar = new GlobalVariable(module, classInfo->llvmType, false,
				GlobalValue::ExternalLinkage, initial);
		AstContext astContext;
		if (varInit->expr != NULL) {
			varInit->expr->expectedType = classInfo;
			AValue v = varInit->expr->codeGen(astContext);
			builder.CreateStore(v.llvmValue, llvmVar);
		}
		globalContext.addVar(varInit->varName, AValue(llvmVar, classInfo));
	}
}
Beispiel #6
0
void VarDef::codeGen(AstContext &astContext) {
	ClassInfo *classInfo = typeDecl->getClassInfo();
	for (unsigned i = 0; i < varInitList.size(); i++) {
		VarInit *varInit = varInitList[i];
		Value *value = NULL;
		if (varInit->expr != NULL) {
			varInit->expr->expectedType = classInfo;
			AValue v = varInit->expr->codeGen(astContext);
			value = v.llvmValue;
		} else {
			value = classInfo->getInitial();
		}
		Value *var = createAlloca(classInfo->llvmType, astContext.allocBB);
		if (!astContext.addVar(varInit->varName, AValue(var, classInfo))) {
			throwError(varInit);
		}
		builder.CreateStore(value, var);
	}
}
Beispiel #7
0
AValue SuperExpr::gen(AstContext &astContext) {
	if (astContext.classContext == NULL) {
		errorMsg = "invalid use of 'super' outside of a constructor";
		throwError(this);
	}
	ClassInfo *currentClass = astContext.classContext->currentClass;
	if (astContext.classContext->superObject == NULL) {
		if (currentClass->superClassInfo == NULL) {
			errorMsg = "class '" + currentClass->name + "' has no super class";
			throwError(this);
		} else if (astContext.classContext->thisObject == NULL) {
			errorMsg = "invalid use of 'super' before super object create";
			throwError(this);
		} else {
			errorMsg = "invalid use of 'super' outside of a constructor";
			throwError(this);
		}
	}
	return AValue(astContext.classContext->superObject,
			astContext.classContext->currentClass->superClassInfo);
}
Beispiel #8
0
AValue Nil::gen(AstContext &astContext) {
	return AValue(ptr_null, nilClass);
}
Beispiel #9
0
AValue Bool::gen(AstContext &astContext) {
	return AValue(builder.getInt1(value), boolClass);
}
Beispiel #10
0
AValue Double::gen(AstContext &astContext) {
	return AValue(ConstantFP::get(doubleType, value), doubleClass);
}
Beispiel #11
0
AValue Char::gen(AstContext &astContext) {
	return AValue(ConstantInt::getSigned(int32Type, value), charClass);
}
Beispiel #12
0
AValue Long::gen(AstContext &astContext) {
	return AValue(ConstantInt::getSigned(int64Type, value), longClass);
}
Beispiel #13
0
static void dumpeit(void *p_cb_data, dvbpsi_eit_t *p_new_eit)
{
	(void)p_cb_data;

	const dvbpsi_eit_event_t *p_event = p_new_eit->p_first_event;
	while (p_event) {
		printf("Event: TS ID %u Network ID %u Event ID %u starttime %s duration %u\n", p_new_eit->i_ts_id, p_new_eit->i_network_id, p_event->i_event_id, AValue(p_event->i_start_time).ToString("016x").str(), p_event->i_duration);

		DumpDescriptors("Event", p_event->p_first_descriptor);

		p_event = p_event->p_next;
	}
}
Beispiel #14
0
AValue BinaryOpExpr::gen(AstContext &astContext) {
	AValue lv = leftExpr->codeGen(astContext);
	AValue rv = rightExpr->codeGen(astContext);
	AValue res;
	if (op == '%') {
		if ((lv.isLong() || lv.isChar()) && (rv.isLong() || rv.isChar())) {
			if (lv.isLong()) {
				rv.castTo(longClass);
			} else {
				lv.castTo(rv.clazz);
			}
			res = AValue(builder.CreateSRem(lv.llvmValue, rv.llvmValue),lv.clazz);
		}
	} else if (lv.isBool() && rv.isBool()) {
		switch (op) {
		case EQUAL:
			res = AValue(builder.CreateICmpEQ(lv.llvmValue, rv.llvmValue),
					boolClass);
			break;
		case NEQUAL:
			res = AValue(builder.CreateICmpNE(lv.llvmValue, rv.llvmValue),
					boolClass);
			break;
		}
	} else if ((lv.isLong() || lv.isDouble() || lv.isChar())
			&& (rv.isLong() || rv.isDouble() || rv.isChar())) {
		if (lv.isDouble() || rv.isDouble()) {
			if (!lv.castTo(doubleClass)) {
				throwError(leftExpr);
			}
			if (!rv.castTo(doubleClass)) {
				throwError(rightExpr);
			}
		} else if (lv.isLong() || rv.isLong()) {
			if (!lv.castTo(longClass)) {
				throwError(leftExpr);
			}
			if (!rv.castTo(longClass)) {
				throwError(rightExpr);
			}
		}
		if (lv.isDouble()) {
			switch (op) {
			case '+':
				res = AValue(builder.CreateFAdd(lv.llvmValue, rv.llvmValue),
						doubleClass);
				break;
			case '-':
				res = AValue(builder.CreateFSub(lv.llvmValue, rv.llvmValue),
						doubleClass);
				break;
			case '*':
				res = AValue(builder.CreateFMul(lv.llvmValue, rv.llvmValue),
						doubleClass);
				break;
			case '/':
				res = AValue(builder.CreateFDiv(lv.llvmValue, rv.llvmValue),
						doubleClass);
				break;
			case EQUAL:
				res = AValue(builder.CreateFCmpOEQ(lv.llvmValue, rv.llvmValue),
						boolClass);
				break;
			case NEQUAL:
				res = AValue(builder.CreateFCmpONE(lv.llvmValue, rv.llvmValue),
						boolClass);
				break;
			case '<':
				res = AValue(builder.CreateFCmpOLT(lv.llvmValue, rv.llvmValue),
						boolClass);
				break;
			case '>':
				res = AValue(builder.CreateFCmpOGT(lv.llvmValue, rv.llvmValue),
						boolClass);
				break;
			case LE:
				res = AValue(builder.CreateFCmpOLE(lv.llvmValue, rv.llvmValue),
						boolClass);
				break;
			case GE:
				res = AValue(builder.CreateFCmpOGE(lv.llvmValue, rv.llvmValue),
						boolClass);
				break;
			}
		} else {
			switch (op) {
			case '+':
				res = AValue(builder.CreateAdd(lv.llvmValue, rv.llvmValue),
						lv.clazz);
				break;
			case '-':
				res = AValue(builder.CreateSub(lv.llvmValue, rv.llvmValue),
						lv.clazz);
				break;
			case '*':
				res = AValue(builder.CreateMul(lv.llvmValue, rv.llvmValue),
						lv.clazz);
				break;
			case '/':
				res = AValue(builder.CreateSDiv(lv.llvmValue, rv.llvmValue),
						lv.clazz);
				break;
			case EQUAL:
				res = AValue(builder.CreateICmpEQ(lv.llvmValue, rv.llvmValue),
						boolClass);
				break;
			case NEQUAL:
				res = AValue(builder.CreateICmpNE(lv.llvmValue, rv.llvmValue),
						boolClass);
				break;
			case '<':
				res = AValue(builder.CreateICmpSLT(lv.llvmValue, rv.llvmValue),
						boolClass);
				break;
			case '>':
				res = AValue(builder.CreateICmpSGT(lv.llvmValue, rv.llvmValue),
						boolClass);
				break;
			case LE:
				res = AValue(builder.CreateICmpSLE(lv.llvmValue, rv.llvmValue),
						boolClass);
				break;
			case GE:
				res = AValue(builder.CreateICmpSGE(lv.llvmValue, rv.llvmValue),
						boolClass);
				break;
			}
		}
	} else if ((lv.isObject() || lv.isArray())
			&& (rv.isObject() || rv.isArray())) {
		if (op == EQUAL) {
			res = AValue(builder.CreateICmpEQ(lv.llvmValue, rv.llvmValue),
					boolClass);
		} else if (op == NEQUAL) {
			res = AValue(builder.CreateICmpNE(lv.llvmValue, rv.llvmValue),
					boolClass);
		}
	}
	if (res.llvmValue == NULL) {
		errorMsg = "invalid operands to binary expression (" + lv.clazz->name
				+ " " + getOperatorName(op) + " " + rv.clazz->name + ")";
		throwError(this);
	}

	return res;
}