void Interpreter::doSuperSend(long bytecodeIndex) { VMSymbol* signature = static_cast<VMSymbol*>(method->GetConstant(bytecodeIndex)); VMFrame* ctxt = GetFrame()->GetOuterContext(); VMMethod* realMethod = ctxt->GetMethod(); VMClass* holder = realMethod->GetHolder(); VMClass* super = holder->GetSuperClass(); VMInvokable* invokable = static_cast<VMInvokable*>(super->LookupInvokable(signature)); if (invokable != nullptr) (*invokable)(GetFrame()); else { long numOfArgs = Signature::GetNumberOfArguments(signature); vm_oop_t receiver = GetFrame()->GetStackElement(numOfArgs - 1); VMArray* argumentsArray = GetUniverse()->NewArray(numOfArgs); for (long i = numOfArgs - 1; i >= 0; --i) { vm_oop_t o = GetFrame()->Pop(); argumentsArray->SetIndexableField(i, o); } vm_oop_t arguments[] = {signature, argumentsArray}; AS_OBJ(receiver)->Send(doesNotUnderstand, arguments, 2); } }
void Parser::superclass(ClassGenerationContext *cgenc) { VMSymbol* superName; if (sym == Identifier) { superName = GetUniverse()->SymbolFor(text); accept(Identifier); } else { superName = GetUniverse()->SymbolFor("Object"); } cgenc->SetSuperName(superName); // Load the super class, if it is not nil (break the dependency cycle) if (superName != GetUniverse()->SymbolFor("nil")) { VMClass* superClass = GetUniverse()->LoadClass(superName); cgenc->SetInstanceFieldsOfSuper(superClass->GetInstanceFields()); cgenc->SetClassFieldsOfSuper(superClass->GetClass()->GetInstanceFields()); } else { // we hardcode here the field names for Class // since Object class superclass = Class // We avoid here any kind of dynamic solution to avoid further complexity. // However, that makes it static, it is going to make it harder to // change the definition of Class and Object vector<StdString> fieldNamesOfClass{ "class", "superClass", "name", "instanceFields", "instanceInvokables" }; VMArray* fieldNames = GetUniverse()->NewArrayFromStrings(fieldNamesOfClass); cgenc->SetClassFieldsOfSuper(fieldNames); } }
VMContext::~VMContext(){ VMClass* thrdcls = mVm->getLoader(NULL)->find(this, "java/lang/Thread"); FieldData* eetop = mThread->getObjField(thrdcls->findFieldIndex("eetop")); CGE::Thread* thrd = (CGE::Thread*)eetop->l; delete thrd; delete mSelf; delete [] mStack; }
VMClass* VMLoader::load(VMContext* ctx, const std::string& name, CGE::Reader& rdr){ VMClass* cls = new VMClass(ctx, this, rdr); cls->initClass(ctx, true); if (ctx->getException() != NULL){ delete cls; return NULL; } mClasses[name] = cls; return cls; }
StdString VMMethod::AsDebugString() const { VMClass* holder = GetHolder(); StdString holder_str; if (holder == load_ptr(nilObject)) { holder_str = "nil"; } else { holder_str = holder->GetName()->GetStdString(); } return "Method(" + holder_str + ">>#" + GetSignature()->GetStdString() + ")"; }
void Universe::LoadSystemClass(VMClass* systemClass) { VMClass* result = LoadClassBasic(systemClass->GetName(), systemClass); StdString s = systemClass->GetName()->GetStdString(); if (!result) { cout << "Can't load system class: " << s << endl; Universe::Quit(ERR_FAIL); } if (result->HasPrimitives() || result->GetClass()->HasPrimitives()) result->LoadPrimitives(classPath); }
void AbstractVMObject::Send(Interpreter* interp, StdString selectorString, vm_oop_t* arguments, long argc) { VMFrame* frame = interp->GetFrame(); VMSymbol* selector = GetUniverse()->SymbolFor(selectorString); frame->Push(this); for (long i = 0; i < argc; ++i) { frame->Push(arguments[i]); } VMClass* cl = GetClass(); VMInvokable* invokable = cl->LookupInvokable(selector); invokable->Invoke(interp, frame); }
void Universe::InitializeSystemClass(VMClass* systemClass, VMClass* superClass, const char* name) { StdString s_name(name); if (superClass != nullptr) { systemClass->SetSuperClass(superClass); VMClass* sysClassClass = systemClass->GetClass(); VMClass* superClassClass = superClass->GetClass(); sysClassClass->SetSuperClass(superClassClass); } else { VMClass* sysClassClass = systemClass->GetClass(); sysClassClass->SetSuperClass(load_ptr(classClass)); } VMClass* sysClassClass = systemClass->GetClass(); systemClass->SetInstanceFields(NewArray(0)); sysClassClass->SetInstanceFields(NewArray(0)); systemClass->SetInstanceInvokables(NewArray(0)); sysClassClass->SetInstanceInvokables(NewArray(0)); systemClass->SetName(SymbolFor(s_name)); ostringstream Str; Str << s_name << " class"; StdString classClassName(Str.str()); sysClassClass->SetName(SymbolFor(classClassName)); SetGlobal(systemClass->GetName(), systemClass); }
VMClass* BootstrapLoader::find(VMContext* ctx, const std::string& name, bool initClass){ TR_USE(Java_Loader); std::map<std::string,VMClass*>::iterator iter = mUninitializedClasses.find(name); if (iter != mUninitializedClasses.end()){ VMClass* cls = iter->second; mUninitializedClasses.erase(iter); mClasses[name] = cls; //delayed class init unsigned idx = cls->findMethodIndex("<clinit>", "()V"); VMMethod* mthd = cls->getMethod(idx); if (mthd){ TR_INFO("Delayed execution of class init method"); mthd->execute(ctx, -1); } return cls; } VMClass* entry = mClasses[name]; if (entry == 0){ //array functions if (name[0] == '['){ entry = new VMArrayClass(this, name); mClasses[name] = entry; return entry; } else if (name.size() == 1){ //primitive types return getPrimitiveClass(ctx, name); } //Java::ClassFile* clfile = new Java::ClassFile(); CGE::Reader* rdr = filenameToReader(name); if (!rdr) return NULL; entry = new VMClass(ctx, this, *rdr); delete rdr; if (ctx->getException() != NULL){ delete entry; return NULL; } if (!initClass) mUninitializedClasses[name] = entry; else mClasses[name] = entry; entry->initClass(ctx, initClass); } return entry; }
void MSCorlib::loadStringClass(N3* vm) { VMClass* type = (VMClass*)vm->coreAssembly->loadTypeFromName( vm->asciizToUTF8("String"), vm->asciizToUTF8("System"), false, false, false, true); MSCorlib::pString = type; MSCorlib::pObject->resolveType(true, false, NULL); MSCorlib::pObject->resolveVT(); type->resolveType(true, false, NULL); type->resolveVT(); uint64 size = mvm::MvmModule::getTypeSize(type->virtualType->getContainedType(0)) + sizeof(const UTF8*) + sizeof(llvm::GlobalVariable*); type->virtualInstance = (VMObject*)gc::operator new(size, VMObject::getN3VirtualTable(type->virtualInstance)); VMObject::initialise(type->virtualInstance, type); }
static void mapInitialThread(N3* vm) { VMClass* cl = (VMClass*)vm->coreAssembly->loadTypeFromName( vm->asciizToUTF8("Thread"), vm->asciizToUTF8("System.Threading"), true, true, true, true); declare_gcroot(VMObject*, appThread) = cl->doNew(); std::vector<VMCommonClass*> args; args.push_back(MSCorlib::pVoid); args.push_back(cl); args.push_back(MSCorlib::pIntPtr); VMMethod* ctor = cl->lookupMethod(vm->asciizToUTF8(".ctor"), args, false, false); VMThread* myth = VMThread::get(); ctor->compileToNative()->invokeVoid(appThread, myth); myth->ooo_appThread = appThread; }
void Interpreter::doSend(long bytecodeIndex) { VMSymbol* signature = static_cast<VMSymbol*>(method->GetConstant(bytecodeIndex)); int numOfArgs = Signature::GetNumberOfArguments(signature); vm_oop_t receiver = GetFrame()->GetStackElement(numOfArgs-1); assert(Universe::IsValidObject(receiver)); assert(dynamic_cast<VMClass*>(CLASS_OF(receiver)) != nullptr); // make sure it is really a class VMClass* receiverClass = CLASS_OF(receiver); assert(Universe::IsValidObject(receiverClass)); #ifdef LOG_RECEIVER_TYPES GetUniverse()->receiverTypes[receiverClass->GetName()->GetStdString()]++; #endif send(signature, receiverClass); }
VMClass* Universe::LoadClassBasic(VMSymbol* name, VMClass* systemClass) { StdString s_name = name->GetStdString(); //cout << s_name.c_str() << endl; VMClass* result; for (vector<StdString>::iterator i = classPath.begin(); i != classPath.end(); ++i) { SourcecodeCompiler compiler; result = compiler.CompileClass(*i, name->GetStdString(), systemClass); if (result) { if (dumpBytecodes) { Disassembler::Dump(result->GetClass()); Disassembler::Dump(result); } return result; } } return nullptr; }
VMClass* Universe::LoadClass(VMSymbol* name) { VMClass* result = static_cast<VMClass*>(GetGlobal(name)); if (result != nullptr) return result; result = LoadClassBasic(name, nullptr); if (!result) { // we fail silently, it is not fatal that loading a class failed return (VMClass*) nilObject; } if (result->HasPrimitives() || result->GetClass()->HasPrimitives()) result->LoadPrimitives(classPath); SetGlobal(name, result); return result; }
VMClass* Universe::GetBlockClassWithArgs(long numberOfArguments) { map<long, GCClass*>::iterator it = blockClassesByNoOfArgs.find(numberOfArguments); if (it != blockClassesByNoOfArgs.end()) return load_ptr(it->second); Assert(numberOfArguments < 10); ostringstream Str; Str << "Block" << numberOfArguments; VMSymbol* name = SymbolFor(Str.str()); VMClass* result = LoadClassBasic(name, nullptr); result->AddInstancePrimitive(new (GetHeap<HEAP_CLS>()) VMEvaluationPrimitive(numberOfArguments) ); SetGlobal(name, result); # warning is _store_ptr sufficient here? blockClassesByNoOfArgs[numberOfArguments] = _store_ptr(result); return result; }
VMClass* SourcecodeCompiler::CompileClass( const StdString& path, const StdString& file, VMClass* systemClass ) { VMClass* result = systemClass; StdString fname = path + fileSeparator + file + ".som"; ifstream* fp = new ifstream(); fp->open(fname.c_str(), std::ios_base::in); if (!fp->is_open()) { return nullptr; } if (parser != nullptr) delete(parser); parser = new Parser(*fp); result = compile(systemClass); VMSymbol* cname = result->GetName(); StdString cnameC = cname->GetStdString(); if (file != cnameC) { ostringstream Str; Str << "Filename: " << file << " does not match class name " << cnameC; showCompilationError(file, Str.str().c_str()); return nullptr; } delete(parser); parser = nullptr; delete(fp); #ifdef COMPILER_DEBUG Universe::ErrorPrint("Compilation finished\n"); #endif return result; }
void CloneObjectsTest::testCloneClass() { VMClass* orig = GetUniverse()->NewClass(load_ptr(integerClass)); orig->SetName(GetUniverse()->NewSymbol("MyClass")); orig->SetSuperClass(load_ptr(doubleClass)); orig->SetInstanceFields(GetUniverse()->NewArray(2)); orig->SetInstanceInvokables(GetUniverse()->NewArray(4)); VMClass* clone = orig->Clone(); CPPUNIT_ASSERT((intptr_t)orig != (intptr_t)clone); CPPUNIT_ASSERT_EQUAL_MESSAGE("class differs!!", orig->clazz, clone->clazz); CPPUNIT_ASSERT_EQUAL_MESSAGE("objectSize differs!!", orig->objectSize, clone->objectSize); CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfFields differs!!", orig->numberOfFields, clone->numberOfFields); CPPUNIT_ASSERT_EQUAL_MESSAGE("superClass differs!!", orig->superClass, clone->superClass); CPPUNIT_ASSERT_EQUAL_MESSAGE("name differs!!", orig->name, clone->name); CPPUNIT_ASSERT_EQUAL_MESSAGE("instanceFields differs!!", orig->instanceFields, clone->instanceFields); CPPUNIT_ASSERT_EQUAL_MESSAGE("instanceInvokables differs!!", orig->instanceInvokables, clone->instanceInvokables); }
VMClass* BootstrapLoader::getPrimitiveClass(VMContext* ctx, std::string name){ VMClass* entry = mClasses[name]; if (entry == 0){ entry = new VMClass(this); entry->setName(name); mClasses[name] = entry; //entry->print(std::cout); //entry->initFields(ctx); VMClass* cls = find(ctx, "java/lang/Class"); VMMethod* clsmthd = cls->getMethod(cls->findMethodIndex("<init>", "()V")); entry->init(ctx, cls); ctx->push((VMObject*)cls); clsmthd->execute(ctx, -1); } return entry; }