Small cleanups.
This commit is contained in:
parent
6afe323080
commit
0f54fabc99
3 changed files with 333 additions and 19 deletions
|
@ -2,7 +2,7 @@ VAR global : INT;
|
|||
|
||||
PUB main() | i : INT
|
||||
BEGIN
|
||||
fun(1) -> i;
|
||||
fun() -> i;
|
||||
END
|
||||
|
||||
PUB fun() -> i : INT
|
||||
|
|
19
src/vm.cpp
19
src/vm.cpp
|
@ -128,12 +128,6 @@ Variable NativeMethod::invoke(Vector<Variable> arguments)
|
|||
return mkvar((Int)result);
|
||||
}
|
||||
|
||||
extern "C" uint32_t __cdecl cCodeFunction(int a, int b)
|
||||
{
|
||||
kprintf("a=%d, b=%d\n", a, b);
|
||||
return 666;
|
||||
}
|
||||
|
||||
struct NativeModuleDef
|
||||
{
|
||||
const char *name;
|
||||
|
@ -174,24 +168,13 @@ extern "C" void vm_start()
|
|||
return;
|
||||
}
|
||||
|
||||
// Load native modules
|
||||
NativeModuleDef *mod = methods;
|
||||
while(mod->name != nullptr) {
|
||||
module->methods.add(mod->name, new NativeMethod(mod->function));
|
||||
mod++;
|
||||
}
|
||||
|
||||
for(const auto &var : module->variables)
|
||||
{
|
||||
kprintf("Variable: '%s' => '", var.first.str());
|
||||
var.second->printval();
|
||||
kprintf("'\n");
|
||||
}
|
||||
|
||||
for(const auto &fn : module->methods)
|
||||
{
|
||||
kprintf("Function: '%s'\n", fn.first.str());
|
||||
}
|
||||
|
||||
Method *main = module->method("main");
|
||||
if(main == nullptr) {
|
||||
kprintf("Script has no main method.\n");
|
||||
|
|
331
src/vm.cpp.autosave
Normal file
331
src/vm.cpp.autosave
Normal file
|
@ -0,0 +1,331 @@
|
|||
#include <stdlib.h>
|
||||
#include <timer.h>
|
||||
#include "../trainscript/tsvm.hpp"
|
||||
|
||||
using namespace ker;
|
||||
using namespace trainscript;
|
||||
|
||||
extern "C" {
|
||||
extern const char mainscript_start;
|
||||
extern const char mainscript_end;
|
||||
extern const char mainscript_size;
|
||||
}
|
||||
|
||||
void cpp_test();
|
||||
|
||||
class NativeMethod :
|
||||
public Method
|
||||
{
|
||||
private:
|
||||
void *function;
|
||||
public:
|
||||
NativeMethod(void *fn) :
|
||||
function(fn)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Variable invoke(Vector<Variable> arguments) override;
|
||||
|
||||
bool validate(ker::String &errorCode) const
|
||||
{
|
||||
if(this->function == nullptr) {
|
||||
errorCode = "Native method with nullptr interface.";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Vector<Type> arguments() const {
|
||||
return Vector<Type>();
|
||||
}
|
||||
|
||||
Type returnType() const {
|
||||
return Type::Int;
|
||||
}
|
||||
};
|
||||
|
||||
static void copyCode(uint8_t **ptr, const uint8_t *src, size_t length)
|
||||
{
|
||||
for(size_t i = 0; i < length; i++) {
|
||||
// Copy byte
|
||||
**ptr = src[i];
|
||||
// Iterate
|
||||
(*ptr)++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Invokes a cdecl function
|
||||
* @param arguments Arguments passed to the c function
|
||||
* @return uint32_t return value of the c function
|
||||
*/
|
||||
Variable NativeMethod::invoke(Vector<Variable> arguments)
|
||||
{
|
||||
if(this->function == nullptr) {
|
||||
return Variable::Invalid;
|
||||
}
|
||||
|
||||
// ASM code:
|
||||
// push ebp
|
||||
// mov ebp, esp
|
||||
// (push imm32) * num
|
||||
// call [function]
|
||||
// add esp, 4 * num
|
||||
// ret
|
||||
|
||||
uint8_t headerCode[] = {
|
||||
0x55, // push ebp
|
||||
0x89, 0xE5, // mov ebp, esp
|
||||
};
|
||||
uint8_t tailCode[] = {
|
||||
0xB8, 0x42, 0x00, 0x00, 0x00, // mov eax,0x42
|
||||
0xFF, 0xD0, // call eax
|
||||
0x83, 0xC4, 0x08, // add esp, 0x00
|
||||
0xC9, // leave
|
||||
// 0x5D, // pop ebp
|
||||
0xC3, // ret
|
||||
};
|
||||
|
||||
// Store some memory for a function
|
||||
uint8_t pushCode[] = {
|
||||
0x68, 0x00, 0x00, 0x00, 0x00 // push 0x00
|
||||
};
|
||||
|
||||
size_t stackSize = 4 * arguments.length();
|
||||
|
||||
// Copy target address to mov eax, 0x42
|
||||
*reinterpret_cast<uintptr_t*>(&tailCode[1]) = reinterpret_cast<uintptr_t>(this->function);
|
||||
// Copy stack size to add esp, 0x00
|
||||
*reinterpret_cast<uint8_t*>(&tailCode[9]) = static_cast<uint8_t>(stackSize);
|
||||
|
||||
uint8_t code[128];
|
||||
// Built the function
|
||||
{
|
||||
uint8_t *codePtr = &code[0];
|
||||
// Copy function header
|
||||
copyCode(&codePtr, headerCode, sizeof(headerCode));
|
||||
|
||||
// Copy arguments
|
||||
for(int i = arguments.length() - 1; i >= 0; i--) {
|
||||
|
||||
// Copy argument value to push 0x00
|
||||
*reinterpret_cast<int32_t*>(&pushCode[1]) = reinterpret_cast<int32_t>(arguments[i].integer);
|
||||
|
||||
// Copy push code
|
||||
copyCode(&codePtr, pushCode, sizeof(pushCode));
|
||||
}
|
||||
|
||||
// Copy function end
|
||||
copyCode(&codePtr, tailCode, sizeof(tailCode));
|
||||
}
|
||||
|
||||
// Call some crazy
|
||||
uint32_t (*func)() = (uint32_t(*)())code;
|
||||
|
||||
uint32_t result = func();
|
||||
|
||||
return mkvar((Int)result);
|
||||
}
|
||||
|
||||
struct NativeModuleDef
|
||||
{
|
||||
const char *name;
|
||||
void *function;
|
||||
};
|
||||
|
||||
NativeModuleDef methods[] = {
|
||||
{ "sleep", (void*)sleep },
|
||||
{ "timer_get", (void*)timer_get },
|
||||
{ "timer_set", (void*)timer_set },
|
||||
{ nullptr, 0 }
|
||||
};
|
||||
|
||||
extern "C" void vm_start()
|
||||
{
|
||||
struct {
|
||||
const char *ptr;
|
||||
uint32_t size;
|
||||
} mainfile {
|
||||
&mainscript_start,
|
||||
(uint32_t)&mainscript_size
|
||||
};
|
||||
|
||||
// cpp_test();
|
||||
|
||||
kprintf("Parse kernel module: ");
|
||||
Module *module = VM::load(mainfile.ptr, mainfile.size);
|
||||
if(module == nullptr) {
|
||||
kprintf("Could not load module :(\n");
|
||||
return;
|
||||
}
|
||||
|
||||
kprintf("Module successfully loaded :)\n");
|
||||
|
||||
String errorCode;
|
||||
if(module->validate(errorCode) == false) {
|
||||
kprintf("Module validation failed: \x12\x06%s\x12\x07\n", errorCode.str());
|
||||
return;
|
||||
}
|
||||
|
||||
// Load native modules
|
||||
NativeModuleDef *mod = methods;
|
||||
while(mod->name != nullptr) {
|
||||
module->methods.add(mod->name, new NativeMethod(mod->function));
|
||||
mod++;
|
||||
}
|
||||
|
||||
Method *main = module->method("main");
|
||||
if(main == nullptr) {
|
||||
kprintf("Script has no main method.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
main->invoke({ });
|
||||
|
||||
delete module;
|
||||
}
|
||||
|
||||
|
||||
String fn()
|
||||
{
|
||||
return String("keks");
|
||||
}
|
||||
|
||||
void put(Vector<int> &v)
|
||||
{
|
||||
kprintf("v[%d]: ", v.length());
|
||||
for(int i : v) { kprintf("%d,", i); }
|
||||
kprintf("\n");
|
||||
}
|
||||
|
||||
void put(Vector<String> &v)
|
||||
{
|
||||
kprintf("v[%d]: ", v.length());
|
||||
for(String &s : v) { kprintf("[%s],", s.str()); }
|
||||
kprintf("\n");
|
||||
}
|
||||
|
||||
void put(Dictionary<int, int> &d)
|
||||
{
|
||||
kprintf("dict: ");
|
||||
for(auto &it : d)
|
||||
{
|
||||
kprintf("[%d -> %d] ", it.first, it.second);
|
||||
}
|
||||
kprintf("\n");
|
||||
}
|
||||
|
||||
void put(Dictionary<String, String> &d)
|
||||
{
|
||||
kprintf("dict: ");
|
||||
for(auto &it : d)
|
||||
{
|
||||
kprintf("[%s -> %s] ", it.first.str(), it.second.str());
|
||||
}
|
||||
kprintf("\n");
|
||||
}
|
||||
|
||||
void cpp_test()
|
||||
{
|
||||
kprintf("Testing ker::String:\n");
|
||||
{
|
||||
String a("hello");
|
||||
String b(a);
|
||||
String c;
|
||||
String d(fn());
|
||||
String e;
|
||||
c = a;
|
||||
e = fn();
|
||||
|
||||
kprintf("'%s' '%s' '%s' '%s' '%s'\n", a.str(), b.str(), c.str(), d.str(), e.str());
|
||||
}
|
||||
|
||||
kprintf("Testing ker::Pair:\n");
|
||||
{
|
||||
Pair<int, int> a(10, 20);
|
||||
Pair<String, String> b("Hey", "Affe");
|
||||
|
||||
Pair<int, int> c(a);
|
||||
Pair<String, String> d(b);
|
||||
|
||||
Pair<int, int> e; e = a;
|
||||
Pair<String, String> f; f = b;
|
||||
|
||||
kprintf("'%d,%d' '%d,%d' '%d,%d'\n", a.first, a.second, c.first, c.second, e.first, e.second);
|
||||
kprintf("'%s,%s' '%s,%s' '%s,%s'\n", b.first.str(), b.second.str(), d.first.str(), d.second.str(), f.first.str(), f.second.str());
|
||||
}
|
||||
|
||||
kprintf("Testing ker::Vector:\n");
|
||||
{
|
||||
Vector<int> a;
|
||||
a.append(1);
|
||||
a.append(2);
|
||||
a.append(3);
|
||||
|
||||
Vector<int> c;
|
||||
Vector<int> b(a);
|
||||
c = a;
|
||||
|
||||
put(a);
|
||||
put(b);
|
||||
put(c);
|
||||
}
|
||||
{
|
||||
Vector<String> a;
|
||||
a.append("x");
|
||||
a.append("y");
|
||||
a.append("z");
|
||||
|
||||
Vector<String> c;
|
||||
Vector<String> b(a);
|
||||
c = a;
|
||||
|
||||
put(a);
|
||||
put(b);
|
||||
put(c);
|
||||
}
|
||||
|
||||
kprintf("Testing ker::Dictionary:\n");
|
||||
{
|
||||
kprintf("int -> int\n");
|
||||
Dictionary<int, int> a;
|
||||
a.add(1, 30);
|
||||
a.add(2, 20);
|
||||
a.add(3, 10);
|
||||
|
||||
kprintf("%d %d\n", a.contains(1), a.contains(4));
|
||||
kprintf("%d %d\n", a.at(1), a.at(3));
|
||||
kprintf("%d %d\n", a[1], a[3]);
|
||||
|
||||
Dictionary<int, int> b(a);
|
||||
Dictionary<int, int> c;
|
||||
c = a;
|
||||
|
||||
put(a);
|
||||
put(b);
|
||||
put(c);
|
||||
}
|
||||
|
||||
{
|
||||
kprintf("String -> String\n");
|
||||
Dictionary<String, String> a;
|
||||
a.add("x", "30");
|
||||
a.add("y", "20");
|
||||
a.add("z", "10");
|
||||
|
||||
kprintf("%d %d\n", a.contains("x"), a.contains("w"));
|
||||
kprintf("%s %s\n", a.at("x").str(), a.at("z").str());
|
||||
kprintf("%s %s\n", a["x"].str(), a["z"].str());
|
||||
|
||||
Dictionary<String, String> b(a);
|
||||
Dictionary<String, String> c;
|
||||
c = a;
|
||||
|
||||
put(a);
|
||||
put(b);
|
||||
put(c);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue