]> gitweb.factorcode.org Git - factor.git/blob - vm/arrays.cpp
renamed vmprim_ to primitive_
[factor.git] / vm / arrays.cpp
1 #include "master.hpp"
2
3 namespace factor
4 {
5
6 /* make a new array with an initial element */
7 array *factorvm::allot_array(cell capacity, cell fill_)
8 {
9         gc_root<object> fill(fill_,this);
10         gc_root<array> new_array(allot_array_internal<array>(capacity),this);
11
12         if(fill.value() == tag_fixnum(0))
13                 memset(new_array->data(),'\0',capacity * sizeof(cell));
14         else
15         {
16                 /* No need for write barrier here. Either the object is in
17                 the nursery, or it was allocated directly in tenured space
18                 and the write barrier is already hit for us in that case. */
19                 cell i;
20                 for(i = 0; i < capacity; i++)
21                         new_array->data()[i] = fill.value();
22         }
23         return new_array.untagged();
24 }
25
26
27 /* push a new array on the stack */
28 inline void factorvm::primitive_array()
29 {
30         cell initial = dpop();
31         cell size = unbox_array_size();
32         dpush(tag<array>(allot_array(size,initial)));
33 }
34
35 PRIMITIVE(array)
36 {
37         PRIMITIVE_GETVM()->primitive_array();
38 }
39
40 cell factorvm::allot_array_1(cell obj_)
41 {
42         gc_root<object> obj(obj_,this);
43         gc_root<array> a(allot_array_internal<array>(1),this);
44         set_array_nth(a.untagged(),0,obj.value());
45         return a.value();
46 }
47
48
49 cell factorvm::allot_array_2(cell v1_, cell v2_)
50 {
51         gc_root<object> v1(v1_,this);
52         gc_root<object> v2(v2_,this);
53         gc_root<array> a(allot_array_internal<array>(2),this);
54         set_array_nth(a.untagged(),0,v1.value());
55         set_array_nth(a.untagged(),1,v2.value());
56         return a.value();
57 }
58
59
60 cell factorvm::allot_array_4(cell v1_, cell v2_, cell v3_, cell v4_)
61 {
62         gc_root<object> v1(v1_,this);
63         gc_root<object> v2(v2_,this);
64         gc_root<object> v3(v3_,this);
65         gc_root<object> v4(v4_,this);
66         gc_root<array> a(allot_array_internal<array>(4),this);
67         set_array_nth(a.untagged(),0,v1.value());
68         set_array_nth(a.untagged(),1,v2.value());
69         set_array_nth(a.untagged(),2,v3.value());
70         set_array_nth(a.untagged(),3,v4.value());
71         return a.value();
72 }
73
74
75 inline void factorvm::primitive_resize_array()
76 {
77         array* a = untag_check<array>(dpop());
78         cell capacity = unbox_array_size();
79         dpush(tag<array>(reallot_array(a,capacity)));
80 }
81
82 PRIMITIVE(resize_array)
83 {
84         PRIMITIVE_GETVM()->primitive_resize_array();
85 }
86
87 void growable_array::add(cell elt_)
88 {
89         factorvm* myvm = elements.myvm;
90         gc_root<object> elt(elt_,myvm);
91         if(count == array_capacity(elements.untagged()))
92                 elements = myvm->reallot_array(elements.untagged(),count * 2);
93
94         myvm->set_array_nth(elements.untagged(),count++,elt.value());
95 }
96
97 void growable_array::trim()
98 {
99         factorvm *myvm = elements.myvm;
100         elements = myvm->reallot_array(elements.untagged(),count);
101 }
102
103 }