void InterpretTest::gcTest() { ConstantPool * pool = new ConstantPool(); Class * cls = initClass("GCTest", pool); const char code[] = { PUSH, 0x00, 0x00, STORE_LOCAL, 0x00, PUSH, 0x01, 0x00, //label1 LOAD_LOCAL, 0x00, SUB, IF_GE, 0x0D,//if(i < 1000) PUSH, 0x01, 0x00, NEW_ARRAY, STORE_LOCAL, 0x01, LOAD_LOCAL, 0x00, INC, STORE_LOCAL, 0x00, JMP, -21, RET_VOID }; Method * m = initMethod("gcTest", code, sizeof(code), 0, 2, 0); ClassLoader cl(""); Interpret instance(&cl); IntConst i; i.value = 0; pool->addItem(&i, INT_CONST);//0 i.value = 1000; pool->addItem(&i, INT_CONST);//1 cls->addMethod(m); cl.addClass(cls); instance.run(cls->getName().c_str(), m->getName().c_str()); }
void GenerateServerMethods::generate_CPP_USER(const std::string &destdir, const std::string &name) { const std::string h_name = theClass.getBaseName() + "_ulxr_server.h"; std::string cpp_name = destdir + theClass.getBaseName() + "_ulxr_server_user.cpp"; struct stat statbuf; if (stat(cpp_name.c_str(), &statbuf) >= 0) { std::cout << "User file already exists: " << cpp_name << std::endl; cpp_name += ".new"; std::cout << "New template will be created: " << cpp_name << std::endl; } std::ofstream cpp_file(cpp_name.c_str()); std::cout << "User file will be created: " << cpp_name << std::endl; generateUserSourceHead(cpp_file, h_name); cpp_file << "#include <ulxmlrpcpp/ulxr_response.h>\n"; cpp_file << "#include <ulxmlrpcpp/ulxr_method_adder.h>\n"; cpp_file << "#include <ulxmlrpcpp/ulxr_signature.h>\n\n"; cpp_file << "#include \"" << theClass.getSource() << "\"\n"; cpp_file << "#include \"" << name + "_ulxr_names.h" << "\"\n\n"; cpp_file << "\nvoid " << name << "Server::setupServerMethods()\n" "{\n"; for (unsigned i = 0; i < theClass.numMethods(); ++i) { if (i != 0) cpp_file << "\n"; Method method = theClass.getMethod(i); method.extractNamespace(); cpp_file << " // mapped to: " << method.getCppString(0, false, ""); if (method.getName() != method.getOverloadName()) cpp_file << " (there are overloaded methods)"; cpp_file << "\n" " method_adder.addMethod(ulxr::make_method(*this, &" << method.getOverloadName(true, "Server") << "),\n" " " << method.getType().getRpcName() << "::getValueName(),\n" " ULXR_CALLTO_" << method.getOverloadName(true, "", "_") << ",\n" " ulxr::Signature()"; for (unsigned p = 0; p < method.numArgs(); ++p) cpp_file << "\n << " << method.getArg(p).getType().getRpcName() << "::getValueName()"; cpp_file << ",\n" " ulxr_i18n(ULXR_PCHAR(\"Some descriptive comment about '" << method.getCppString(0, true, "") << "'.\"))); // TODO adjust comment\n"; } cpp_file << "}\n\n"; }
void InterpretTest::localsTest() { ConstantPool * pool = new ConstantPool(); Class * cls = initClass("LocalsTest", pool); const char code[] = { PUSH, 0x00, 0x00, STORE_LOCAL, 0x00, PUSH, 0x01, 0x00, STORE_LOCAL, 0x01, LOAD_LOCAL, 0x00, LOAD_LOCAL, 0x01, ADD, RET }; Method * m = initMethod("localsTest", code, sizeof(code), 0, 2, 0); ClassLoader cl(""); Interpret instance(&cl); IntConst i; i.value = 20; pool->addItem(&i, INT_CONST); i.value = 30; pool->addItem(&i, INT_CONST); cls->addMethod(m); cl.addClass(cls); assert(50 == instance.run(cls->getName().c_str(), m->getName().c_str())); }
void InterpretTest::aritmeticTest() { ConstantPool * pool = new ConstantPool(); Class * cls = initClass("AritmeticTest", pool); const char code[] = { PUSH, 0x00, 0x00, PUSH, 0x01, 0x00, ADD, PUSH, 0x00, 0x00, SUB, PUSH, 0x00, 0x00, MUL, PUSH, 0x00, 0x00, DIV, INC, DEC, RET }; Method * m = initMethod("aritmeticTest", code, sizeof(code), 0, 0, 0); ClassLoader cl(""); Interpret instance(&cl); IntConst i; i.value = 20; pool->addItem(&i, INT_CONST); i.value = 30; pool->addItem(&i, INT_CONST); cls->addMethod(m); cl.addClass(cls); assert(30 == instance.run(cls->getName().c_str(), m->getName().c_str())); }
int main(int argc, char** argv){ //===================================Test JNI functions======================================= //testJNI(); //===================================end Test JNI functions=================================== Loader * l= Loader::getInstance(); Heap * h= Heap::getInstance(); char className[80]; ClassData * cptr=NULL; Method * m = NULL; ByteCode * b= NULL; cout<<"Enter calssName: "; //cin>> className; strcpy(className,argv[1]); cptr = l->getClassData(className); cptr->prepare(); cout<<"Class name is: "<<cptr->getFQName()<<endl; cout<<"Initialize the class"<<endl; cptr->initialize(); /* cout<<"Hash size: "<<h->HashSize()<<endl; m=cptr->lookupMethod("<clinit>","()V"); cout<<"method name: "<<m->getName()<<endl<<"describtor :"<<m->getDesc()<<endl; exec->executeMethod(NULL,m);*/ m=cptr->lookupMethod("main","()V"); cout<<endl<<endl<<"method name: "<<m->getName()<<endl<<"describtor :"<<m->getDesc()<<endl; /* b=m->getByteCode(); for(int i =0 ; i<b->codeLength;i++) { cout<<(int)b->code[i]<<endl; }*/ b=m->getByteCode(); //Execute the main ExecutionEng::e_exexute(cptr->constantPool,b); Loader::deleteLoader(); Heap::deleteHeap(); /* int * j=NULL; cout<<u4(j)<<"\t"<<j<<endl; int i=-1000000; vArg(12,123.777,-1,'a',false,&i);*/ }
void TypeChecker::checkAbstraction(Class* subClass){ if (!subClass->getBaseClassSymbol()->isAbstract){ return; // no abstraction check required } if (subClass->isAbstract) // base class abstract and sub class also declared abstract return; Class* baseClass = subClass->getBaseClassSymbol(); Method* walker = baseClass->getMethods(); if (walker == nullptr){ //the base class has no methods //and declared as abstract //sub class should be declared too string errString = string(subClass->getName()) + " should be declared abstract"; this->errRecovery->errQ->enqueue(subClass->getLineNo(), subClass->getColNo(), errString.c_str(), ""); return; // done } //the base class has methods while (walker != nullptr){ if (walker->isAbstract){ // abstract base method //search the sub class for overrided method Method* subsWalker = subClass->getMethods(); if (subsWalker == nullptr){ // the sub class has no methods string errString = string(subClass->getName()) + " should be declared abstract, or override all abstract methods"; this->errRecovery->errQ->enqueue(subClass->getLineNo(), subClass->getColNo(), errString.c_str(), ""); } //the sub class has methods bool foundAbsMethod = false; while (subsWalker != nullptr){ if (string(subsWalker->getName()) == string(walker->getName())) foundAbsMethod = true; // we found the method in sub class subsWalker = dynamic_cast<Method*>(subsWalker->node); } if (!foundAbsMethod){ string errString = string(subClass->getName()) + " doesn't implement " + walker->getName(); this->errRecovery->errQ->enqueue(subClass->getLineNo(), subClass->getColNo(), errString.c_str() , ""); } } walker = dynamic_cast<Method*>(walker->node); } }
void InterpretTest::arrayTest() { ConstantPool * pool = new ConstantPool(); Class * cls = initClass("ArrayTest", pool); const char code[] = { PUSH, 0x01, 0x00, NEW_ARRAY, // a = array[10] STORE_LOCAL, 0x00, PUSH, 0x00, 0x00, STORE_LOCAL, 0x01, // i = 0 LOAD_LOCAL, 0x01, //label1 PUSH, 0x01, 0x00, SUB, IF_GE, 0x0C,//if(i < 10) LOAD_LOCAL, 0x01, DUP, DUP, LOAD_LOCAL, 0x00, STORE_ARRAY, //a[i] = i INC, STORE_LOCAL, 0x01, JMP, -20, //jmp label1 PUSH, 0x00, 0x00, PUSH, 0x00, 0x00, STORE_LOCAL, 0x01, STORE_LOCAL, 0x02, LOAD_LOCAL, 0x01, //label2 PUSH, 0x01, 0x00, SUB, IF_GE, 17,//if(i < 10) LOAD_LOCAL, 0x01, LOAD_LOCAL, 0x00, LOAD_ARRAY, LOAD_LOCAL, 0x02, ADD, STORE_LOCAL, 0x02, //sum += a[i] LOAD_LOCAL, 0x01, INC, STORE_LOCAL, 0x01, JMP, -25, //jmp label2 LOAD_LOCAL, 0x02, RET }; Method * m = initMethod("arrayTest", code, sizeof(code), 0, 3, 0); ClassLoader cl(""); Interpret instance(&cl); IntConst i; i.value = 0; pool->addItem(&i, INT_CONST);//0 i.value = 10; pool->addItem(&i, INT_CONST);//1 cls->addMethod(m); cl.addClass(cls); assert(45 == instance.run(cls->getName().c_str(), m->getName().c_str())); }
void Symbol_Table::insert_scope2(char *name,Scope *scope){ Method * t = (Method*)this->currScope->m->lookup(name); if(t) { t = new Method(); t->setName(t->getName()); t->setScope(scope); this->rootScope->m->pop(name); this->rootScope->m->insert(name, t); } }
void InterpretTest::jumpTest() { ConstantPool * pool = new ConstantPool(); Class * cls = initClass("JumpTest", pool); const char code[] = { JMP, 0x01, RET_VOID, //skipped PUSH, 0x01, 0x00, IF_EQ, 0x01, RET_VOID, //skipped PUSH, 0x00, 0x00, IF_NE, 0x01, RET_VOID, //skipped PUSH, 0x02, 0x00, IF_LT, 0x01, RET_VOID, //skipped PUSH, 0x00, 0x00, IF_GT, 0x01, RET_VOID, //skipped PUSH, 0x00, 0x00, PUSH, 0x00, 0x00, IF_LE, 0x02, IF_GE, 0x01, RET_VOID, //skipped PUSH, 0x00, 0x00, INC, PUSH, 0x00, 0x00, INC, CMP_EQ, IF_EQ, 0x01, RET_VOID, PUSH, 0x00, 0x00, PUSH, 0x0, 0x00, CMP_NE, IF_NE, 0x01, RET_VOID, PUSH, 0x00, 0x00, RET }; Method * m = initMethod("jumpTest", code, sizeof(code), 0, 0, 0); ClassLoader cl(""); Interpret instance(&cl); IntConst i; i.value = 1; pool->addItem(&i, INT_CONST); i.value = 0; pool->addItem(&i, INT_CONST); i.value = -1; pool->addItem(&i, INT_CONST); cls->addMethod(m); cl.addClass(cls); assert(1 == instance.run(cls->getName().c_str(), m->getName().c_str())); }
void TypeChecker::checkOverridingMethods(Class* subClass){ Class* baseClass = subClass->getBaseClassSymbol(); Method* walker = baseClass->getMethods(); if (walker == nullptr) // no methods return; while (walker != nullptr){ Method* subsWalker = subClass->getMethods(); while (subsWalker != nullptr){ if (string(subsWalker->getName()) == string(walker->getName())){ // we found a method overriding the final base method if (walker->isFinal()){ // final base method string errString = string(subClass->getName()) + " can't implement final method " + walker->getName(); this->errRecovery->errQ->enqueue(subClass->getLineNo(), subClass->getColNo(), errString.c_str(), ""); } else { // the base method is not final, check access level switch(walker->getAccessModifier()){ case PROTECTED_ACCESS: if (subsWalker->getAccessModifier() == PRIVATE_ACCESS){ string errString = string(subClass->getName()) + " can't assign weaker access privileges for " + walker->getName(); this->errRecovery->errQ->enqueue(subClass->getLineNo(), subClass->getColNo(), errString.c_str(), ""); } break; case PUBLIC_ACCESS : string errString = string(subClass->getName()) + " can't assign weaker access privileges for " + walker->getName(); this->errRecovery->errQ->enqueue(subClass->getLineNo(), subClass->getColNo(), errString.c_str(), ""); break; } } } subsWalker = dynamic_cast<Method*>(subsWalker->node); } walker = dynamic_cast<Method*>(walker->node); } }
void InterpretTest::callTest() { ConstantPool * pool = new ConstantPool(); Class * cls = initClass("CallTest", pool); const char code1[] = { RET_VOID }; const char code2[] = { PUSH, 0x00, 0x00, RET }; const char code[] = { CALL, 0x01, 0x00, 0x02, 0x00, //ClassRef na pozici 1, MethodRef na pozici 2 CALL, 0x01, 0x00, 0x03, 0x00, //ClassRef na pozici 1, MethodRef na pozici 3 RET }; Method * m = initMethod("callTest", code, sizeof(code), 0, 0, 0); Method * m1 = initMethod("returnVoid", code1, sizeof(code1), 0, 0, 0); Method * m2 = initMethod("returnInt", code2, sizeof(code2), 0, 0, 0); ClassLoader cl(""); Interpret instance(&cl); IntConst i; i.value = 1; pool->addItem(&i, INT_CONST);//0 ClassRef cr; memset(cr.name, 0x00, IDENTIFIER_LENGTH); sprintf(cr.name, "%s", cls->getName().c_str()); pool->addItem(&cr, CLASS_REF);//1 MethodRef mr; sprintf(mr.name, "%s", m1->getName().c_str()); mr.params = 0; pool->addItem(&mr, METHOD_REF);//2 sprintf(mr.name, "%s", m2->getName().c_str()); pool->addItem(&mr, METHOD_REF);//3 cls->addMethod(m); cls->addMethod(m1); cls->addMethod(m2); cl.addClass(cls); assert(1 == instance.run(cls->getName().c_str(), m->getName().c_str())); }
void InterpretTest::consoleTest() { ConstantPool * pool = new ConstantPool(); Class * cls = initClass("ConsoleTest", pool); const char code[] = { PUSH, 0x00, 0x00, CALL, 0x01, 0x00, 0x02, 0x00, //console.print(20) CALL, 0x01, 0x00, 0x03, 0x00, //line = console.readLine() CALL, 0x01, 0x00, 0x02, 0x00, //console.print(line) CALL, 0x01, 0x00, 0x04, 0x00, //i = console.readInt() CALL, 0x01, 0x00, 0x02, 0x00, //console.print(i) CALL, 0x01, 0x00, 0x05, 0x00, //i = console.readReal() CALL, 0x01, 0x00, 0x02, 0x00, //console.print(i) RET_VOID }; Method * m = initMethod("consoleTest", code, sizeof(code), 0, 2, 0); ClassLoader cl(""); Interpret instance(&cl); IntConst i; i.value = 20; pool->addItem(&i, INT_CONST);//0 ClassRef cr; sprintf(cr.name, "%s", CONSOLE_CLASS);//1 pool->addItem(&cr, CLASS_REF); MethodRef mr; sprintf(mr.name, "print"); mr.params = 1; pool->addItem(&mr, METHOD_REF);//2 sprintf(mr.name, "readLine"); mr.params = 0; pool->addItem(&mr, METHOD_REF);//3 sprintf(mr.name, "readInt"); mr.params = 0; pool->addItem(&mr, METHOD_REF);//4 sprintf(mr.name, "readReal"); mr.params = 0; pool->addItem(&mr, METHOD_REF);//5 cls->addMethod(m); cl.addClass(cls); instance.run(cls->getName().c_str(), m->getName().c_str()); }
void GenerateServerMethods::generateHeaderMethods(std::ostream & h_file) { for (unsigned i = 0; i < theClass.numMethods(); ++i) { Method method = theClass.getMethod(i); method.extractNamespace(); h_file << " // mapped to: " << method.getCppString(0, false, ""); if (method.getName() != method.getOverloadName()) h_file << " (there are overloaded methods)"; h_file << "\n" << " ulxr::MethodResponse " << method.getOverloadName() << " (const ulxr::MethodCall &calldata);\n\n"; } h_file << " private:\n\n"; h_file << " void setupServerMethods();\n"; h_file << " void removeServerMethods();\n\n"; }
std::string CppCode::generateFullTestReader(Problem& problem) { Method* method = problem.getMethod(); Variable* var; std::string code = tabStr + "const std::string currentDateTime() {\n"+ tabStr + tabStr + "time_t now = time(0);\n"+ tabStr + tabStr + "struct tm tstruct;\n"+ tabStr + tabStr + "char buf[80];\n" + tabStr + tabStr + "tstruct = *localtime(&now);\n"+ tabStr + tabStr + "strftime(buf, sizeof(buf), \"%Y-%m-%d %X\", &tstruct);\n"+ tabStr + tabStr + "return buf;\n"+ tabStr+"}\n\n"+ tabStr+"//This method will only accept input files that are formatted in proper way.\n"+ tabStr+"//Command line example: "+problem.getClassName()+".exe -2 <"+problem.getClassName()+".io\n"+ tabStr+"bool run_full_test() {\n" + tabStr+tabStr+"int testCase, N, caseNo, correct=0;\n"; //declare all variables for (int i=0; i<method->getNumberOfParameters(); i++) { var = method->getParameterAt(i); code+= tabStr+tabStr+this->generateDatatype(var)+" "+var->getName()+";\n";//vector<int> var; //if we have an array then we will create another variable to read single item of that array, redundant but easy to code :| if (var->isArray()) { code += tabStr+tabStr+this->convertDataType(var->getDataType())+" "+var->getName()+"_sin;\n"; //with _in suffix } } var = method->getReturnVariable(); code+= tabStr+tabStr+this->generateDatatype(var)+" "+var->getName()+";\n";//vector<int> var; if (var->isArray()) { code += tabStr+tabStr+this->convertDataType(var->getDataType())+" "+var->getName()+"_sin;\n"; //with _in suffix } code += "\n"; code+= tabStr+tabStr+"std::cin>>testCase; std::cin.ignore(10, '\\n');\n" + tabStr+tabStr+"for (int i=0; i<testCase; i++) {\n" + tabStr+tabStr+tabStr+"std::cin>>caseNo; std::cin.ignore(10, '\\n');\n"; //code to read all parameters for (int i=0; i<method->getNumberOfParameters(); i++) { code += this->generateSingleCaseReader(method->getParameterAt(i), tabStr+tabStr); } //code to read expected result code += this->generateSingleCaseReader(method->getReturnVariable(), tabStr+tabStr); //code to run class.Method(parameters...) code += tabStr+tabStr+tabStr+"clock_t start_ = clock();\n"; code += tabStr+tabStr+tabStr+this->generateDatatype(method->getReturnVariable())+" received_ = " + problem.getClassName()+"()."+method->getName()+"("; for (int i=0; i<method->getNumberOfParameters(); i++) { if (i) { code += ", "; } code += method->getParameterAt(i)->getName(); } code += ");\n"; code += tabStr+tabStr+tabStr+"correct += verify_case(caseNo, " + method->getReturnVariable()->getName() + ", received_, clock()-start_);\n"; code+=tabStr+tabStr+"}//end of testCase for loop\n\n"; code += tabStr+tabStr +"if (testCase == 0) {\n" + tabStr+tabStr+tabStr+"cerr << \"No test cases run.\" << endl;\n" + tabStr+tabStr+"} else if (correct < testCase) {\n"+ tabStr+tabStr+tabStr+"cerr << \"Some cases FAILED (passed \" << correct << \" of \" << testCase << \").\" << endl;\n"+ tabStr+tabStr+"} else {\n"+ tabStr+tabStr+tabStr+"cerr << \"All \" << testCase << \" tests passed!\" << endl;\n"+ tabStr+tabStr+tabStr+"std::ofstream ofs(\""+problem.getClassName()+".st\", std::ios_base::app);\n"+ tabStr+tabStr+tabStr+"ofs<<currentDateTime()<<std::endl;\n"+ tabStr+tabStr+tabStr+"ofs.close();\n"+ tabStr+tabStr+"}\n"+ tabStr+tabStr+"return true;\n"+ tabStr+"}\n\n"; return code; }
void GenerateServerMethods::generateSourceMethods(std::ostream & cpp_file) { for (unsigned i = 0; i < theClass.numMethods(); ++i) { Method method = theClass.getMethod(i); method.extractNamespace(); cpp_file << "// mapped to: " << method.getCppString(0, false, ""); if (method.getName() != method.getOverloadName()) cpp_file << " (there are overloaded methods)"; cpp_file << "\nulxr::MethodResponse\n " << method.getOverloadName(true, "Server") << " (const ulxr::MethodCall &calldata)\n" << "{\n" << " try\n" << " {\n"; for (unsigned iarg = 0; iarg < method.numArgs(); ++iarg) { std::string adap = method.getArg(iarg).getType().getTypeAdapter(); std::string adap2; if (adap.length() != 0) { adap += "("; adap2 = ")"; } cpp_file << " " << method.getArg(iarg).getType().getName() << " p" << iarg << " = " << "(" << method.getArg(iarg).getType().getName() << ") " << adap + method.getArg(iarg).getType().getRpcName() << "(calldata.getParam(" << iarg << "))." << method.getArg(iarg).getType().getRpcAccessor() << "()" << adap2 << ";\n"; } bool have_retval = false; if (method.getType().getName() != "void" || method.getType().getLeft() != "" || method.getType().getRight() != "") have_retval = true; if (have_retval) { cpp_file << " " << method.getType().getProxyType() << " retval = " << method.getType().getTypeDereference(); } else cpp_file << " "; cpp_file << "server." << method.getName() << "("; for (unsigned iarg = 0; iarg < method.numArgs(); ++iarg) { if (iarg != 0) cpp_file << ", "; // cpp_file << "(" << method.getArg(iarg).getType().getCppString() << ")"; if(method.getArg(iarg).getType().isPointer()) cpp_file << "&"; cpp_file << "p" << iarg; } cpp_file << ");\n"; std::string adap = method.getType().getInversTypeAdapter(); std::string adap2; if (adap.length() != 0) { adap += "("; adap2 = ")"; } if (have_retval) cpp_file << " return ulxr::MethodResponse ("<< method.getType().getRpcName() << " (" << adap << "retval" << adap2 << "));\n"; else cpp_file << " return ulxr::MethodResponse (ulxr::Void());\n"; cpp_file << " }\n" << " catch(std::exception &ex)\n" << " {\n" << " ulxr::CppString s = ULXR_PCHAR(\"C++ exception caught when invoking '" << method.getCppString(0, false, "") << "'\\n \");\n" << " s += ULXR_GET_STRING(ex.what());\n" << " return ulxr::MethodResponse(ulxr::ApplicationError, s);\n" << " }\n" << " catch(...)\n" << " {\n" << " ulxr::CppString s = ULXR_PCHAR(\"Unknown exception caught when invoking '" << method.getCppString(0, false, "") << "'\");\n" << " return ulxr::MethodResponse(ulxr::ApplicationError, s);\n" << " }\n"; cpp_file << "}\n\n\n"; } // ------------------------------------ cpp_file << "\nvoid " << theClass.getBaseName() << "Server::removeServerMethods()\n" "{\n"; for (unsigned i = 0; i < theClass.numMethods(); ++i) { Method method = theClass.getMethod(i); method.extractNamespace(); cpp_file << " method_adder.removeMethod(ULXR_CALLTO_" << method.getOverloadName(true, "", "_") << ");"; cpp_file << " // mapped to: " << method.getCppString(0, false, ""); if (method.getName() != method.getOverloadName()) cpp_file << " (there are overloaded methods)"; cpp_file << "\n"; } cpp_file << "\n}\n\n\n"; }
void InterpretTest::callDynamicTest() { ConstantPool * pool = new ConstantPool(); Class * cls = initClass("Counter", pool); cls->addField("counter"); const char code1[] = { LOAD_LOCAL, 0x00, // PUSH this LOAD, 0x06, 0x00, //PUSH this[0] LOAD_LOCAL, 0x01, // PUSH value ADD, // this[0] + value LOAD_LOCAL, 0x00, // PUSH this STORE, 0x06, 0x00, // this[0] = this[0] + value RET_VOID }; const char code2[] = { LOAD_LOCAL, 0x00, // PUSH this LOAD, 0x06, 0x00, //PUSH this[0] RET }; const char code3[] = { PUSH, 0x04, 0x00, // PUSH 0 LOAD_LOCAL, 0x00, // PUSH this STORE, 0x06, 0x00, // this[0] = 0 RET_VOID }; const char code[] = { NEW, 0x00, 0x00, //new Counter DUP, STORE_LOCAL, 0x00, //a = new Counter CALL_DYNAMIC, 0x03, 0x00, //a.init LOAD_LOCAL, 0x00, PUSH, 0x05, 0x00, //PUSH 3 CALL_DYNAMIC, 0x01, 0x00, //a.increase(3) LOAD_LOCAL, 0x00, CALL_DYNAMIC, 0x02, 0x00, //a.getValue RET }; Method * m = initMethod("callTest", code, sizeof(code), 0, 1, 0); Method * m1 = initMethod("increase", code1, sizeof(code1), 2, 0, 1); Method * m2 = initMethod("getValue", code2, sizeof(code2), 1, 1, 1); Method * m3 = initMethod("init", code3, sizeof(code3), 1, 1, 1); ClassLoader cl(""); Interpret instance(&cl); ClassRef cr; memset(cr.name, 0x00, IDENTIFIER_LENGTH); sprintf(cr.name, "%s", cls->getName().c_str()); pool->addItem(&cr, CLASS_REF); //0 MethodRef mr; mr.params = m1->getParamCount(); sprintf(mr.name, "%s", m1->getName().c_str()); pool->addItem(&mr, METHOD_REF); //1 mr.params = m2->getParamCount(); sprintf(mr.name, "%s", m2->getName().c_str()); pool->addItem(&mr, METHOD_REF); //2 mr.params = m3->getParamCount(); sprintf(mr.name, "%s", m3->getName().c_str()); pool->addItem(&mr, METHOD_REF); //3 IntConst i; i.value = 0; pool->addItem(&i, INT_CONST); //4 i.value = 3; pool->addItem(&i, INT_CONST); //5 FieldRef fr; memset(fr.name, 0x00, IDENTIFIER_LENGTH); sprintf(fr.name, "counter"); pool->addItem(&fr, FIELD_REF); //6 cls->addMethod(m); cls->addMethod(m1); cls->addMethod(m2); cls->addMethod(m3); cl.addClass(cls); assert(3 == instance.run(cls->getName().c_str(), m->getName().c_str())); }