blob: 44e7cc35d5237164ffa4afd0816ce1717a1fc3af [file] [log] [blame]
//===--------- Object.cc - Common objects for vmlets ----------------------===//
//
// The Micro Virtual Machine
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <stdlib.h>
#include "MvmGC.h"
#include "mvm/Method.h"
#include "mvm/Object.h"
#include "mvm/PrintBuffer.h"
#include "mvm/Threads/Key.h"
#include "mvm/Threads/Thread.h"
using namespace mvm;
VirtualTable *NativeString::VT = 0;
VirtualTable *PrintBuffer::VT = 0;
mvm::Key<mvm::Thread>* mvm::Thread::threadKey = 0;
void Object::initialise() {
# define INIT(X) { \
X fake; \
X::VT = ((void**)(void*)(&fake))[0]; }
INIT(NativeString);
INIT(PrintBuffer);
#undef INIT
}
void PrintBuffer::TRACER {
((PrintBuffer *)this)->contents()->MARK_AND_TRACE;
}
PrintBuffer *PrintBuffer::writeObj(const Object *obj) {
#ifdef MULTIPLE_GC
Object *beg = (Object*)mvm::Thread::get()->GC->begOf(obj);
#else
Object *beg = (Object*)Collector::begOf(obj);
#endif
if(beg) {
if(beg == obj) {
obj->print((mvm::PrintBuffer*)this);
} else {
write("<In Object [");
beg->print(this);
write("] -- offset ");
writeS4((intptr_t)obj - (intptr_t)beg);
write(">");
}
} else {
write("<DirectValue: ");
writeS4((intptr_t)obj);
write(">");
}
return this;
}
extern "C" void write_ptr(PrintBuffer* buf, void* obj) {
buf->writePtr(obj);
}
extern "C" void write_int(PrintBuffer* buf, int a) {
buf->writeS4(a);
}
extern "C" void write_str(PrintBuffer* buf, char* a) {
buf->write(a);
}
char *Object::printString(void) const {
PrintBuffer *buf= PrintBuffer::alloc();
buf->writeObj(this);
return buf->contents()->cString();
}
void Object::print(PrintBuffer *buf) const {
buf->write("<Object@");
buf->writePtr((void*)this);
buf->write(">");
}
void NativeString::print(PrintBuffer *buf) const {
NativeString *const self= (NativeString *)this;
buf->write("\"");
for (size_t i= 0; i < strlen(self->cString()); ++i) {
int c= self->cString()[i];
switch (c) {
case '\b': buf->write("\\b"); break;
case '\f': buf->write("\\f"); break;
case '\n': buf->write("\\n"); break;
case '\r': buf->write("\\r"); break;
case '\t': buf->write("\\t"); break;
case '"': buf->write("\\\""); break;
default: {
char esc[32];
if (c < 32)
sprintf(esc, "\\x%02x", c);
else
sprintf(esc, "%c", c);
buf->write(esc);
}
}
}
buf->write("\"");
}