예제 #1
0
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);
    }
}
예제 #2
0
파일: Parser.cpp 프로젝트: SOM-st/SOMpp
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);
    }
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
파일: VMMethod.cpp 프로젝트: jdegeete/SOMpp
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() + ")";
}
예제 #6
0
파일: Universe.cpp 프로젝트: jdegeete/SOMpp
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);
}
예제 #7
0
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);
}
예제 #8
0
파일: Universe.cpp 프로젝트: jdegeete/SOMpp
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);
}
예제 #9
0
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;
}
예제 #10
0
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);
}
예제 #11
0
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;
}
예제 #12
0
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);
}
예제 #13
0
파일: Universe.cpp 프로젝트: jdegeete/SOMpp
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;
}
예제 #14
0
파일: Universe.cpp 프로젝트: jdegeete/SOMpp
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;
}
예제 #15
0
파일: Universe.cpp 프로젝트: jdegeete/SOMpp
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;
}
예제 #16
0
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;
}
예제 #17
0
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);
}
예제 #18
0
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;
}