cfad47cfa3/tads3/vmlst.h

4b825dc642cb6eb9a060e54bf8d69288fbee4904cfad47cfa334b206c65f22086bcc5d63e6f70944
1
/* $Header: d:/cvsroot/tads/tads3/VMLST.H,v 1.2 1999/05/17 02:52:28 MJRoberts Exp $ */
2
3
/* 
4
 *   Copyright (c) 1998, 2002 Michael J. Roberts.  All Rights Reserved.
5
 *   
6
 *   Please see the accompanying license file, LICENSE.TXT, for information
7
 *   on using and copying this software.  
8
 */
9
/*
10
Name
11
  vmlst.h - VM dynamic list implementation
12
Function
13
  
14
Notes
15
  
16
Modified
17
  10/29/98 MJRoberts  - Creation
18
*/
19
20
#ifndef VMLST_H
21
#define VMLST_H
22
23
#include <stdlib.h>
24
#include "vmtype.h"
25
#include "vmobj.h"
26
#include "vmcoll.h"
27
#include "vmglob.h"
28
#include "vmstack.h"
29
30
31
class CVmObjList: public CVmObjCollection
32
{
33
    friend class CVmMetaclassList;
34
35
public:
36
    /* metaclass registration object */
37
    static class CVmMetaclass *metaclass_reg_;
38
    class CVmMetaclass *get_metaclass_reg() const { return metaclass_reg_; }
39
40
    /* am I of the given metaclass? */
41
    virtual int is_of_metaclass(class CVmMetaclass *meta) const
42
    {
43
        /* try my own metaclass and my base class */
44
        return (meta == metaclass_reg_
45
                || CVmObjCollection::is_of_metaclass(meta));
46
    }
47
48
    /* create dynamically using stack arguments */
49
    static vm_obj_id_t create_from_stack(VMG_ const uchar **pc_ptr,
50
                                         uint argc);
51
52
    /* 
53
     *   Create dynamically from parameters in the stack; we do not remove
54
     *   the elements from the stack, but simply create a list from the
55
     *   parameters.  'idx' is the parameter index of the first parameter,
56
     *   and 'cnt' is the number of parameters to use.  
57
     */
58
    static vm_obj_id_t create_from_params(VMG_ uint idx, uint cnt);
59
60
    /* 
61
     *   call a static property - we don't have any of our own, so simply
62
     *   "inherit" the base class handling 
63
     */
64
    static int call_stat_prop(VMG_ vm_val_t *result,
65
                              const uchar **pc_ptr, uint *argc,
66
                              vm_prop_id_t prop)
67
    {
68
        return CVmObjCollection::
69
            call_stat_prop(vmg_ result, pc_ptr, argc, prop);
70
    }
71
72
    /* reserve constant data */
73
    virtual void reserve_const_data(VMG_ class CVmConstMapper *mapper,
74
                                    vm_obj_id_t self);
75
76
    /* convert to constant data */
77
    virtual void convert_to_const_data(VMG_ class CVmConstMapper *mapper,
78
                                       vm_obj_id_t self);
79
80
    /* get my datatype when converted to constant data */
81
    virtual vm_datatype_t get_convert_to_const_data_type() const
82
      { return VM_LIST; }
83
84
    /* create a list with no initial contents */
85
    static vm_obj_id_t create(VMG_ int in_root_set);
86
87
    /* 
88
     *   create a list with a given number of elements, for construction
89
     *   of the list element-by-element 
90
     */
91
    static vm_obj_id_t create(VMG_ int in_root_set, size_t element_count);
92
93
    /* 
94
     *   create a list from a constant list, for construction of the list
95
     *   as a modified copy of an original list 
96
     */
97
    static vm_obj_id_t create(VMG_ int in_root_set, const char *lst);
98
99
    /*
100
     *   List construction: set an element.  List contents are immutable,
101
     *   so they cannot be changed after the list is constructed.
102
     *   However, it is often convenient to construct a list one element
103
     *   at a time, so a caller can create the list with the appropriate
104
     *   number of elements, then use this routine to set each element of
105
     *   the list individually.
106
     *   
107
     *   idx is the index of the element in the list; the first element is
108
     *   at index zero.  Note that this routine does *not* allocate
109
     *   memory; the list must be pre-allocated to its full number of
110
     *   elements.
111
     */
112
    void cons_set_element(size_t idx, const vm_val_t *val);
113
114
    /* update the list in place so that each value is unique */
115
    void cons_uniquify(VMG0_);
116
117
    /* 
118
     *   Copy an existing list into our list, starting at a given index.  The
119
     *   caller must ensure that our list buffer is large enough to
120
     *   accommodate the new elements.  The 'orig_list' value must point to a
121
     *   standard list constant value: a UINT2 element count prefix followed
122
     *   by DATAHOLDER elements.  
123
     */
124
    void cons_copy_elements(size_t start_idx, const char *orig_list);
125
126
    /*
127
     *   Copy existing list elements into our list, starting at the given
128
     *   index.  The caller must ensure that our list buffer is large enough
129
     *   to accommodate the new elements.  The 'ele_array' is an array of
130
     *   DATAHOLDER values.  
131
     */
132
    void cons_copy_data(size_t start_idx, const char *ele_array,
133
                        size_t ele_count);
134
135
    /*
136
     *   Set the length of the list.  This can be used when constructing a
137
     *   list, and the actual number of elements is unknown before
138
     *   construction is complete (however, the maximum number of elements
139
     *   must be known in advance, since this merely sets the length, and
140
     *   does NOT reallocate the list -- hence, this call can only be used
141
     *   to shrink the list below its allocated size, never to expand it).
142
     */
143
    void cons_set_len(size_t len)
144
        { vmb_put_len(ext_, len); }
145
146
    /* notify of deletion */
147
    void notify_delete(VMG_ int in_root_set);
148
149
    /* set a property */
150
    void set_prop(VMG_ class CVmUndo *undo,
151
                  vm_obj_id_t self, vm_prop_id_t prop, const vm_val_t *val);
152
153
    /* get a property */
154
    int get_prop(VMG_ vm_prop_id_t prop, vm_val_t *val,
155
                 vm_obj_id_t self, vm_obj_id_t *source_obj, uint *argc);
156
157
    /* undo operations - lists are immutable and hence keep no undo */
158
    void notify_new_savept() { }
159
    void apply_undo(VMG_ struct CVmUndoRecord *) { }
160
    void mark_undo_ref(VMG_ struct CVmUndoRecord *) { }
161
    void remove_stale_undo_weak_ref(VMG_ struct CVmUndoRecord *) { }    
162
163
    /* mark references */
164
    void mark_refs(VMG_ uint state);
165
166
    /* 
167
     *   remove weak references - we keep only normal (strong) references,
168
     *   so this routine doesn't need to do anything 
169
     */
170
    void remove_stale_weak_refs(VMG0_) { }
171
172
    /* load from an image file */
173
    void load_from_image(VMG_ vm_obj_id_t, const char *ptr, size_t)
174
        { ext_ = (char *)ptr; }
175
176
    /* rebuild for image file */
177
    virtual ulong rebuild_image(VMG_ char *buf, ulong buflen);
178
179
    /* save to a file */
180
    void save_to_file(VMG_ class CVmFile *fp);
181
182
    /* restore from a file */
183
    void restore_from_file(VMG_ vm_obj_id_t self,
184
                           class CVmFile *fp, class CVmObjFixup *fixups);
185
186
    /* 
187
     *   Add a value to the list.  If the value to add is a list (constant
188
     *   or object), we'll append each element of the list to this list;
189
     *   otherwise, we'll just append the value itself to the list.  In
190
     *   any case, we don't modify this list itself, but create a new list
191
     *   object to hold the result.
192
     */
193
    void add_val(VMG_ vm_val_t *result,
194
                 vm_obj_id_t self, const vm_val_t *val);
195
196
    /*
197
     *   Index the list 
198
     */
199
    void index_val(VMG_ vm_val_t *result, vm_obj_id_t self,
200
                   const vm_val_t *index_val);
201
202
    /*
203
     *   Set an indexed element of the list.  Since the contents of a list
204
     *   object cannot be changed, we'll return in *new_container a new
205
     *   list object that we create with the modified contents.  
206
     */
207
    void set_index_val(VMG_ vm_val_t *new_container, vm_obj_id_t self,
208
                       const vm_val_t *index_val, const vm_val_t *new_val);
209
210
    /* 
211
     *   Subtract a value from the list.  This creates a new list with the
212
     *   element matching the given value removed from the original list.
213
     *   We do not modify the original list; instead, we create a new list
214
     *   object with the new value.  
215
     */
216
    void sub_val(VMG_ vm_val_t *result,
217
                 vm_obj_id_t self, const vm_val_t *val);
218
219
    /* 
220
     *   get as a list - simply return our extension, which is in the
221
     *   required portable list format 
222
     */
223
    const char *get_as_list() const { return ext_; }
224
225
    /* 
226
     *   Check a value for equality.  We will match any constant list that
227
     *   contains the same data as our list, and any other list object
228
     *   with the same underlying data.  
229
     */
230
    int equals(VMG_ vm_obj_id_t self, const vm_val_t *val, int depth) const;
231
232
    /*
233
     *   Static list adder.  This creates a new list object that results
234
     *   from appending the given value to the given list constant.  This
235
     *   is defined statically so that this code can be shared for adding
236
     *   to constant pool lists and adding to CVmObjList objects.
237
     *   
238
     *   'lstval' must point to a constant list.  The first two bytes of
239
     *   the list are stored in portable UINT2 format and give the number
240
     *   of elements in the list; this is immediately followed by a packed
241
     *   array of data holders in portable format.  
242
     */
243
    static void add_to_list(VMG_ vm_val_t *result,
244
                            vm_obj_id_t self, const char *lstval,
245
                            const vm_val_t *val);
246
247
    /*
248
     *   Static list subtraction routine. This creates a new list object
249
     *   that results from removing the given value from the list
250
     *   constant.  This is defined statically so that this code can be
251
     *   shared for subtracting from constant pool lists and subtracting
252
     *   from CVmObjList objects.
253
     *   
254
     *   'lstmem' must point to a constant list in the same format as
255
     *   required for add_to_list.  If 'lstmem' comes from the constant
256
     *   pool, then 'lstval' must be provided to give us the constant pool
257
     *   address; otherwise, 'lstval' should be null.  
258
     */
259
    static void sub_from_list(VMG_ vm_val_t *result,
260
                              const vm_val_t *lstval, const char *lstmem,
261
                              const vm_val_t *val);
262
263
    /*
264
     *   Constant list comparison routine.  Compares the given list
265
     *   constant (in portable format, with leading UINT2 element count
266
     *   prefix followed by the list's elements in portable data holder
267
     *   format) to the other value.  Returns true if the other value is a
268
     *   list constant or object whose contents match the list constant,
269
     *   false if not.
270
     *   
271
     *   If 'lstmem' comes from the constant pool, then 'lstval' must be
272
     *   provided to give us the constant pool address; otherwise,
273
     *   'lstval' should be null.  
274
     */
275
    static int const_equals(VMG_ const vm_val_t *lstval, const char *lstmem,
276
                            const vm_val_t *val, int depth);
277
278
    /*
279
     *   Calculate a hash value for the list 
280
     */
281
    uint calc_hash(VMG_ vm_obj_id_t self, int depth) const;
282
283
    /*
284
     *   Constant list hash value calculation
285
     */
286
    static uint const_calc_hash(VMG_ const vm_val_t *self_val,
287
                                const char *lst, int depth);
288
289
    /*
290
     *   When we're the right-hand side of a '+' or '-' operation whose
291
     *   left-hand side is another collection type that treats these
292
     *   operators as concatenation/set subtraction, add/subtract our
293
     *   elements individually.  
294
     */
295
    size_t get_coll_addsub_rhs_ele_cnt(VMG0_) const
296
        { return vmb_get_len(ext_); }
297
    void get_coll_addsub_rhs_ele(VMG_ vm_val_t *result,
298
                                 vm_obj_id_t self, size_t idx)
299
        { index_list(vmg_ result, ext_, idx); }
300
301
    /*
302
     *   Constant list indexing routine.  Indexes the given constant list
303
     *   (which must be in portable format, with leading UINT2 element
304
     *   count followed by the list's elements in portable data holder
305
     *   format), looking up the value at the index number given by the
306
     *   index value, and puts the result in *result. 
307
     */
308
    static void index_list(VMG_ vm_val_t *result,
309
                           const char *lst, const vm_val_t *index_val);
310
311
    /* index a list, using a 1-based index */
312
    static void index_list(VMG_ vm_val_t *result, const char *lst, uint idx);
313
314
    /* push the indexed element, using a 1-based index */
315
    static void index_and_push(VMG_ const char *lst, uint idx)
316
    {
317
        vm_val_t *p;
318
319
        /* push a new stack element */
320
        p = G_stk->push();
321
322
        /* index the list and store the value directly in the stack */
323
        index_list(vmg_ p, lst, idx);
324
    }
325
326
    /*
327
     *   Constant list set-index routine.  Creates a new list object as a
328
     *   copy of this list, with the element at the given index set to the
329
     *   given new value. 
330
     */
331
    static void set_index_list(VMG_ vm_val_t *result,
332
                               const char *lst, const vm_val_t *index_val,
333
                               const vm_val_t *new_val);
334
335
    /*
336
     *   Find a value within a list.  If we find the value, we'll set
337
     *   *idxp to the index (starting at zero for the first element) of
338
     *   the item we found, and we'll return true; if we don't find the
339
     *   value, we'll return false.  
340
     */
341
    static int find_in_list(VMG_ const vm_val_t *lst,
342
                            const vm_val_t *val, size_t *idxp);
343
344
    /* find the last match for a value */
345
    static int find_last_in_list(VMG_ const vm_val_t *lst,
346
                                 const vm_val_t *val, size_t *idxp);
347
348
    /*
349
     *   Evaluate a property of a constant list value.  Returns true if we
350
     *   successfully evaluated the property, false if the property is not
351
     *   one of the properties that the list class defines.  
352
     */
353
    static int const_get_prop(VMG_ vm_val_t *retval, const vm_val_t *self_val,
354
                              const char *lst, vm_prop_id_t prop, 
355
                              vm_obj_id_t *srcobj, uint *argc);
356
357
    /* property evaluator - undefined property */
358
    static int getp_undef(VMG_ vm_val_t *, const vm_val_t *,
359
                          const char *, uint *)
360
        { return FALSE; }
361
362
    /* property evaluator - select a subset through a callback */
363
    static int getp_subset(VMG_ vm_val_t *retval, const vm_val_t *self_val,
364
                           const char *lst, uint *argc);
365
366
    /* property evaluator - apply a callback to each element */
367
    static int getp_map(VMG_ vm_val_t *retval, const vm_val_t *self_val,
368
                        const char *lst, uint *argc);
369
370
    /* get the length */
371
    static int getp_len(VMG_ vm_val_t *retval, const vm_val_t *self_val,
372
                        const char *lst, uint *argc);
373
374
    /* sublist */
375
    static int getp_sublist(VMG_ vm_val_t *retval, const vm_val_t *self_val,
376
                            const char *lst, uint *argc);
377
378
    /* intersect */
379
    static int getp_intersect(VMG_ vm_val_t *retval,
380
                              const vm_val_t *self_val,
381
                              const char *lst, uint *argc);
382
383
    /* indexOf */
384
    static int getp_index_of(VMG_ vm_val_t *retval, const vm_val_t *self_val,
385
                             const char *lst, uint *argc);
386
387
    /* car */
388
    static int getp_car(VMG_ vm_val_t *retval, const vm_val_t *self_val,
389
                        const char *lst, uint *argc);
390
391
    /* cdr */
392
    static int getp_cdr(VMG_ vm_val_t *retval, const vm_val_t *self_val,
393
                        const char *lst, uint *argc);
394
395
    /* indexWhich */
396
    static int getp_index_which(VMG_ vm_val_t *retval,
397
                                const vm_val_t *self_val,
398
                                const char *lst, uint *argc);
399
400
    /* forEach */
401
    static int getp_for_each(VMG_ vm_val_t *retval, const vm_val_t *self_val,
402
                             const char *lst, uint *argc);
403
404
    /* forEachAssoc */
405
    static int getp_for_each_assoc(VMG_ vm_val_t *retval,
406
                                   const vm_val_t *self_val,
407
                                   const char *lst, uint *argc);
408
409
    /* valWhich */
410
    static int getp_val_which(VMG_ vm_val_t *retval,
411
                              const vm_val_t *self_val,
412
                              const char *lst, uint *argc);
413
414
    /* lastIndexOf */
415
    static int getp_last_index_of(VMG_ vm_val_t *retval,
416
                                  const vm_val_t *self_val,
417
                                  const char *lst, uint *argc);
418
419
    /* lastIndexWhich */
420
    static int getp_last_index_which(VMG_ vm_val_t *retval,
421
                                     const vm_val_t *self_val,
422
                                     const char *lst, uint *argc);
423
424
    /* lastValWhich */
425
    static int getp_last_val_which(VMG_ vm_val_t *retval,
426
                                   const vm_val_t *self_val,
427
                                   const char *lst, uint *argc);
428
429
    /* countOf */
430
    static int getp_count_of(VMG_ vm_val_t *retval,
431
                             const vm_val_t *self_val,
432
                             const char *lst, uint *argc);
433
434
    /* countWhich */
435
    static int getp_count_which(VMG_ vm_val_t *retval,
436
                                const vm_val_t *self_val,
437
                                const char *lst, uint *argc);
438
439
    /* general routine for indexWhich and lastIndexWhich */
440
    static int gen_index_which(VMG_ vm_val_t *retval,
441
                               const vm_val_t *self_val,
442
                               const char *lst, uint *argc,
443
                               int forward);
444
445
    /* getUnique */
446
    static int getp_get_unique(VMG_ vm_val_t *retval,
447
                               const vm_val_t *self_val,
448
                               const char *lst, uint *argc);
449
450
    /* appendUnique */
451
    static int getp_append_unique(VMG_ vm_val_t *retval,
452
                                  const vm_val_t *self_val,
453
                                  const char *lst, uint *argc);
454
455
    /* append */
456
    static int getp_append(VMG_ vm_val_t *retval,
457
                           const vm_val_t *self_val,
458
                           const char *lst, uint *argc);
459
460
    /* sort */
461
    static int getp_sort(VMG_ vm_val_t *retval,
462
                         const vm_val_t *self_val,
463
                         const char *lst, uint *argc);
464
465
    /* insertAt */
466
    static int getp_insert_at(VMG_ vm_val_t *retval,
467
                              const vm_val_t *self_val,
468
                              const char *lst, uint *argc);
469
470
    /* prepend */
471
    static int getp_prepend(VMG_ vm_val_t *retval,
472
                            const vm_val_t *self_val,
473
                            const char *lst, uint *argc);
474
475
    /* property evaluator - remove a single element at a given index */
476
    static int getp_remove_element_at(VMG_ vm_val_t *retval,
477
                                      const vm_val_t *self_val,
478
                                      const char *lst, uint *argc);
479
480
    /* property evaluator - removeRange */
481
    static int getp_remove_range(VMG_ vm_val_t *retval,
482
                                 const vm_val_t *self_val,
483
                                 const char *lst, uint *argc);
484
485
protected:
486
    /* general processor for forEach and forEachAssoc */
487
    static int for_each_gen(VMG_ vm_val_t *retval,
488
                            const vm_val_t *self_val,
489
                            const char *lst, uint *argc,
490
                            int send_idx_to_cb);
491
492
    /*
493
     *   Compute the intersection of two lists.  Returns a new list with the
494
     *   elements that occur in both lists.  
495
     */
496
    static vm_obj_id_t intersect(VMG_ const vm_val_t *lst1,
497
                                 const vm_val_t *lst2);
498
499
    /* insert the arguments into the list at the given index */
500
    static void insert_elements(VMG_ vm_val_t *retval,
501
                                const vm_val_t *self_val,
502
                                const char *lst, uint argc, int idx);
503
504
    /* remove elements */
505
    static void remove_range(VMG_ vm_val_t *retval,
506
                             const vm_val_t *self_val,
507
                             const char *lst, int start_idx, int del_cnt);
508
509
    /* create an iterator */
510
    virtual void new_iterator(VMG_ vm_val_t *retval,
511
                              const vm_val_t *self_val);
512
513
    /* 
514
     *   create a live iterator - for a list, there is no difference
515
     *   between snapshot and live iterators, since a list is immutable 
516
     */
517
    virtual void new_live_iterator(VMG_ vm_val_t *retval,
518
                                   const vm_val_t *self_val)
519
        { new_iterator(vmg_ retval, self_val); }
520
521
    /* get the number of elements in the list */
522
    size_t get_ele_count() const { return vmb_get_len(ext_); }
523
524
    /* get an element, given a zero-based index */
525
    void get_element(size_t idx, vm_val_t *val) const
526
    {
527
        /* get the data from the data holder in our extension */
528
        vmb_get_dh(get_element_ptr(idx), val);
529
    }
530
531
    /* get the number of elements in a constant list */
532
    static size_t get_ele_count_const(const char *lstval)
533
        { return vmb_get_len(lstval); }
534
535
    /* get an element from a constant list, given a zero-based index */
536
    static void get_element_const(const char *lstval, size_t idx,
537
                                  vm_val_t *val)
538
    {
539
        /* get the data from the data holder in the constant list */
540
        vmb_get_dh(get_element_ptr_const(lstval, idx), val);
541
    }
542
543
    /* given an index, get a pointer to the element's data in the list */
544
    char *get_element_ptr(size_t idx) const
545
    {
546
        /* 
547
         *   figure out where this element's data holder is by skipping
548
         *   the count prefix, then skipping past preceding data holders 
549
         */
550
        return ext_ + VMB_LEN + (idx * VMB_DATAHOLDER);
551
    }
552
553
    /* 
554
     *   given an index, and a pointer to a constant list, get a pointer
555
     *   to the element's data in the list constant 
556
     */
557
    static const char *get_element_ptr_const(const char *lstval, size_t idx)
558
    {
559
        /* 
560
         *   figure out where this element's data holder is by skipping
561
         *   the count prefix, then skipping past preceding data holders 
562
         */
563
        return lstval + VMB_LEN + (idx * VMB_DATAHOLDER);
564
    }
565
566
    /* 
567
     *   given a pointer to a list element, increment the pointer so that
568
     *   it points to the next element 
569
     */
570
    static void inc_element_ptr(char **p)
571
    {
572
        /* add the size of a data holder to the current pointer */
573
        *p += VMB_DATAHOLDER;
574
    }
575
576
    /* increment a constant element pointer */
577
    static void inc_const_element_ptr(const char **p)
578
    {
579
        /* add the size of a data holder to the current pointer */
580
        *p += VMB_DATAHOLDER;
581
    }
582
583
    /* create a list with no initial contents */
584
    CVmObjList() { ext_ = 0; }
585
    
586
    /* 
587
     *   create a list with a given number of elements, for construction
588
     *   of the list element-by-element 
589
     */
590
    CVmObjList(VMG_ size_t element_count);
591
    
592
    /* create a list from a constant list */
593
    CVmObjList(VMG_ const char *lst);
594
595
    /*
596
     *   Calculate the amount of space we need to store a list of a given
597
     *   length.  We require two bytes for the length prefix, plus the
598
     *   space for each element.
599
     */
600
    static size_t calc_alloc(size_t elecnt)
601
        { return (VMB_LEN + (elecnt * VMB_DATAHOLDER)); }
602
603
    /* allocate space for the list, given the number of elements */
604
    void alloc_list(VMG_ size_t element_count);
605
606
    /* property evaluation function table */
607
    static int (*func_table_[])(VMG_ vm_val_t *retval,
608
                                const vm_val_t *self_val,
609
                                const char *lst, uint *argc);
610
};
611
612
613
/* ------------------------------------------------------------------------ */
614
/*
615
 *   A constant list is exactly like an ordinary list, except that our
616
 *   contents come from the constant pool.  We store a pointer directly to
617
 *   our constant pool data rather than making a separate copy.  The only
618
 *   thing we have to do differently from an ordinary list is that we don't
619
 *   delete our extension when we're deleted, since our extension is really
620
 *   just a pointer into the constant pool.  
621
 */
622
class CVmObjListConst: public CVmObjList
623
{
624
public:
625
    /* notify of deletion */
626
    void notify_delete(VMG_ int /*in_root_set*/)
627
    {
628
        /* 
629
         *   do nothing, since our extension is just a pointer into the
630
         *   constant pool 
631
         */
632
    }
633
634
    /* create from constant pool data */
635
    static vm_obj_id_t create(VMG_ const char *const_ptr);
636
637
protected:
638
    /* construct from constant pool data */
639
    CVmObjListConst(VMG_ const char *const_ptr)
640
    {
641
        /* point our extension directly to the constant pool data */
642
        ext_ = (char *)const_ptr;
643
    }
644
};
645
646
/* ------------------------------------------------------------------------ */
647
/*
648
 *   Registration table object 
649
 */
650
class CVmMetaclassList: public CVmMetaclass
651
{
652
public:
653
    /* get the global name */
654
    const char *get_meta_name() const { return "list/030007"; }
655
656
    /* create from image file */
657
    void create_for_image_load(VMG_ vm_obj_id_t id)
658
    {
659
        new (vmg_ id) CVmObjList();
660
        G_obj_table->set_obj_gc_characteristics(id, TRUE, FALSE);
661
    }
662
663
    /* create from restoring from saved state */
664
    void create_for_restore(VMG_ vm_obj_id_t id)
665
    {
666
        new (vmg_ id) CVmObjList();
667
        G_obj_table->set_obj_gc_characteristics(id, TRUE, FALSE);
668
    }
669
670
    /* create dynamically using stack arguments */
671
    vm_obj_id_t create_from_stack(VMG_ const uchar **pc_ptr, uint argc)
672
        { return CVmObjList::create_from_stack(vmg_ pc_ptr, argc); }
673
674
    /* call a static property */
675
    int call_stat_prop(VMG_ vm_val_t *result,
676
                       const uchar **pc_ptr, uint *argc,
677
                       vm_prop_id_t prop)
678
    {
679
        return CVmObjList::call_stat_prop(vmg_ result, pc_ptr, argc, prop);
680
    }
681
682
    /* I'm a Collection object */
683
    CVmMetaclass *get_supermeta_reg() const
684
        { return CVmObjCollection::metaclass_reg_; }
685
};
686
687
#endif /* VMLST_H */
688
689
/*
690
 *   Register the class 
691
 */
692
VM_REGISTER_METACLASS(CVmObjList)
693