245
edits
m (Forgot to close correctly the fixed width text tags) |
(I had a little slip and forgot the rest of the section) |
||
Line 106: | Line 106: | ||
====Local variable segments==== | ====Local variable segments==== | ||
This section contains the script’s local variable segment, which consists of a sequence of 16 bit little-endian values. | This section contains the script’s local variable segment, which consists of a sequence of 16 bit little-endian values. | ||
==Selectors== | |||
Selectors are very important in SCI. They can be either methods or object/class-relative variables, and this makes the interpretation of SCI operations like <tt>send</tt> a bit tricky. | |||
Each class comes with two two-dimensional tables. The first table contains selector values and selector indices4 for each variable selector. The second table contains selector indices and script-relative method offsets. Objects look nearly identical, but they do not contain the list of selector indices for variable selectors, since those can be looked up at the class they were instantiated from (their ”species”, which happens to be one of the variable selectors). | |||
Now, whenever a selector is sent for, the engine has to determine the right action to take. FreeSCI first determines whether the selector is a variable selector, by looking for it in the list of variable selector indices of the species class of the object that the ”<tt>send</tt>” was sent to (classes use their own class number<ref>Those can be used as an index into <tt>vocab.997</tt>, where the selector names are stored as strings.</ref> as their species class).<ref>In practice, send looks up the heap position of the requested class in a global class table.</ref> If it is, the selector value is either read (if no parameter was provided to the send call) or set (if one parameter was provided). If the selector was not part of the variable selectors of the specified object, the object’s methods are checked for this selector index. If they don’t contain the selector index, either, then FreeSCI recurses into checking the method selectors of the object’s superclasses. If it finds the selector value there, it calls the heap address corresponding to the selector index. | |||
==Function invocation== | |||
SCI provides three distinct ways for invocating a function<ref>Of course, ”manual” invocation (using push and jump operations) could also be used, but there are no special provisions for it, and it does not appear to be used in the existing SCI bytecode.</ref>: Calling exported functions (<tt>calle</tt>, <tt>callb</tt>) Calling selector methods (<tt>send</tt>, <tt>self</tt>, <tt>super</tt>) Calling PC-relative addresses (<tt>call</tt>) Exported functions are called by providing a script number and an exported function number (which is then looked up in the script’s Type 7 block). They use the object they were called from to look up local variables and selectors for self and super. | |||
Selector methods are called by providing an object and a selector index. The selector index gets looked up in the object’s selector tables, and, if it is used for a method, this method gets invocated. The provided object is used for local references. | |||
PC-relative calls only make sense inside scripts, since they jump to a position relative to the call opcode. The calling object is used for local references. | |||
==Variable types== | |||
SCI bytecode can address four types of variables (not counting the variable selectors). Those variable types are: | |||
;Local variables | |||
:These are the variables stored in Type 10 script blocks. They are shared between the objects and classes of each script. | |||
;Global variables | |||
:These variables are the local variables of script 0. | |||
;Temporary variables | |||
:Those variables are stored on the stack. They are relative to the stack frame of the current method, so space for them must be allocated before they can be used. This is commonly done by using the <tt>link</tt> operation. | |||
;Parameters | |||
:Parameters are stored on the stack below the current stack frame, as they technically belong to the calling function. They can be modified, if necessary.<ref>Obviously, SCI uses a call-by-value model for primitives and call-by-reference for objects.</ref> |
edits