Thanks for replies.
Trap:
Quote:
Why do you have a dedicated _this register?
Just think of it as ecx. This is a generic register, but when calling functions from objects, it keeps the pointed object. It can keep any value, just like _reg_x registers.
The problem starts when generating assembly from high level code. Despite the fact that _this can hold anything, i only use it to access member variables from objects.
Quote:
Where does push _this store the value of _this (on the same stack as everything else)?
Yes. Push operates on stack whatever thing it has to push. It doesn't distinguish between registers, variables and constants.
Quote:
Can you do mov _reg_1, _this; and mov _this,_reg_1;?
Yes. As i said above, _this is just another general purpose register.
Quote:
What is your procedure calling convention?
Parameters are passed from left to right, and the called function is responsible for cleaning the stack (or more correctly, the vm when a ret instruction is encountered). So it looks like __stdcall with reversed parameter passing.
I haven't really thought of passing parameters from right to left (as __stdcall does). I think, it doesn't really matter if the called function keeps parameter indexes in correct order.
Quote:
Moving this-change directly in front of the call doesn't change the number of stack-moves, does it?
Altering _this register by moving something to it (line 8) doesn't change the stack. But pushing _this on the stack, does change it. I'll try to explain the problem better.
deffer:
Quote:
So the only reason you're going with AST is optimization, is that correct?
With AST (Abstract Syntax Tree) i mean the parser output. I'm not doing any AST level optimizations (which i should, btw).
Quote:
If you've decided to make _this register the only one (besides _stack) that can do memory accesses, then you're stuck with constantly swapping _this. If you really want do do optimizations, make other registers able to do such magic.
No. Every register (as long as it holds a reference to an object) can do memory accesses. So _reg_1[someMember] is possible as long as _reg_1 holds an object.
The problem isn't how things work at assembly level. If i was writing scripts in assembly, then everything would be fine. The problem is how to generate assembly code from the high level representation of the statement.
A member function call looks like this:
object.member1.member2.function(argument1, argument2, ...);
where arguments can be function calls, constants, objects and members.
The way i'm handling the above piece of code now, is this:
1) I have an identifier followed by period ('.'). Check to see if it's an object. It is.
1.1) In case to be able to do anything on it (access its members) i have to move it somewhere. Move it to _this, so i know where to search for its members.
1.2) After this step, previous _this is on the stack, and _this now holds 'object'.
2) Check to see if the identifier following the period is a function or a variable. If it is a variable go to 1. Else go to 3.
3) We reached the actual function call. For every argument, calculate the expression using the stack and leave the result on the stack.
4) At this point the stack has arguments pushed, _this pointer points to member2 (the last variable), so call the function.
5) pop all object from the stack so _this returns to its initial value.
If i understood what you suggested correctly, i have to first find the actual function call, assemble all expressions (function arguments) and then change _this to point to member2?
Is this correct?
Thanks again for the replies.
HellRaiZer