Adds native code invoke unit.
This commit is contained in:
parent
a22d91903f
commit
8e5f1e90c3
9 changed files with 305 additions and 6 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -41,3 +41,6 @@ trainscript/tsvm
|
|||
*.tab.h
|
||||
*.l.h
|
||||
lex.yy.cpp
|
||||
|
||||
depmake.exe*
|
||||
docs/*
|
||||
|
|
21
Depfile
Normal file
21
Depfile
Normal file
|
@ -0,0 +1,21 @@
|
|||
#Config
|
||||
Artifact=kernel
|
||||
TempDir=obj
|
||||
SourceDir=asm src
|
||||
Files=trainscript/trainscript.y trainscript/trainscript.l trainscript/tsvm.cpp
|
||||
|
||||
# Tools
|
||||
AS=gcc
|
||||
CC=gcc
|
||||
CXX=g++
|
||||
LD=g++
|
||||
LEX=flex
|
||||
YACC=bison
|
||||
|
||||
# Flags
|
||||
FLAGS=-m32 -Dnullptr=0
|
||||
ASFLAGS=
|
||||
CCFLAGS=-g -std=c11 -Dnullptr=0 -Wall -g -fno-stack-protector -ffreestanding -Iinclude
|
||||
CXXFLAGS=-g -std=c++11 -Wall -g -fno-stack-protector -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore -Wall -Wextra -ffreestanding -Wno-unused-function -Iinclude
|
||||
LDFLAGS=-g -m32 -nostdlib -fno-builtin -Tkernel.ld
|
||||
|
6
Makefile
6
Makefile
|
@ -8,11 +8,11 @@ LEX=flex
|
|||
YACC=bison
|
||||
|
||||
# define nullptr, but not NULL.
|
||||
CFLAGS = -m32 -Dnullptr=0
|
||||
CFLAGS = -m32
|
||||
ASFLAGS =
|
||||
CCFLAGS = -g -std=c11 -Wall -g -fno-stack-protector -ffreestanding -Iinclude
|
||||
CCFLAGS = -g -std=c11 -Wall -Dnullptr=0 -g -fno-stack-protector -ffreestanding -Iinclude
|
||||
CXXFLAGS = -g -std=c++11 -Wall -g -fno-stack-protector -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore -Wall -Wextra -ffreestanding -Wno-unused-function -Iinclude
|
||||
LDFLAGS = -g -m32 -Tkernel.ld
|
||||
LDFLAGS = -g -m32 -nostdlib -fno-builtin -Tkernel.ld
|
||||
|
||||
all: clean kernel
|
||||
|
||||
|
|
109
Makefile.new
Normal file
109
Makefile.new
Normal file
|
@ -0,0 +1,109 @@
|
|||
# Makefile generated by makedep.
|
||||
|
||||
# Tools
|
||||
AS = gcc
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
LD = g++
|
||||
LEX = flex
|
||||
YACC = bison
|
||||
|
||||
# File Lists
|
||||
SRCS_AS = asm/intr_common_handler.S asm/multiboot.S asm/start.S
|
||||
SRCS_CC = src/console.c src/init.c src/interrupts.c src/malloc.c src/pmm.c src/stdlib.c src/timer.c src/vmm.c
|
||||
SRCS_CXX = trainscript/tsvm.cpp src/cplusplus.cpp src/vm.cpp obj/trainscript.yy.cpp obj/trainscript.tab.cpp
|
||||
OBJS = obj/trainscript.o obj/trainscript.o obj/tsvm.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o
|
||||
|
||||
# Flags
|
||||
FLAGS = -m32 -Dnullptr=0
|
||||
ASFLAGS =
|
||||
CCFLAGS = -g -std=c11 -Dnullptr=0 -Wall -g -fno-stack-protector -ffreestanding -Iinclude
|
||||
CXXFLAGS = -g -std=c++11 -Wall -g -fno-stack-protector -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore -Wall -Wextra -ffreestanding -Wno-unused-function -Iinclude
|
||||
LDFLAGS = -g -m32 -nostdlib -fno-builtin -Tkernel.ld
|
||||
|
||||
# Targets
|
||||
all: kernel
|
||||
|
||||
kernel: obj/trainscript.o obj/trainscript.o obj/tsvm.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o
|
||||
$(LD) $(FLAGS) $(LDFLAGS) -o $@ obj/trainscript.o obj/trainscript.o obj/tsvm.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o
|
||||
|
||||
# src/console.c
|
||||
obj/console.o: src/console.c include/console.h include/stdlib.h \
|
||||
include/varargs.h
|
||||
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/console.c
|
||||
|
||||
# src/init.c
|
||||
obj/init.o: src/init.c include/kernel.h include/stdlib.h include/varargs.h \
|
||||
include/console.h include/interrupts.h include/cpustate.h include/pmm.h \
|
||||
include/multiboot.h include/vmm.h include/timer.h
|
||||
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/init.c
|
||||
|
||||
# src/interrupts.c
|
||||
obj/interrupts.o: src/interrupts.c include/interrupts.h include/cpustate.h \
|
||||
include/console.h include/stdlib.h include/varargs.h include/io.h \
|
||||
src/intr_stubs.h
|
||||
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/interrupts.c
|
||||
|
||||
# src/malloc.c
|
||||
obj/malloc.o: src/malloc.c include/stdlib.h include/varargs.h
|
||||
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/malloc.c
|
||||
|
||||
# src/pmm.c
|
||||
obj/pmm.o: src/pmm.c include/pmm.h include/multiboot.h include/kernel.h \
|
||||
include/stdlib.h include/varargs.h include/console.h
|
||||
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/pmm.c
|
||||
|
||||
# src/stdlib.c
|
||||
obj/stdlib.o: src/stdlib.c include/stdlib.h include/varargs.h \
|
||||
include/kernel.h
|
||||
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/stdlib.c
|
||||
|
||||
# src/timer.c
|
||||
obj/timer.o: src/timer.c include/timer.h include/interrupts.h \
|
||||
include/cpustate.h
|
||||
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/timer.c
|
||||
|
||||
# src/vmm.c
|
||||
obj/vmm.o: src/vmm.c include/vmm.h include/pmm.h include/multiboot.h \
|
||||
include/stdlib.h include/varargs.h include/console.h include/kernel.h
|
||||
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/vmm.c
|
||||
|
||||
# trainscript/tsvm.cpp
|
||||
obj/tsvm.o: trainscript/tsvm.cpp include/stdlib.h include/varargs.h \
|
||||
include/console.h trainscript/common.h trainscript/tsvm.hpp \
|
||||
include/ker/string.hpp include/ker/vector.hpp include/ker/new.hpp \
|
||||
include/ker/dictionary.hpp include/ker/pair.hpp trainscript/typeid.hpp \
|
||||
trainscript/trainscript.tab.hpp trainscript/trainscript.l.h \
|
||||
include/string.h
|
||||
$(CXX) $(FLAGS) $(CXXFLAGS) -o $@ -c trainscript/tsvm.cpp
|
||||
|
||||
# src/cplusplus.cpp
|
||||
obj/cplusplus.o: src/cplusplus.cpp include/stdlib.h include/varargs.h \
|
||||
include/console.h include/ker/new.hpp
|
||||
$(CXX) $(FLAGS) $(CXXFLAGS) -o $@ -c src/cplusplus.cpp
|
||||
|
||||
# src/vm.cpp
|
||||
obj/vm.o: src/vm.cpp include/stdlib.h include/varargs.h \
|
||||
src/../trainscript/tsvm.hpp include/console.h include/ker/string.hpp \
|
||||
include/ker/vector.hpp include/ker/new.hpp include/ker/dictionary.hpp \
|
||||
include/ker/pair.hpp src/../trainscript/typeid.hpp
|
||||
$(CXX) $(FLAGS) $(CXXFLAGS) -o $@ -c src/vm.cpp
|
||||
|
||||
# obj/trainscript.yy.cpp
|
||||
$(CXX) $(FLAGS) $(CXXFLAGS) -o $@ -c obj/trainscript.yy.cpp
|
||||
|
||||
# obj/trainscript.tab.cpp
|
||||
$(CXX) $(FLAGS) $(CXXFLAGS) -o $@ -c obj/trainscript.tab.cpp
|
||||
|
||||
# asm/intr_common_handler.S
|
||||
obj/intr_common_handler.o: asm/intr_common_handler.S
|
||||
$(AS) $(FLAGS) $(ASFLAGS) -o $@ -c asm/intr_common_handler.S
|
||||
|
||||
# asm/multiboot.S
|
||||
obj/multiboot.o: asm/multiboot.S
|
||||
$(AS) $(FLAGS) $(ASFLAGS) -o $@ -c asm/multiboot.S
|
||||
|
||||
# asm/start.S
|
||||
obj/start.o: asm/start.S
|
||||
$(AS) $(FLAGS) $(ASFLAGS) -o $@ -c asm/start.S
|
||||
|
|
@ -183,6 +183,7 @@ void kprintf(const char *format, ...)
|
|||
{
|
||||
c = *(format++);
|
||||
int i;
|
||||
float f;
|
||||
char *str;
|
||||
switch(c)
|
||||
{
|
||||
|
@ -200,6 +201,10 @@ void kprintf(const char *format, ...)
|
|||
i = va_arg(vl, int);
|
||||
kputs(itoa(i, buffer, 16));
|
||||
break;
|
||||
case 'f':
|
||||
f = va_arg(vl, float);
|
||||
kputs(ftoa(f, buffer, 3));
|
||||
break;
|
||||
case 'c':
|
||||
c = va_arg(vl, int);
|
||||
kputc(c);
|
||||
|
|
48
src/stdlib.c
48
src/stdlib.c
|
@ -97,6 +97,54 @@ double atod(const char *str)
|
|||
return 42.0;
|
||||
}
|
||||
|
||||
// Converts a given integer x to string str[]. d is the number
|
||||
// of digits required in output. If d is more than the number
|
||||
// of digits in x, then 0s are added at the beginning.
|
||||
static int intToStr(int x, char str[], int d)
|
||||
{
|
||||
int i = 0;
|
||||
while (x)
|
||||
{
|
||||
str[i++] = (x%10) + '0';
|
||||
x = x/10;
|
||||
}
|
||||
|
||||
// If number of digits required is more, then
|
||||
// add 0s at the beginning
|
||||
while (i < d)
|
||||
str[i++] = '0';
|
||||
|
||||
reverse(str, i);
|
||||
str[i] = '\0';
|
||||
return i;
|
||||
}
|
||||
|
||||
// Converts a floating point number to string.
|
||||
void ftoa(float n, char *res, int afterpoint)
|
||||
{
|
||||
// Extract integer part
|
||||
int ipart = (int)n;
|
||||
|
||||
// Extract floating part
|
||||
float fpart = n - (float)ipart;
|
||||
|
||||
// convert integer part to string
|
||||
int i = intToStr(ipart, res, 0);
|
||||
|
||||
// check for display option after point
|
||||
if (afterpoint != 0)
|
||||
{
|
||||
res[i] = '.'; // add dot
|
||||
|
||||
// Get the value of fraction part upto given no.
|
||||
// of points after dot. The third parameter is needed
|
||||
// to handle cases like 233.007
|
||||
//fpart = fpart * pow(10, afterpoint);
|
||||
|
||||
intToStr((int)fpart, res + i + 1, afterpoint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *memmove( void *destination, const void *source, size_t num)
|
||||
{
|
||||
|
|
114
src/vm.cpp
114
src/vm.cpp
|
@ -15,12 +15,18 @@ VAR global : INT;
|
|||
PUB main() | i : INT
|
||||
BEGIN
|
||||
print(10, 20, 30);
|
||||
afraid(15.0, 34) → i;
|
||||
print(40, i, 60);
|
||||
0 -> i;
|
||||
REPEAT
|
||||
WHILE i < 5 DO
|
||||
BEGIN
|
||||
print(i);
|
||||
i + 1 -> i;
|
||||
END
|
||||
REPEAT
|
||||
BEGIN
|
||||
|
||||
END
|
||||
END)code";
|
||||
|
||||
void cpp_test();
|
||||
|
@ -32,6 +38,21 @@ public:
|
|||
Variable invoke(Vector<Variable> arguments) override;
|
||||
};
|
||||
|
||||
class NativeMethod :
|
||||
public Method
|
||||
{
|
||||
private:
|
||||
void *function;
|
||||
public:
|
||||
NativeMethod(void *fn) :
|
||||
function(fn)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Variable invoke(Vector<Variable> arguments) override;
|
||||
};
|
||||
|
||||
Variable PrintMethod::invoke(Vector<Variable> arguments)
|
||||
{
|
||||
for(auto &var : arguments)
|
||||
|
@ -43,6 +64,95 @@ Variable PrintMethod::invoke(Vector<Variable> arguments)
|
|||
return Variable::Void;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
extern "C" uint32_t __attribute__((cdecl)) cCodeFunction(float a, int b)
|
||||
{
|
||||
kprintf("a=%d, b=%d\n", a, b);
|
||||
return 666;
|
||||
}
|
||||
|
||||
extern "C" void vm_start()
|
||||
{
|
||||
// cpp_test();
|
||||
|
@ -58,6 +168,8 @@ extern "C" void vm_start()
|
|||
|
||||
module->methods.add("print", new PrintMethod());
|
||||
|
||||
module->methods.add("afraid", new NativeMethod(reinterpret_cast<void*>(&cCodeFunction)));
|
||||
|
||||
for(const auto &var : module->variables)
|
||||
{
|
||||
kprintf("Variable: '%s' => '", var.first.str());
|
||||
|
|
|
@ -51,7 +51,8 @@ DISTFILES += \
|
|||
trainscript/Makefile \
|
||||
trainscript/trainscript.y \
|
||||
trainscript/file02.ts \
|
||||
kernel.ld
|
||||
kernel.ld \
|
||||
Depfile
|
||||
|
||||
QMAKE_INCDIR =
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ extern "C" {
|
|||
namespace trainscript
|
||||
{
|
||||
using Int = int32_t;
|
||||
using Real = double;
|
||||
using Real = float;
|
||||
using Void = void;
|
||||
using Bool = bool;
|
||||
|
||||
|
|
Loading…
Reference in a new issue