blob: 3719360f4583a0bbee3262e910945c3169258dfd [file] [log] [blame]
//===------------- JavaTypes.cpp - Java primitives ------------------------===//
//
// JnJVM
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <vector>
#include "mvm/JIT.h"
#include "JavaAccess.h"
#include "JavaArray.h"
#include "JavaClass.h"
#include "JavaConstantPool.h"
#include "JavaJIT.h"
#include "JavaThread.h"
#include "JavaTypes.h"
#include "JavaUpcalls.h"
#include "Jnjvm.h"
using namespace jnjvm;
static void typeError(const UTF8* name, short int l) {
if (l != 0) {
JavaThread::get()->isolate->
unknownError("wrong type %d in %s", l, name->printString());
} else {
JavaThread::get()->isolate->
unknownError("wrong type %s", name->printString());
}
}
static bool analyseIntern(const UTF8* name, uint32 pos, uint32 meth,
uint32& ret) {
short int cur = name->elements[pos];
switch (cur) {
case I_PARD :
ret = pos + 1;
return true;
case I_BOOL :
ret = pos + 1;
return false;
case I_BYTE :
ret = pos + 1;
return false;
case I_CHAR :
ret = pos + 1;
return false;
case I_SHORT :
ret = pos + 1;
return false;
case I_INT :
ret = pos + 1;
return false;
case I_FLOAT :
ret = pos + 1;
return false;
case I_DOUBLE :
ret = pos + 1;
return false;
case I_LONG :
ret = pos + 1;
return false;
case I_VOID :
ret = pos + 1;
return false;
case I_TAB :
if (meth == 1) {
pos++;
} else {
while (name->elements[++pos] == I_TAB) {}
analyseIntern(name, pos, 1, pos);
}
ret = pos;
return false;
case I_REF :
if (meth != 2) {
while (name->elements[++pos] != I_END_REF) {}
}
ret = pos + 1;
return false;
default :
typeError(name, cur);
}
return false;
}
void PrimitiveTypedef::tPrintBuf(mvm::PrintBuffer* buf) const {
prim->name->print(buf);
}
void ArrayTypedef::tPrintBuf(mvm::PrintBuffer* buf) const {
CommonClass::printClassName(keyName, buf);
}
void ObjectTypedef::tPrintBuf(mvm::PrintBuffer* buf) const {
CommonClass::printClassName(pseudoAssocClassName, buf);
}
const char* Typedef::printString() const {
mvm::PrintBuffer *buf= mvm::PrintBuffer::alloc();
buf->write("Type<");
tPrintBuf(buf);
buf->write(">");
return buf->contents()->cString();
}
UserCommonClass* ArrayTypedef::assocClass(JnjvmClassLoader* loader) const {
return loader->constructArray(keyName);
}
UserCommonClass* ObjectTypedef::assocClass(JnjvmClassLoader* loader) const {
return loader->loadName(pseudoAssocClassName, false, true);
}
void Typedef::humanPrintArgs(const std::vector<Typedef*>* args,
mvm::PrintBuffer* buf) {
buf->write("(");
for (uint32 i = 0; i < args->size(); i++) {
args->at(i)->tPrintBuf(buf);
if (i != args->size() - 1) {
buf->write(", ");
}
}
buf->write(")");
}
const char* Signdef::printString() const {
mvm::PrintBuffer *buf= mvm::PrintBuffer::alloc();
buf->write("Signature<");
ret->tPrintBuf(buf);
buf->write("...");
Typedef::humanPrintArgs(&args, buf);
buf->write(">");
return buf->contents()->cString();
}
void Signdef::printWithSign(CommonClass* cl, const UTF8* name,
mvm::PrintBuffer* buf) {
ret->tPrintBuf(buf);
buf->write(" ");
CommonClass::printClassName(cl->name, buf);
buf->write("::");
name->print(buf);
Typedef::humanPrintArgs(&args, buf);
}
Signdef::Signdef(const UTF8* name, JnjvmClassLoader* loader) {
Signdef* res = this;
std::vector<Typedef*> buf;
uint32 len = (uint32)name->size;
uint32 pos = 1;
uint32 pred = 0;
while (pos < len) {
pred = pos;
bool end = analyseIntern(name, pos, 0, pos);
if (end) break;
else {
buf.push_back(loader->constructType(name->extract(loader->hashUTF8, pred, pos)));
}
}
if (pos == len) {
typeError(name, 0);
}
analyseIntern(name, pos, 0, pred);
if (pred != len) {
typeError(name, 0);
}
res->args = buf;
res->ret = loader->constructType(name->extract(loader->hashUTF8, pos, pred));
res->initialLoader = loader;
res->keyName = name;
res->_virtualCallBuf = 0;
res->_staticCallBuf = 0;
res->_virtualCallAP = 0;
res->_staticCallAP = 0;
res->JInfo = 0;
}
ObjectTypedef::ObjectTypedef(const UTF8* name, UTF8Map* map) {
keyName = name;
pseudoAssocClassName = name->extract(map, 1, name->size - 1);
}
intptr_t Signdef::staticCallBuf() {
if (!_staticCallBuf) {
LLVMSignatureInfo* LSI = initialLoader->getModule()->getSignatureInfo(this);
LSI->getStaticBuf();
}
return _staticCallBuf;
}
intptr_t Signdef::virtualCallBuf() {
if (!_virtualCallBuf) {
LLVMSignatureInfo* LSI = initialLoader->getModule()->getSignatureInfo(this);
LSI->getVirtualBuf();
}
return _virtualCallBuf;
}
intptr_t Signdef::staticCallAP() {
if (!_staticCallAP) {
LLVMSignatureInfo* LSI = initialLoader->getModule()->getSignatureInfo(this);
LSI->getStaticAP();
}
return _staticCallAP;
}
intptr_t Signdef::virtualCallAP() {
if (!_virtualCallAP) {
LLVMSignatureInfo* LSI = initialLoader->getModule()->getSignatureInfo(this);
LSI->getVirtualAP();
}
return _virtualCallAP;
}