; Problem Set 8 ; This file contains the material given in the lecture. It then concludes with ; some questions. Note: You can't turn this into a certifiable book without ; commenting out a lot of the illustrative evaluations used in the lecture! (include-book "keytuples") (in-package "M5") ; Below are five defkeytuple commands, defining ; state ; thread ; frame ; class ; method ; After each I illustrate some sample uses of the keytuple functions. ; I'll discuss these examples in class. ; An M5 state will be a keytuple consisting of a ; item name value ; thread table :tt list of threads ; heap :hp binding environment binding references to objects ; class table :ct list of classes (defkeytuple state (:tt :hp :ct)) ; These are bogus values of the fields. (make state :hp 2 :tt 1 :ct 3) (get :hp (make state :hp 2 :tt 1 :ct 3)) (get :tt (make state :hp 2 :tt 1 :ct 3)) (get :xx (make state :hp 2 :tt 1 :ct 3)) (put :hp 22 (make state :hp 2 :tt 1 :ct 3)) ; An M5 thread contains ; item name value ; thread identifier :id natural number ; call stack :cs push down stack of frames ; status :stat symbol ; heap reference :ref reference to object in heap (defkeytuple thread (:id :cs :stat :ref)) (make thread :id 1 :cs '(frame1-2 frame1-1 frame1-0) :stat 'active :ref '(REF 1)) ; A thread table (tt) in a state is just a list of threads. Here is a list of threads. (list (make thread :id 1 :cs '(frame1-2 frame1-1 frame1-0) :stat 'active :ref '(REF 1)) (make thread :id 2 :cs '(frame2-2 frame2-1 frame2-0) :stat 'active :ref '(REF 2)) (make thread :id 3 :cs '(frame3-2 frame3-1 frame3-0) :stat 'active :ref '(REF 3))) ; We manipulate lists of keytuples with find and replace. (find :id 2 (list (make thread :id 1 :cs '(frame1-2 frame1-1 frame1-0) :stat 'active :ref '(REF 1)) (make thread :id 2 :cs '(frame2-2 frame2-1 frame2-0) :stat 'active :ref '(REF 2)) (make thread :id 3 :cs '(frame3-2 frame3-1 frame3-0) :stat 'active :ref '(REF 3)))) (replace :id 2 (make thread :id 2 :cs '(NEW-FRAME frame2-2 frame2-1 frame2-0) :stat 'active :ref '(REF 2)) (list (make thread :id 1 :cs '(frame1-2 frame1-1 frame1-0) :stat 'active :ref '(REF 1)) (make thread :id 2 :cs '(frame2-2 frame2-1 frame2-0) :stat 'active :ref '(REF 2)) (make thread :id 3 :cs '(frame3-2 frame3-1 frame3-0) :stat 'active :ref '(REF 3)))) ; An M5 frame is a keytuple containing a ; item name value ; program counter :pc natural number ; local variables :locs list of primitive values or references ; operand stack :stk push down stack of primitive values or references ; method pointer :mloc pointer to a specific method in the class table ; It may also contain an ignored field named ; next instruction next-inst the inst indicated by the pc (defkeytuple frame (:pc :locs :stk :mloc) :allow-but-ignore (:next-inst)) (make frame :pc 0 :locs '(0 1 2) :stk nil :mloc '("Math" "main" 2)) (make frame :pc 0 :locs '(0 1 2) :stk nil :mloc '("Math" "main" 2) :next-inst '(ILOAD 1)) ; A class is a keytuple containing ; item name value ; class name :name name of class (a string) ; superclasses :supers list (in ascending order) of superclasses ; instance fields :fields list of fields (list of strings) ; methods :methods list of method descriptors (see below) (defkeytuple class (:name :supers :fields :methods)) ; A method descriptor is a keytuple containing ; item name value ; method name :name a string ; method formals :formals list of symbols ; synchronized flg :sync Boolean indicating whether this is a sync'd method ; bytecode :code list of instructions ; exception table :xtbl exception table (defkeytuple method (:name :formals :sync :code :xtbl)) ; Here then is the shape of a state and a brief explanation of how each ; component of each keytuple is used. #| (make STATE :TT (list ... ; thread table (list of threads) (make THREAD ; thread :ID id ; thread identifier (natp) :CS (list ... ; call stack (stack of frames) (make FRAME ; frame :PC pc ; program counter (natp) :LOCS locs ; local variable values :STK stk ; operand stack :MLOC mloc) ; method locator ...) :STAT stat ; status (ACTIVE or INACTIVE) :REF ref) ; reference to "Thread" Object in heap ...) :HP hp ; heap (binding environment mapping ; addresses to Objects) :CT (list ; class table (list of classes) ... (make CLASS ; class :NAME name ; name (string) :SUPERS supers ; proper superclasses (list of strings) :FIELDS fields ; fields (list of strings) :METHODS (list ; methods (list of method objects) ... (make METHOD ; method :NAME name ; name (string) :FORMALS formals ; formals (list of symbols) :SYNC sync ; synchronized flag (boolean) :CODE code ; code (list of instructions) :XTBL xtbl) ; exception table ...)) ...)) |# ; ----------------------------------------------------------------- ; Threads ; The :TT (``thread table'') component of a state is a list of thread ; keytuples. Every thread has a :CS (``call stack''), which is a stack (list) ; of frame keytuples. The topmost frame in a thread's call stack is called its ; ``top frame'' and is the frmae of the most recently invoked method. The ; frame immediately below it invoked that one, etc. ; In the following you may assume that id is a thread identifier for some ; thread in the thread table of state s. ; Problem 8-1: Define the function cst so that it takes a thread identifier, ; id, for some thread in the thread table of state, s, and it takes s, and it ; returns the call stack of the indicated thread. ; In the future I will just write a problem of this sort as follows: ; (cst id s) ; returns the call stack of the indicated thread provided id is a thread ; identifier in the thread table of state s. ; Problem 8-2: ; (top-frame id s) ; returns the topmost frame of the call stack of the indicated thread ; under the same restrictions on id and s as in cst. ; ----------------------------------------------------------------- ; Objects ; Every class keytuple in the class table contains the name of the class ; (:NAME), the list of the names of the proper super classes (:SUPERS), and the ; list of immediate instance field names (:FIELDS). All these names are ; strings. The super classes are listed in order, from most specific to least; ; thus, "Object" is always the last element of every :SUPERS except one. ; Problem 8-3: ; Which class is the exception just mentioned? ; Java Objects are represented as doubly nested binding environments. At the ; top level, each successive class name in the superclass hierarchy is bound to ; a binding environment which specifies the values for the immediate fields of ; the corresponding class. For example, suppose class "Beta" extends "Alpha" ; which extends "Object". Suppose the fields of "Beta", "Alpha" and "Object" ; are, respectively, "b1", ..., "bb", "a1", ..., "aa", and "o1", ..., "oo". ; Then the representation of an instance of an Object of class "Beta" is: ; (("Beta" (("b1" vb1) ... ("bb" vbb))) ; immediate data for "Beta" ; ("Alpha" (("a1" va1) ... ("aa" vaa))) ; immediate data for "Alpha" ; ("Object" (("o1" vo1) ... ("oo" voo)))) ; immediate data for "Object" ; The vxx are the values of the corresponding fields. ; Define the following functions. In the following, you may assume that ; class-name is a class name in the class table ct and that field-name is the ; name of one of the immediate instance fields of class-name. In addition, obj ; is the representation of a Java object as above. ; Problem 8-4: ; (super-classes class-name ct) ; return the super-class chain of class-name, starting with class-name and ; ending with "Object". ; Problem 8-5: ; (new-object class-name ct) ; build an Object of class class-name. All fields should be (un-)initialized, meaning ; their values should all be 0. ; Problem 8-6: ; (instanceofp obj class-name) ; return t or nil to indicate whether obj is an instance of class-name ; Problem 8-7: ; (getf class-name field-name obj) ; return the value of the immediate field field-name of class-name in obj. ; You may assume obj is an instance of class-name. ; Problem 8-8: ; (putf class-name field-name value obj) ; "modify" obj so that the immediate field field-name of class-name in obj has ; value value. You may assume obj is an instance of class-name. Of course, ; you cannot actually modify obj. Technically, you should return a new object ; with the same superclass chain as obj in which all the fields are set as in ; obj except for the immediate field field-name of class-name, which should be ; set to value. ; Problem 8-9: ; (extendsp class-name1 class-name2 ct) ; return t or nil to indicate whether class-name1 extends class-name2. Both ; may be assumed to be class names in class table ct.