]> gitweb.factorcode.org Git - factor.git/blob - vm/arrays.cpp
moved reallot_array into vm
[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 array *allot_array(cell capacity, cell fill_)
27 {
28         return vm->allot_array(capacity,fill_);
29 }
30
31 /* push a new array on the stack */
32 inline void factorvm::vmprim_array()
33 {
34         cell initial = dpop();
35         cell size = unbox_array_size();
36         dpush(tag<array>(allot_array(size,initial)));
37 }
38
39 PRIMITIVE(array)
40 {
41         PRIMITIVE_GETVM()->vmprim_array();
42 }
43
44 cell factorvm::allot_array_1(cell obj_)
45 {
46         gc_root<object> obj(obj_,this);
47         gc_root<array> a(allot_array_internal<array>(1),this);
48         set_array_nth(a.untagged(),0,obj.value());
49         return a.value();
50 }
51
52 cell allot_array_1(cell obj_)
53 {
54         return vm->allot_array_1(obj_);
55 }
56
57 cell factorvm::allot_array_2(cell v1_, cell v2_)
58 {
59         gc_root<object> v1(v1_,this);
60         gc_root<object> v2(v2_,this);
61         gc_root<array> a(allot_array_internal<array>(2),this);
62         set_array_nth(a.untagged(),0,v1.value());
63         set_array_nth(a.untagged(),1,v2.value());
64         return a.value();
65 }
66
67 cell allot_array_2(cell v1_, cell v2_)
68 {
69         return vm->allot_array_2(v1_,v2_);
70 }
71
72 cell factorvm::allot_array_4(cell v1_, cell v2_, cell v3_, cell v4_)
73 {
74         gc_root<object> v1(v1_,this);
75         gc_root<object> v2(v2_,this);
76         gc_root<object> v3(v3_,this);
77         gc_root<object> v4(v4_,this);
78         gc_root<array> a(allot_array_internal<array>(4),this);
79         set_array_nth(a.untagged(),0,v1.value());
80         set_array_nth(a.untagged(),1,v2.value());
81         set_array_nth(a.untagged(),2,v3.value());
82         set_array_nth(a.untagged(),3,v4.value());
83         return a.value();
84 }
85
86 cell allot_array_4(cell v1_, cell v2_, cell v3_, cell v4_)
87 {
88         return vm->allot_array_4(v1_,v2_,v3_,v4_);
89 }
90
91 inline void factorvm::vmprim_resize_array()
92 {
93         array* a = untag_check<array>(dpop());
94         cell capacity = unbox_array_size();
95         dpush(tag<array>(reallot_array(a,capacity)));
96 }
97
98 PRIMITIVE(resize_array)
99 {
100         PRIMITIVE_GETVM()->vmprim_resize_array();
101 }
102
103 void growable_array::add(cell elt_)
104 {
105         factorvm* myvm = elements.myvm;
106         gc_root<object> elt(elt_,myvm);
107         if(count == array_capacity(elements.untagged()))
108                 elements = myvm->reallot_array(elements.untagged(),count * 2);
109
110         set_array_nth(elements.untagged(),count++,elt.value());
111 }
112
113 void growable_array::trim()
114 {
115         factorvm *myvm = elements.myvm;
116         elements = myvm->reallot_array(elements.untagged(),count);
117 }
118
119 }