Quote:
Quote:
the way, you implement it, is totally up to you, you could use one big array or c's malloc (i think i would go this way).
I was thinking about having one big chunk of memory, but then that would lead to fragmentation problems, so I thought why not just leave it to the OS?
i would just use the malloc implementation provided by your compiler, because it may be the fastet for a given platform.
Quote:
Quote:
no, in your language every method is 'virtual', if you think of virtual of just meaning, that the address of a method is unkown at compile time, so it has to be determined at run time.
I was refering to what C++ calls 'virtual', that the method can be overridden. Using your definition, then only interface methods are virtual, the others are known at compile time.
are you really sure, that you understood what virtual means in c++?
if you say:
struct A{ void hello() { printf("class a"); } virtual void hello2() { printf("class a"); } }struct A : B{ void hello() { printf("class b"); } void hello2() { printf("class b"); } }void test{ A real_a; B real_b; A* a1; B* a2; a1 = &real_a; a2 = &real_b; a1.hello(); a2.hello(); a1.hello2(); a2.hellow();}
the output would be:
class a
class a
class a
class b
in c++ you can 'overide' every method, but if the method is not declared as virtual the method of the pointer's class is used, if the method is virtual the method of the real class is used.
so every method of yours is virtual.
Quote:
Quote:
what do you mean with an offset to the object's structure?, if the offset and the address of the object's structure is known at compile time, you can simply use the real address of the method.
Because of overriding. This codeclass base void print() print("One")class step1 : base void print() print("Two")class step2 : base void print() print("Three")class step3 : step2 void print() print("Four")base a = base.alloc().init()base b = step1.alloc().init()base c = step2.alloc().init()base d = step3.alloc().init()a.print()b.print()c.print()d.print()// should outputOneTwoThreeFour
Yes you know the offset for the method, but you do not know which one to use. So you use the object to get it's class, then you use the offset of the method to jump to the right place in the class, then you jump to the method. Every class that inherits from base will have that method location pointing to a method. Even if they don't implement that method, it will just point to the last implementation of it.
this is just normal c++ code, with every method being virtual, but it's totally inefficent, as you can trust the c++ compiler writers to have decent knowledge about this topic, you should probally choose to use their way.
the first step of compiling should be to check if a method is anywhere is overridden, if it is, it's marked as virtual (or whatever you want to call it). for every method not being virtual you can determine the address at compile time, because everytime you this method of the object (in source code means), you known the direct address in the bytecode.
for example:
call 0x2310
if the method is virtual, you should really use a vtable, as methods get overridden at class basis, so you waste not so much space, a function call to this method would then look like this:
mov eax, [vtable_start + offset * pointer_size] // i'm not sure about the asm syntax
call eax
as you can see the overhead of this technique is one pointer per class (the pointer to the vtable), for every method overridden one byte per class used (the pointer to the method in the vtable), and the runtime overhead is to construct a pointer to the vtable position (vtable_start + offset * pointer_size), dereffence it and then call the resulting memory offset.
as you can see every method beeing virtual causes a memory and runtime overhead, wich you should avoid.
Quote:
Quote:
Just on an aside, what would be wrong with using pointers on the code and link everything together?
what do you mean, i don't understand your explanation.
Instead of using ID values for a method, just use pointers. If you want to find an object's method, just follow the pointer to it.
// virtual machine implementationclass voodoo_class{ char* name; voodoo_method* methods[];};
Instead of plain data. The byte code could even be linked this way, a reference to a constant could be replaced with a pointer to the constant.
if you really strive for simplicity and clearity you should also try to follow these principle in your vm, so why let the vm know about classes, if it doesn't give you any big advantage?
since your language is staticly typed, and does not need to know anything about method names, etc, you should use some bytecode more like assembler.
the vm itself will be very lightweighted - you can write such an vm in under 1000 lines of code. and be able to express anything you will want.
as i said earlier in this thread i have once written a vm like this, but as i latley looked at the code, it was only on big mess (it seems like i did just start a rewrite, when i stopped).
and all comments are in german, so i think it won't help much if i upload code.
but i will try to update at least the file describing all opcodes and upload it.