Presentation is loading. Please wait.

Presentation is loading. Please wait.

Prof. Fateman CS 164 Lecture 281 Virtual Machine Structure Lecture 28.

Similar presentations


Presentation on theme: "Prof. Fateman CS 164 Lecture 281 Virtual Machine Structure Lecture 28."— Presentation transcript:

1 Prof. Fateman CS 164 Lecture 281 Virtual Machine Structure Lecture 28

2 Prof. Fateman CS 164 Lecture 282 Basics of the Tiger Virtual Machine Byte addressed (though we do this only as a concession to the annoying reality of some machines: we are forever shifting by 2 bits to get from words to bytes or back.) All instructions fit in a single word. All integers fit in a single word. Everything else is “pointed to” and all pointers fit in a single word. There is a run-time stack instead of a pile of registers. We could be generating code to load data into registers, …after a while it is almost as complex, but with registers there is always the possibility of running out. (New architectures with 128 registers or more make this unlikely but still something you have to program around). We will fortunately be able to ignore little/big endian issues.

3 Prof. Fateman CS 164 Lecture 283 Instructions: stack manipulation pushi x push immediate the constant x on the top of the stack used only for iconst. Same as iconst. e.g. (iconst 43) Only 24 bits for x(?). (larger consts in 2 steps??) pusha x push address. pushes the address of x on stack. e.g. pusha ="hello world“. We assume the assembler will find some place for x. Same as sconst. e.g. (sconst "hello") pop pops top of stack; value is lost dup pushes duplicate of top of stack

4 Prof. Fateman CS 164 Lecture 284 A simple call Let function f():int=3 in f() /*here */end How do we compile f() ? Set up a label L001 for location /*here*/. Save it on the stack. Push the address of F on the stack. Execute a (callj 0) to call F, a function of 0 args Execute an (args 0) /* some environment stuff.. See later */ Push 3 on the stack. the stack looks like L001 3 Execute a (return). Which jumps to L001, leaving 3 on the stack. (exit 0)

5 Prof. Fateman CS 164 Lecture 285 A simple call/ the program Let function f():int=3 in f() /*here */end (save L001) (lvar 1 0) // magic… get address of f on stack.. Details follow (callj 0) // call function of 0 args L001: // label to return to (exit 0) The program f looks like (args 0) // collect 0 arguments into environment.. Details follow (pushi 3) (return)

6 Prof. Fateman CS 164 Lecture 286 The Environment At any time there is an environment structure that is either the default global environment or the global environment augmented by some local bindings. Each function and each let-in-end has its own lexical level. If we have used the “transform-let-AST” program we have transformed the let- in-end into more levels, e.g. one level for each var, one level for each set of adjacent functions, (and perhaps for each set of type defs). The type defs do not change during run-time; if we store them at all, we certainly don’t look at them. A function F always has the same level, regardless of how many times it is called recursively.

7 Prof. Fateman CS 164 Lecture 287 The Environment, an example / let Let var x:=15 /* inside let */ function F(y:int,z:int):int= /* inside F*/ y+z in print(F(3,F(x,1))) end The environment inside let: An array (actually we will use a list) Level Contents 0 Global bindings e.g. [print, getchar, flush, ….] an array 1 [x]

8 Prof. Fateman CS 164 Lecture 288 The Environment, nested, let, F Let var x:=15 function F(y:int,z:int):int= /* inside */ y+z in print(F(3,F(x,1))) end The environment inside F: Level Contents 0 Global bindings e.g. [print, getchar, flush, ….] an array 1 [x] 2 [y, z]

9 Prof. Fateman CS 164 Lecture 289 The Environment, when the let happens Let var x:=15 function F(y:int,z:int):int= /* inside */ y+z in print(F(3,F(x,1))) end What steps must be executed? What do we compile? First we compute 15, the initial value for x, on the stack and then use the opcode (args 1) to create an array [15] and make this array part of the environment : (in other implementations we would allocate this “array” [15] on a stack, perhaps a different one from the arithmetic stack, perhaps the same… ). Level Contents 0 Global bindings 1 [15] /* [x] */

10 Prof. Fateman CS 164 Lecture 2810 The Environment, when a call happens Let var x:=15 function F(y:int,z:int):int= /* inside */ y+z in print(F(3,F(x,1))) /*here */ end To compile the call print(…) we make up a label L001 for location /*here*/ push it, and push print’s argument on the stack, push the address of the global function print on the stack, and do callj. HOLD IT. WE HAVE TO COMPUTE ARGUMENT TO PRINT.. Level Contents 0 Global bindings e.g. [print, getchar, flush, ….] an array 1 [15] /* [x] */ 2 [15, 1] /*[y, z] */

11 Prof. Fateman CS 164 Lecture 2811 The Environment, when a call happens Let var x:=15 function F(y:int,z:int):int= y+z in print(F(3,F(x,1)) /*here2*/ ) end To compile the call F(3,…), we make up a label for location /*here2*/ push 3 on the stack, and push the second argument to F, namely F(x,1) on the stack… how to do that?? If we could do that, then we would have on the stack 3 and 16… then we could execute the body of F to add them as below ENVIRONMENT B Level Contents 0 Global bindings e.g. [print, getchar, flush, ….] an array 1 [15] /* [x] */ 2 [ 3, 16 ] /*[y, z] */

12 Prof. Fateman CS 164 Lecture 2812 The Environment, what happened behind the scenes Let var x:=15 function F(y:int,z:int):int= /* inside */ y+z in print(F(3,F(x,1))) end To compile the call F(x,1), we copy the value of x from the let environment level 1 to the stack, and push 1 on. Run (args 2) to copy 2 items from stack into an array, and make this array part of the environment inside F: ENVIRONMENT A Level Contents 0 Global bindings e.g. [print, getchar, flush, ….] an array 1 [15] /* [x] */ 2 [ 15, 1] /*[y, z] */

13 Prof. Fateman CS 164 Lecture 2813 The Environment, What’s the relationship between ENVIRONMENTS A and B ENVIRONMENT A …. Call F(x,1) Level Contents 0 Global bindings e.g. [print, getchar, flush, ….] an array 1 [15] /* [x] */ 2 [ 15, 1] /*[y, z] */ ENVIRONMENT B … Call F(3, …) Level Contents 0 Global bindings e.g. [print, getchar, flush, ….] an array 1 [15] /* [x] */ 2 [ 3, 16 ] /*[y, z] */ Same levels, same contents, mostly. Just different entries for level 2. Could be a array of 3 pointers to [lev-0, lev-1, lev-2]. (args n) changes the highest-numbered of these levels.

14 Prof. Fateman CS 164 Lecture 2814 The Environment, inside function body F(x,1) Let var x:=1 function F(y:int,z:int):int= /* inside */ y+z in print(F(3,F(x,1))) end Level Contents 0 Global bindings e.g. [print, getchar, flush, ….] an array 1 [15] /* [x] */ 2 [15, 1] /*[y, z] */ To compute y+z we push on the run-time stack value at location level=2, position 0 (namely y with value 15), then level=2 position 1 (namely z with value 1) on the stack, then execute (+) leaving 16 on the top of the stack.

15 Prof. Fateman CS 164 Lecture 2815 The Environment, a return Recall that before we issued a (callj 2), we saved a return address (actually a TRIPLE..) when we are set with a return value, and the saved return address just ahead of it, we do a (return). What is this triple: the function body (an array in “binary program space” actually the lisp heap) the program counter inside that body that corresponds to the label we saved the environment in use at the time we saved the label. (The locally useful array that (args 2) allocated is GONE. If we had used a stack, we could just pop it off)

16 Prof. Fateman CS 164 Lecture 2816 Instructions: variable manipulation lvar i, j pushes the {jth variable’s value in the ith environment frame} on stack. If an int, value itself. If not an int, e.g. string, a pointer to the value in heap. lset i, j copies top of stack into lvar variable i j (does not pop stack) These refer to an environment… available at any time we are running Tiger Programs. Assume lexically we are n+1 levels deep. The Environment is list of arrays (could be an array, but complicates life..) Env[0]= array of all global bindings Env[1]= array of all bindings at level 1 … Env[n]= array of local bindings.

17 Prof. Fateman CS 164 Lecture 2817 Instructions: heap memory access mem use the top two elements of the stack to access a memory location. top of stack is an offset index. Second from top is an array origin. For example, an array reference foo[i] would be done by (pusha foo) (pushi i) (mem). Two items are popped off and result, value of foo[i] is put back on stack. smem (store to memory ) Use the top 3 elements of the stack to store into a memory structure such as an array or record. An array store foo[i]:=v would be done by pushing foo, pushing i, pushing v, then doing a smem. All three items are popped off. A record foo.subpart:=v is the same, where subpart is the ith subpart.

18 Prof. Fateman CS 164 Lecture 2818 Instructions: heap memory allocation alloc (allocate heap memory) Uses the top 2 elements of the stack. Push initial element value, then push number of elements. We ignore considerations of how large an element might be: each element is a reference to a value except in the case of an int, which might actually be that 32-bit int. Space is allocated on the heap, a space (in words) equal to the number on the top of the stack. Each element is initialized to (a pointer to...) the given value. Both stack positions are popped, and alloc leaves the address of the space on the top of the stack. If there is insufficient space, your Tiger dies. (we could of course do something else like check for zero as an address etc etc.)

19 Prof. Fateman CS 164 Lecture 2819 Instructions: jump, test jumpn label go to label if top of stack is non-zero that is, jump true; pop stack jumpz label go to label if top of stack is zero that is jump if false; pop stack The label must be in the same function as the jump. That is, neither of these can jump to a truly arbitrary place labeled in another function.

20 Prof. Fateman CS 164 Lecture 2820 Instructions: setting up for call, args We already used these… save loc: saves return address loc on the top of the stack. Actually this will have 3 components: function, program counter (pc) within the function of label, and the environment. (environment = pointer to heap). Ordinarily loc is label just after callj, the instruction to execute after the return. return Uses the top 2 items on the stack. Call the top V and next-to-top element S. V is the return value. The value of S is a saved location (actually a triple...)from save, above. The result of executing RETURN is: both S and V are popped off the stack. The function, program counter, and environment are all set from S, and V is pushed back on the stack. The environment at the point of the RETURN is lost (except insofar as it is shared with the SAVE environment.)

21 Prof. Fateman CS 164 Lecture 2821 Instructions: the call and collecting parameters callj n Take top of stack as function location. The next n items on the stack are the arguments to the function. Pops the function location off the stack and jumps to it. The called function removes the next n items using args. At the end of a procedure the result will be on the stack, and the saved return will be next on the stack. Return gets us back to the caller. args n Used only as the first instruction in a procedure foo, args n moves n arguments from stack to foo's environment. This means creating an array with n elements, replacing the nth level with it.

22 Prof. Fateman CS 164 Lecture 2822 Instructions: arithmetic asli n arithmetic shift left immediate. asli 2 multiplies top of stack by 4. (only use we make of it!) addi n add immediate. For example, addi 2 adds 2 to the top of stack. + * - / a collection of binary integer operators: For example (pushi 3)(pushi 4) (+)  7 on stack Since 3>4 is false. The order is important. In lisp: (apply op (second stack)(first stack)).

23 Prof. Fateman CS 164 Lecture 2823 Instructions: comparison A choice… should we add > = <= = a collection of binary integer operators: For example (pushi 3)(pushi 4) (>)  0 on stack Since 3>4 is false. The order is important. In lisp: (apply op (second stack)(first stack)). OR A>B could be (push A) (push B) (-) (jumpn FALSE_LABEL) (pushi 1) (jump OVER_label) FALSE_LABEL: (pushi 0) OVER_label

24 Prof. Fateman CS 164 Lecture 2824 Instructions: comparison Factors: Sometimes computing A-B lead to arithmetic overflow!! The code that is generated for if a>b then “hello” else “goodbye” from this sequence is really poor. Why not (push a) (push b) (-) (jumpn L01) (pusha “goodbye”) (jump L02) L01: (pusha “hello”) L02:

25 Prof. Fateman CS 164 Lecture 2825 Instructions: another kind of comparison The code that is generated for if a>b then “hello” else “goodbye” (push a) (push b) (COMPARE) //made up code.. (jump> L01) (pusha “goodbye”) (jump L02) L01: (pusha “hello”) L02:

26 Prof. Fateman CS 164 Lecture 2826 Instructions: string, other string> string = string<= a collection of binary string operators: The order is important. In lisp: (apply op (second stack)(first stack)). = <> Equal and not-equal should work on any operands including int, string, record, array. Knowing whether to use string> or > is important!

27 Prof. Fateman CS 164 Lecture 2827 Instructions: environment changing pushenv n Change the current environment by pushing a frame with n (empty) slots on the environment. Used by let and (pushenv 1) by for loop to make room for index. popenv remove the top frame on the stack. Used by exit from let. (does part of a return)

28 Prof. Fateman CS 164 Lecture 2828 Instructions: miscellaneous exit n Quits with code n I left this out.. I had it implemented as a call to the built-in function exit(j:int)

29 Prof. Fateman CS 164 Lecture 2829 Built-in functions of Tiger Print, ord, chr, getchar, flush, not, … are not part of the machine exactly, but are part of a suite of built-in functions known at runtime.


Download ppt "Prof. Fateman CS 164 Lecture 281 Virtual Machine Structure Lecture 28."

Similar presentations


Ads by Google