{"id":18900233,"url":"https://github.com/grosquildu/agh_vm","last_synced_at":"2025-09-09T16:43:46.511Z","repository":{"id":89132201,"uuid":"113711498","full_name":"GrosQuildu/agh_vm","owner":"GrosQuildu","description":"Virtual machine for design patterns subject","archived":false,"fork":false,"pushed_at":"2020-07-13T10:56:34.000Z","size":98,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-05-24T09:39:37.979Z","etag":null,"topics":["agh","virtual-machine"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GrosQuildu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-12-10T00:30:45.000Z","updated_at":"2022-01-26T14:08:12.000Z","dependencies_parsed_at":"2023-03-04T22:45:19.502Z","dependency_job_id":null,"html_url":"https://github.com/GrosQuildu/agh_vm","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/GrosQuildu/agh_vm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GrosQuildu%2Fagh_vm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GrosQuildu%2Fagh_vm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GrosQuildu%2Fagh_vm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GrosQuildu%2Fagh_vm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GrosQuildu","download_url":"https://codeload.github.com/GrosQuildu/agh_vm/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GrosQuildu%2Fagh_vm/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265049773,"owners_count":23703590,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agh","virtual-machine"],"created_at":"2024-11-08T08:50:37.146Z","updated_at":"2025-07-12T20:38:56.120Z","avatar_url":"https://github.com/GrosQuildu.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Virtual Machine\n\nA virtual machine developed during a Design Patterns course on AGH UST.\n\n### Build and run:\n\n```bash\nbash ./build.sh [ARM | x86] [NORMAL | DEBUG]\n\nqemu-arm -L /usr/arm-linux-gnueabi/ ./VM --help\n# or\n./VM --help\n```\n\nDEBUG mode uses ncurses.\n\n\n### Bytecode\nProgram to run must be placed in separate directory. Files extension must be \".pp\".\n\nOne file is one function. Template is:\n\n```\nDEF FUNCTION_NAME ARGS_COUNT\nDECLARE VARIABLE1\nDECLARE VARIABLE2\n...\n\nLOAD 0\nRETURN\nEND\n```\n\nVariables declaration must be placed just after function header. Variables can store signed integers. Functions must end with RETURN and END.\n\nMachine implements (software) threading, each thread must be started with a function. Main thread is determined by function name: \"MAIN\".\n\nWord after bytecode can be one of: VAR (variable name), CONST (integer), ARG (ARG_number, like ARG_0), FUNC (function name), THREAD (thread name)\n\nArguments to bytecode (like RETURN or ADD) are passed by LOAD[V|T|F] bytecode.\n\n\n##### Assign, print, arithmetic\n\n```\n# varname := 12\nLOADV VARNAME\nLOAD 12\nASSIGN\n\n# print args[1]\nLOAD ARG_1\nPRINT\n\n# var1 := var2 + 12\nLOADV VAR1\nLOADV VAR2\nLOAD 12\nADD\n\n# var1 := var1 - var2\nLOADV VAR1\nLOADV VAR1\nLOADV VAR2\nSUB\n\n# var1 := 12 / arg[0]\nLOADV VAR1\nLOAD 12\nLOAD ARG_0\nDIV\n\n# var2 := var1  * var3\nLOADV VAR2\nLOADV VAR1\nLOADV VAR3\nMUL\n```\n\n##### Function calls\n\n```\n# var1 := function_name(-15, var1)\nLOADF FUNCTION_NAME  # function to call, name as declared in function header after \"DEF\"\nLOADV VAR1  # variable where to store result of function call\nLOAD -15  # first arg to function, amount of args for function is declared in function header after function name\nLOADV VAR1  # second arg to function\nCALL\n\n# return -1\nLOAD -1\nRETURN\n```\n\n##### Threads\n\n```\n# new thread, return value of thread's main function will be lost\nLOADF FUNC_NAME\nLOADT THREAD_NAME  # must be unique in whole program\nLOAD -15  # first argument to function\n\n# stop thread\nLOADT THREAD_NAME\nSTOP\n\n# join (wait until given thread ends)\nLOADT THREAD_TO_WAIT_FOR_NAME\nJOIN\n\n# send value to thread, non blocking call\nLOADT THREAD_NAME\nLOADV VAR1\nSEND\n\n# recv value, store in varx. Blocks until any value in recv table. Can't determine which thread send value.\nLOADV VARX\nRECV\n\n# change thread's priority, must be in range [1,10]. Greater value, more priority.\nLOADT THREAD_NAME\nLOAD 9\nPRIORITY\n```\n\nExamples in `example_programs` directory\n\n\n### Scheduler\n\nMachine support three types of scheduling: first-in first-out, round-robin and priority based. Scheduler can be selected in VM command line arguments.\n\nFIFO scheduler works as expected: main thread is executed, then next threads in order they were started. Blocking operations (recv, join) may force thread change.\n\nRound robin executes few bytecodes from each thread, then move to next thread. Number of bytecodes is set by scheduler class in initialize method in Thread.cpp file.\n\nPriority scheduler execute thread with the highest priority, if more than one thread have the same priority, they are scheduled in round-robin style.\n\n\n### JIT\n\nMachine had to works as \u003every simple\u003c just-in-time compiler (or inline-threading as some call it). So each function is divided into blocks (size depends on which scheduler is used), each block is compiled by external compiler (gcc), loaded as shared library and called when needed. Blocks (c++ code as shared library file) are stored in folder specified in command line argument.\n\n\n### Patterns\n\nIt was required to use at least three design patterns in the project. Comments in source code points to methods that implements a pattern.\n\n* Observer\n  + Used when joining thread (thread that want to wait register himself in target thread, when that thread ends, it notify each of registered threads)\n  + Observers and observable classes are the same: Thread\n* Singleton\n  + VM class is used to start and clear after execution of bytecode. It also works as interface for bytecode for some instructions (like starting new thread). It's impemented as singleton.\n  + Class: VM\n* Prototype\n  + Functions specified in \".pp\" files can be reused (f.e. call the same funtion few times) and some of the variables (like consts and bytecode table) are constants and some vary (like function's arguments), so prototype pattern was used to simplify creation of new functions.\n  + Classes: FunctionPrototype, FunctionFactory, Function.\n* Strategy\n  + Pseudo (lacks wrapper class) strategy pattern was used to implement different schedulers\n  + Classes: ThreadScheduler, FIFOScheduler, RoundRobinScheduler, PriorityScheduler\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrosquildu%2Fagh_vm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgrosquildu%2Fagh_vm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrosquildu%2Fagh_vm/lists"}