1 #ifndef SVALUE_H__
2 #define SVALUE_H__ 1
3
4 /*---------------------------------------------------------------------------
5 * Stack-value datatypes used by the virtual machine.
6 *
7 *---------------------------------------------------------------------------
8 * This file refers to, but does not define 'basic' types like mappings,
9 * arrays or lambdas.
10 */
11
12 #include "driver.h"
13 #include "typedefs.h"
14
15 /* --- Types --- */
16
17 /* --- union u: the hold-all type ---
18 *
19 * This union is used to hold the data referenced by a svalue.
20 * It contains no type information, which must be provided by the
21 * containing svalue.
22 *
23 * Lots of code assumes that '.number' is big enough to contain the whole
24 * union regardless of its actual content, therefore it is of type 'p_int'.
25 */
26 union u {
27 string_t *str;
28 /* T_STRING: pointer to the string.
29 * T_SYMBOL: pointer to the (shared) symbol string.
30 * T_(PROTECTED_)STRING_RANGE_LVALUE: the target string holding
31 * the range.
32 */
33 char *charp;
34 /* T_(PROTECTED_)CHAR_LVALUE: pointer to the referenced character
35 * (referenced from a T_LVALUE).
36 */
37 p_int number;
38 /* T_NUMBER: the number.
39 */
40 object_t *ob;
41 /* T_OBJECT: pointer to the object structure.
42 * T_CLOSURE: efun-, simul_efun-, operator closures: the object
43 * the closure is bound to.
44 */
45 vector_t *vec;
46 /* T_POINTER, T_QUOTED_ARRAY: pointer to the vector structure.
47 * T_(PROTECTED_)POINTER_RANGE_LVALUE: the target vector holding
48 * the range.
49 */
50 #ifdef USE_STRUCTS
51 struct_t *strct;
52 /* T_STRUCT: pointer to the structure instance.
53 */
54 #endif
55 mapping_t *map;
56 /* T_MAPPING: pointer to the mapping structure.
57 * T_PROTECTOR_MAPPING: TODO: ???
58 */
59 lambda_t *lambda;
60 /* T_CLOSURE: allocated closures: the closure structure.
61 */
62 p_int mantissa;
63 /* T_FLOAT: The mantissa (or at least one half of the float bitpattern).
64 */
65 callback_t *cb;
66 /* T_CALLBACK: A callback structure referenced from the stack
67 * to allow proper cleanup during error recoveries. The interpreter
68 * knows how to free it, but that's all.
69 */
70
71 void *generic;
72 /* Use read-only, this member is used to read the svalue generically
73 * as "a pointer". It is mostly used in comparisons.
74 */
75
76 svalue_t *lvalue;
77 /* T_LVALUE: pointer to a (usually 'normal') svalue which
78 * this lvalue references. Also, lvalues may be chained through
79 * this pointer so that only the last lvalue points to the real
80 * svalue, and the others point to the next lvalue in the chain.
81 * This is necessary when lvalues are passed around as lfun args.
82 *
83 * For T_LVALUE this may point to one of the protector
84 * structures (see interpret.c) which just 'happen' to have a svalue
85 * as first element. The actual type of the protected svalue is given
86 * by the .type of the referenced protector structure.
87 *
88 * When creating such a protected T_LVALUE, this .lvalue field is set
89 * by assigning one of the following aliases:
90 */
91 struct protected_lvalue *protected_lvalue;
92 struct protected_char_lvalue *protected_char_lvalue;
93 struct protected_range_lvalue *protected_range_lvalue;
94
95 /* The following fields are used only in svalues referenced by
96 * T_LVALUE svalues:
97 */
98 void (*error_handler) (svalue_t *);
99 /* T_ERROR_HANDLER: this function is
100 * executed on a free_svalue(), receiving the T_ERROR_HANDLER svalue*
101 * as argument. This allows the transparent implemention of cleanup
102 * functions which are called even after runtime errors. In order
103 * to pass additional information to the error_handler(), embed
104 * the T_ERROR_HANDLER svalue into a larger structure (possible since
105 * it has to be referenced by pointer) and let the error_handler()
106 * execute the appropriate casts.
107 */
108 };
109
110 /* --- struct svalue_s: the LPC data structure ---
111 *
112 * svalues ('stack values)' are used throughout the driver to hold LPC
113 * values. One svalue consists of an instance of union u to hold the
114 * actual value, and a type field describing the type of the value.
115 *
116 * Some values need specific, additional information (e.g. string values
117 * distinguish shared from allocated strings), which is stored in the
118 * union 'x'.
119 *
120 * The T_LVALUE type family is special in that the svalue instance does
121 * not contain the actual value, but instead a reference to another
122 * svalue. lvalues are necessary whenever existing svalue instance
123 * are to be assigned. A special case are protected lvalues where the
124 * svalue referenced by the T_LVALUE.u.lvalue is not the target svalue,
125 * but instead a T_PROTECTED_xxx_LVALUE which then points to the target
126 * and its protector. Similar, indexed and range-indexed lvalues don't
127 * point to the data itself, but instead to one of the dedicated T_xxx_LVALUE
128 * types which contain the necessary information to perform the indexing
129 * operation; effectively limiting the access to the target value to
130 * the view specified by the index/range bounds.
131 *
132 * T_LVALUEs are also used to reference meta data, like T_ERROR_HANDLER
133 * svalues. TODO: Maybe they should get the T_META type.
134 */
135 struct svalue_s
136 {
137 ph_int type; /* Primary type information */
138 union { /* Secondary type information */
139 ph_int exponent; /* Exponent of a T_FLOAT */
140 ph_int closure_type; /* Type of a T_CLOSURE */
141 ph_int quotes; /* Number of quotes of a quoted array or symbol */
142 ph_int num_arg; /* used by call_out.c to for vararg callouts */
143 ph_int extern_args; /* Callbacks: true if the argument memory was
144 * allocated externally */
145 ph_int generic;
146 /* For types without secondary type information, this is set to
147 * a fixed value, usually (u.number << 1).
148 * Also, this field is also used as generic 'secondary type field'
149 * handle, e.g. when comparing svalues.
150 */
151 } x;
152 union u u; /* The value */
153 };
154
155 #define SVALUE_FULLTYPE(svp) ((p_int *)(svp))
156 /* Return a pointer to an integer with the primary and secondary type
157 * information.
158 */
159 /* TODO: Sanity test: sizeof struct { ph_int, ph_int } <= sizeof p_int */
160
161
162 /* struct svalue_s.type: Primary types.
163 * There must be no more than 16 different primary types, as some
164 * type tables (prolang.y::hook_type_map[] for example) store
165 * them as bitflags in shorts.
166 * TODO: Create these constants, plus the names in
167 * TODO:: interpret.c::svalue_typename[] from a descriptive _spec file.
168 */
169
170 #define T_INVALID 0x0 /* empty svalue */
171 #define T_LVALUE 0x1 /* a lvalue */
172 #define T_NUMBER 0x2 /* an integer number */
173 #define T_STRING 0x3 /* a string */
174 #define T_POINTER 0x4 /* a vector */
175 #define T_OBJECT 0x5 /* an object */
176 #define T_MAPPING 0x6 /* a mapping */
177 #define T_FLOAT 0x7 /* a float number */
178 #define T_CLOSURE 0x8 /* a closure */
179 #define T_SYMBOL 0x9 /* a symbol */
180 #define T_QUOTED_ARRAY 0xa /* a quoted array */
181 #ifdef USE_STRUCTS
182 #define T_STRUCT 0xb /* a struct */
183 #endif /* USE_STRUCTS */
184
185 #define T_CHAR_LVALUE 0xc
186 /* .u.string points to the referenced character in a string */
187
188 /* The following types must be used only in svalues referenced
189 * by a T_LVALUE svalue.
190 */
191 #define T_STRING_RANGE_LVALUE 0x0d /* TODO: ??? */
192 #define T_POINTER_RANGE_LVALUE 0x0e /* TODO: ??? */
193 #define T_PROTECTED_CHAR_LVALUE 0x0f
194 /* A protected character lvalue */
195 #define T_PROTECTED_STRING_RANGE_LVALUE 0x10
196 /* A protected string range lvalue */
197 #define T_PROTECTED_POINTER_RANGE_LVALUE 0x11
198 /* A protected pointer/mapping range lvalue */
199 #define T_PROTECTED_LVALUE 0x12
200 /* A protected lvalue */
201 #define T_PROTECTOR_MAPPING 0x13 /* TODO: ??? */
202
203 #define T_CALLBACK 0x14
204 /* A callback structure referenced from the stack to allow
205 * proper cleanup during error recoveries. The interpreter
206 * knows how to free it, but that's all.
207 */
208
209 #define T_ERROR_HANDLER 0x15
210 /* Not an actual value, this is used internally for cleanup
211 * operations. See the description of the error_handler() member
212 * for details.
213 */
214
215 #define T_NULL 0x16
216 /* Not an actual type, this is used in the efun_lpc_types[] table
217 * to encode the acceptance of '0' instead of the real datatype.
218 */
219
220 #define T_MOD_SWAPPED 0x80
221 /* This flag is |-ed to the swapped-out type value if the value
222 * data has been swapped out.
223 */
224
225 /* T_CLOSURE secondary information. */
226
227 /* For closures of operators (internal machine codes), efuns and
228 * simul_efuns, the x.closure_type is a negative number defining
229 * which operator/efun/simul_efun to call.
230 * The values given here are just the limits of the usable number
231 * ranges.
232 * The relations are:
233 * Operator-closure index = CLOSURE_OPERATOR_OFFS + instruction index
234 * Efun-closure index = CLOSURE_EFUN_OFFS + instruction index
235 * Simul_efun index = CLOSURE_SIMUL_EFUN_OFFS + function index
236 * Yes, the operator range can be overlaid onto the efun range without
237 * collision, distinguishing them by the struct instr[].Default fields
238 * (the 'closure' instruction does that to save space), but this way they
239 * are easier to distinguish.
240 * TODO: Note: Some code interprets these values as unsigned shorts.
241 */
242
243 #define CLOSURE_OPERATOR (-0x1800) /* == 0xe800 */
244 #define CLOSURE_EFUN (-0x1000) /* == 0xf000 */
245 #define CLOSURE_SIMUL_EFUN (-0x0800) /* == 0xf800 */
246
247 #define CLOSURE_OPERATOR_OFFS (CLOSURE_OPERATOR & 0xffff)
248 #define CLOSURE_EFUN_OFFS (CLOSURE_EFUN & 0xffff)
249 #define CLOSURE_SIMUL_EFUN_OFFS (CLOSURE_SIMUL_EFUN & 0xffff)
250
251 /* The other closure types are created from actual objects and lambdas,
252 * the detailed information is stored in the u.lambda field.
253 * The first types are 'just' references to existing lfuns and variables,
254 * the others actually point to code.
255 */
256
257 #define CLOSURE_LFUN 0 /* lfun in an object */
258
259 /* Code 1 was used for ALIEN_LFUNs - some mudlibs however rely on the
260 * old code values.
261 */
262
263 #define CLOSURE_IDENTIFIER 2 /* variable in this object */
264
265 #define CLOSURE_PRELIMINARY 3
266 /* Efun closure used in a static initialization */
267
268 #define CLOSURE_BOUND_LAMBDA 4 /* Bound unbound-lambda closure */
269 #define CLOSURE_LAMBDA 5 /* normal lambda closure */
270 #define CLOSURE_UNBOUND_LAMBDA 6 /* unbound lambda closure. */
271
272
273 #define CLOSURE_IDENTIFIER_OFFS 0xe800
274 /* When creating lfun/variable closures, the lfun/variable to bind
275 * is given as unsigned number:
276 * number < C_I_OFFS: number is index into function table
277 * number >= C_I_OFFS: (number-C_I_OFFS) is index into variable table.
278 */
279
280 /* Predicates operating on T_CLOSURE secondary information */
281
282 #define CLOSURE_MALLOCED(c) ((c) >= 0)
283 /* TRUE if the closure was created at LPC runtime, ie is not an operator,
284 * efun or simul_efun.
285 */
286
287 #define CLOSURE_IS_LFUN(c) ((c) == CLOSURE_LFUN)
288 /* TRUE if the closure is of the #'<lfun> type.
289 */
290
291 #define CLOSURE_REFERENCES_CODE(c) ((c) > CLOSURE_PRELIMINARY)
292 /* TRUE if the closure may have or reference code.
293 */
294
295 #define CLOSURE_HAS_CODE(c) ((c) > CLOSURE_BOUND_LAMBDA)
296 /* TRUE if the closure points to actual code.
297 */
298
299 #define CLOSURE_CALLABLE(c) ((c) >= CLOSURE_EFUN && (c) <= CLOSURE_LAMBDA)
300 /* TRUE if the closure is callable.
301 */
302
303 /* --- The primary types in bit-flag encoding ---
304 *
305 * This flag encoding is used for the runtime typetests.
306 * Not all svalue types have a corresponding bitflag.
307 */
308
309 #define TF_INVALID (1 << T_INVALID)
310 #define TF_LVALUE (1 << T_LVALUE)
311 #define TF_NUMBER (1 << T_NUMBER)
312 #define TF_STRING (1 << T_STRING)
313 #define TF_POINTER (1 << T_POINTER)
314 #define TF_OBJECT (1 << T_OBJECT)
315 #define TF_MAPPING (1 << T_MAPPING)
316 #define TF_FLOAT (1 << T_FLOAT)
317 #define TF_CLOSURE (1 << T_CLOSURE)
318 #define TF_SYMBOL (1 << T_SYMBOL)
319 #define TF_QUOTED_ARRAY (1 << T_QUOTED_ARRAY)
320 #define TF_NULL (1 << T_NULL)
321 #ifdef USE_STRUCTS
322 #define TF_STRUCT (1 << T_STRUCT)
323 #endif /* USE_STRUCTS */
324
325 #define TF_ANYTYPE (~0)
326 /* This is used in the efun_lpc_types[]
327 * table to encode the acceptance of any type.
328 */
329
330 /* --- Float Support --- */
331
332 /* The driver uses a 48-Bit floating point format with a 32 bit mantissa
333 * and a 16 bit exponent, stored in u.mantissa and x.exponent. This should
334 * be well below all existing host floating point formats so that we get
335 * the same accuracy on all platforms.
336 *
337 * To keep the implementation transparent, the following macros/functions are
338 * defined:
339 *
340 * int FLOAT_FORMAT:
341 * 0 for the portable format, 1 for the fast format.
342 * Additional numbers may be defined for more formats.
343 *
344 * double READ_DOUBLE(struct svalue * sp)
345 * Return the floating point number stored in *sp.
346 *
347 * long SPLIT_DOUBLE (double d, int * p)
348 * Store the bytes 4..5 of <d> to the address given in <p>, and
349 * return the bytes 0..3 of <d> as a long.
350 * Used by the compiler to generate F_FLOAT instructions.
351 * TODO: This code makes heave assumptions about data sizes and layout
352 * TODO:: of integral types.
353 *
354 * unknown STORE_DOUBLE (struct svalue * dest, double d)
355 * Store the float <d> into the svalue *dest.
356 *
357 * STORE_DOUBLE_USED
358 * Declaration of a local variable which STORE_DOUBLE needs.
359 */
360
361
362 /* --- The portable format, used if no other format is defined */
363
364 #ifndef STORE_DOUBLE
365
366 #define FLOAT_FORMAT_0
367
READ_DOUBLE(svalue_t * sv)368 static INLINE double READ_DOUBLE(svalue_t *sv) {
369 return ldexp( (double)(sv->u.mantissa), sv->x.exponent - 31 );
370 }
371 /* if your machine doesn't use the exponent to designate powers of two,
372 the use of ldexp in SPLIT_DOUBLE won't work; you'll have to multiply
373 with 32768. in this case */
374
SPLIT_DOUBLE(double doublevalue,int * int_p)375 static INLINE p_int SPLIT_DOUBLE(double doublevalue, int *int_p) {
376 return (p_int)ldexp( frexp( doublevalue, int_p ), 31);
377 }
378
379 // STORE_DOUBLE_USED is not needed anymore and defined empty.
380 #define STORE_DOUBLE_USED
STORE_DOUBLE(svalue_t * dest,double doublevalue)381 static INLINE void STORE_DOUBLE(svalue_t *dest, double doublevalue) {
382 int exponent;
383 dest->u.mantissa = SPLIT_DOUBLE(doublevalue, &exponent);
384 dest->x.exponent = (ph_int)exponent;
385 }
386
387 #endif /* ifndef STORE_DOUBLE */
388
389 /* --- svalue macros --- */
390
391 #define addref_closure(sp, from) \
392 MACRO( svalue_t * p = sp; \
393 if (CLOSURE_MALLOCED(p->x.closure_type)) \
394 p->u.lambda->ref++; \
395 else \
396 (void)ref_object(p->u.ob, from); \
397 )
398 /* void addref_closure(sp, from): Add one ref to the closure svalue <sp>
399 * in the function <from>.
400 */
401
402
403 /* void put_<type>(sp, value): Initialise svalue *sp with value of <type>.
404 * 'sp' is evaluated several times and must point to an otherwise
405 * empty svalue. If <value> is a refcounted value, its refcount is
406 * NOT incremented.
407 *
408 * void put_ref_<type>(sp, value): Initialise svalue *sp with value
409 * of <type>. 'sp' is evaluated several times and must point to an
410 * otherwise empty svalue. <value> must be a refcounted value, and
411 * its refcount is incremented.
412 *
413 * void push_<type>(), void push_ref_<type>()
414 * As the put_() macros, but <sp> is incremented once first.
415 *
416 * As a rule, all arguments must not have sideeffects!
417 *
418 * The psh_ macros are not in use (yet) - they have been renamed from push_
419 * so that the first use stands out.
420 *
421 * TODO: Add push_xxx() macros, see MudOS:interpret.h. In general, get
422 * TODO:: rid of the local sp/pc copies since they make error handling
423 * TODO:: very difficult.
424 * TODO: Also add 'adopt_<type>()' and 'pop_<type>()'macros, e.g.
425 * TODO:: 'adopt_object(sp)', which
426 * TODO:: retrieve the type from the *sp and set sp->type to T_INVALID.
427 */
428
429 #define put_number(sp,num) \
430 ( (sp)->type = T_NUMBER, (sp)->u.number = (num) )
431
432 #define put_float(sp,fnum) \
433 do { STORE_DOUBLE_USED; (sp)->type = T_FLOAT; STORE_DOUBLE((sp), fnum); }while(0)
434
435 #define put_ref_array(sp,arr) \
436 ( (sp)->type = T_POINTER, (sp)->u.vec = ref_array(arr) )
437 #define put_array(sp,arr) \
438 ( (sp)->type = T_POINTER, (sp)->u.vec = arr )
439
440 #ifdef USE_STRUCTS
441 #define put_ref_struct(sp,st) \
442 ( (sp)->type = T_STRUCT, (sp)->u.strct = ref_struct(st) )
443 #define put_struct(sp,st) \
444 ( (sp)->type = T_STRUCT, (sp)->u.strct = st )
445 #endif /* USE_STRUCTS */
446
447 #define put_ref_mapping(sp,val) \
448 ( (sp)->type = T_MAPPING, (sp)->u.map = ref_mapping(val) )
449 #define put_mapping(sp,val) \
450 ( (sp)->type = T_MAPPING, (sp)->u.map = val )
451
452 #define put_ref_object(sp,val,from) \
453 ( (sp)->type = T_OBJECT, (sp)->u.ob = ref_object(val, from) )
454 #define put_object(sp,val) \
455 ( (sp)->type = T_OBJECT, (sp)->u.ob = val )
456
457 #define put_ref_valid_object(sp,val,from) \
458 ( ((val) && !((val)->flags & O_DESTRUCTED)) \
459 ? (put_ref_object(sp,val,from), 0) : put_number(sp, 0))
460
461 #define put_valid_object(sp,val) \
462 ( ((val) && !((val)->flags & O_DESTRUCTED)) \
463 ? (put_object(sp,val), 0) : put_number(sp, 0))
464
465 #define put_ref_string(sp,val) \
466 ( (sp)->type = T_STRING, (sp)->u.str = ref_mstring(val) )
467 #define put_string(sp,val) \
468 ( (sp)->type = T_STRING, (sp)->u.str = val )
469
470 #define put_callback(sp,val) \
471 ( (sp)->type = T_CALLBACK, (sp)->u.cb = val )
472
473 #define push_number(sp,num) \
474 ( (sp)++, put_number(sp, num) )
475
476 #define push_float(sp,fnum) \
477 ( (sp)++, put_float(sp, fnum) )
478
479 #define push_ref_array(sp,arr) \
480 ( (sp)++, put_ref_array(sp, arr) )
481 #define push_array(sp,arr) \
482 ( (sp)++, put_array(sp, arr) )
483
484 #ifdef USE_STRUCTS
485 #define push_ref_struct(sp,st) \
486 ( (sp)++, put_ref_struct(sp, st) )
487 #define push_struct(sp,st) \
488 ( (sp)++, put_struct(sp, st) )
489 #endif /* USE_STRUCTS */
490
491 #define psh_ref_mapping(sp,val) \
492 ( (sp)++, put_ref_mapping(sp,val) )
493 #define push_mapping(sp,val) \
494 ( (sp)++, put_mapping(sp,val) )
495
496 #define push_ref_object(sp,val,from) \
497 ( (sp)++, put_ref_object(sp,val,from) )
498 #define push_object(sp,val) \
499 ( (sp)++, put_object(sp,val) )
500
501 #define push_ref_valid_object(sp,val,from) \
502 ( (sp)++, put_ref_valid_object(sp,val,from) )
503 #define push_valid_object(sp,val) \
504 ( (sp)++, put_valid_object(sp,val) )
505
506 #define push_ref_string(sp,val) \
507 ( (sp)++, put_ref_string(sp,val) )
508 #define push_string(sp,val) \
509 ( (sp)++, put_string(sp,val) )
510 #define push_c_string(sp,txt) \
511 ( (sp)++, put_c_string(sp, txt) )
512 #define push_c_n_string(sp,txt,len) \
513 ( (sp)++, put_c_n_string(sp, txt, len) )
514
515
516 #define psh_callback(sp,val) \
517 ( (sp)++, put_callback(sp,val) )
518
519 /* The following macros implement the dynamic cost evaluations:
520 *
521 * DYN_STRING_COST(l): increase eval_cost depending on string length <l>.
522 * DYN_ARRAY_COST(l): increase eval_cost depending on array length <l>.
523 * DYN_MAPPING_COST(l): increase eval_cost depending on mapping length <l>.
524 *
525 * Covered so far are:
526 * F_ALLOCATE, F_ADD, F_ADD_EQ, F_VOID_ADD_EQ, F_MULTIPLY,
527 * F_MULT_EQ of strings
528 *
529 * TODO: Expand this to all datatypes and sizes.
530 */
531
532 #if defined(DYNAMIC_COSTS)
533
534 #define DYN_STRING_COST(l) eval_cost += (l) / 1000;
535 #define DYN_ARRAY_COST(l) eval_cost += (l) / 1000;
536 #define DYN_MAPPING_COST(l) eval_cost += (l) / 1000;
537
538 #else
539
540 #define DYN_STRING_COST(l)
541 #define DYN_ARRAY_COST(l)
542 #define DYN_MAPPING_COST(l)
543
544 #endif
545
546 /* --- Prototypes (in interpret.c) --- */
547
548 extern void free_string_svalue(svalue_t *v);
549 extern void free_object_svalue(svalue_t *v);
550 extern void zero_object_svalue(svalue_t *v);
551 extern void free_svalue(svalue_t *v);
552 extern void assign_svalue_no_free(svalue_t *to, svalue_t *from);
553 extern void assign_svalue(svalue_t *dest, svalue_t *v);
554 extern void transfer_svalue_no_free(svalue_t *dest, svalue_t *v);
555 extern void transfer_svalue(svalue_t *dest, svalue_t *v);
556 extern svalue_t *pop_n_elems (int n, svalue_t *sp);
557
558 #endif /* SVALUE_H__ */
559