#include "j3/j3codegenvar.h"
#include "j3/j3codegen.h"
#include "j3/j3class.h"
#include "j3/j3.h"
#include "j3/j3classloader.h"

#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Function.h"

using namespace j3;

void J3CodeGenVar::killUnused(llvm::AllocaInst** stack, bool isObj) {
	llvm::Type* i8ptr = codeGen->builder.getInt8Ty()->getPointerTo();
	llvm::Value* meta = codeGen->builder.CreateBitCast(codeGen->nullValue, i8ptr);
	llvm::Type* i8ptrptr = i8ptr->getPointerTo();

	for(uint32_t i=0; i<maxStack; i++) {
		llvm::AllocaInst* cur = stack[i];

    unsigned uses = cur->getNumUses();
    if (!uses) {
      cur->eraseFromParent();
    } else if (uses == 1 && llvm::dyn_cast<llvm::StoreInst>(*(cur->use_begin()))) {
			llvm::dyn_cast<llvm::StoreInst>(*(cur->use_begin()))->eraseFromParent();
      cur->eraseFromParent();
    } else if(isObj) {
			if(codeGen->needGC()) {
				codeGen->builder.SetInsertPoint(cur->getNextNode());
				codeGen->builder.CreateCall2(codeGen->gcRoot, codeGen->builder.CreateBitCast(refStack[i], i8ptrptr), meta);
			}
			//codeGen->builder.CreateStore(codeGen->nullValue, cur);
			//
		}
	}
}

void J3CodeGenVar::killUnused() {
	killUnused(intStack, 0);
	killUnused(longStack, 0);
	killUnused(floatStack, 0);
	killUnused(doubleStack, 0);
	killUnused(refStack, 1);
}

uint32_t J3CodeGenVar::metaStackSize() {
	return topStack*sizeof(llvm::Type*);
}

void J3CodeGenVar::init(J3CodeGen* _codeGen, uint32_t max) {
	codeGen = _codeGen;
	void* space = codeGen->allocator->allocate(max*5*sizeof(llvm::AllocaInst*) + max*sizeof(llvm::Type*));
	maxStack = max;
	intStack = (llvm::AllocaInst**)space;
	longStack = intStack + max;
	floatStack = longStack + max;
	doubleStack = floatStack + max;
	refStack = doubleStack + max;
	metaStack = (llvm::Type**)(refStack + max);
	topStack = 0;
	
	for(uint32_t i=0; i<max; i++) {
		intStack[i] = codeGen->builder.CreateAlloca(codeGen->builder.getInt32Ty());
		longStack[i] = codeGen->builder.CreateAlloca(codeGen->builder.getInt64Ty());
		floatStack[i] = codeGen->builder.CreateAlloca(codeGen->builder.getFloatTy());
		doubleStack[i] = codeGen->builder.CreateAlloca(codeGen->builder.getDoubleTy());
		refStack[i] = codeGen->builder.CreateAlloca(codeGen->vm->typeJ3ObjectPtr);
	}
}

void J3CodeGenVar::dump() {
	for(uint32_t i=0; i<topStack; i++) {
		fprintf(stderr, "              [%u]: ", i);
		stackOf(metaStack[i])[i]->dump();
		//fprintf(stderr, "\n");
	}
}

void J3CodeGenVar::drop(uint32_t n) {
	topStack -= n;
}

llvm::AllocaInst** J3CodeGenVar::stackOf(llvm::Type* t) {
	if(!t)
		J3::internalError("unable to find the type of a local/stack");

	if(t->isIntegerTy(64)) {
		return longStack;
	} else if(t->isIntegerTy()) {
		return intStack;
	} else if(t->isFloatTy()) {
		return floatStack;
	} else if(t->isDoubleTy()) {
		return doubleStack;
	} else if(t->isPointerTy()) {
		return refStack;
	} 
		
	J3::internalError("should not happen");
}

void J3CodeGenVar::setAt(llvm::Value* value, uint32_t idx) {
	llvm::Type*   t = value->getType();
	codeGen->builder.CreateStore(value, stackOf(t)[idx]);
}

llvm::Value* J3CodeGenVar::at(uint32_t idx, llvm::Type* t) {
	return codeGen->builder.CreateLoad(stackOf(t)[idx]);
}

void J3CodeGenVar::push(llvm::Value* value) {
	//	fprintf(stderr, "push: ");
	//	value->dump();
	//	fprintf(stderr, "\n");
	if(topStack >= maxStack)
		J3::classFormatError(codeGen->cl, "too many push in... ");

	metaStack[topStack] = value->getType();
	setAt(value, topStack);
	topStack++;
}

llvm::Value* J3CodeGenVar::pop() {
	if(!topStack)
		J3::classFormatError(codeGen->cl, "too many pop in... ");

	--topStack;
	return at(topStack, metaStack[topStack]);
}

llvm::Value* J3CodeGenVar::top(uint32_t idx) {
	if(topStack <= idx)
		J3::classFormatError(codeGen->cl, "too large top in... ");

	uint32_t n = topStack - idx - 1;
	return at(n, metaStack[n]);
}
