3 CELL string_nth(F_STRING* string, CELL index)
5 /* If high bit is set, the most significant 16 bits of the char
6 come from the aux vector. The least significant bit of the
7 corresponding aux vector entry is negated, so that we can
8 XOR the two components together and get the original code point
10 CELL ch = bget(SREF(string,index));
15 F_BYTE_ARRAY *aux = untag_byte_array_fast(string->aux);
16 return (cget(BREF(aux,index * sizeof(u16))) << 7) ^ ch;
20 void set_string_nth_fast(F_STRING *string, CELL index, CELL ch)
22 bput(SREF(string,index),ch);
25 void set_string_nth_slow(F_STRING *string_, CELL index, CELL ch)
27 gc_root<F_STRING> string(string_);
31 bput(SREF(string.untagged(),index),(ch & 0x7f) | 0x80);
35 /* We don't need to pre-initialize the
36 byte array with any data, since we
37 only ever read from the aux vector
38 if the most significant bit of a
39 character is set. Initially all of
40 the bits are clear. */
41 aux = allot_array_internal<F_BYTE_ARRAY>(
42 untag_fixnum_fast(string->length)
45 write_barrier(string.value());
46 string->aux = tag_object(aux);
49 aux = untag_byte_array_fast(string->aux);
51 cput(BREF(aux,index * sizeof(u16)),(ch >> 7) ^ 1);
54 /* allocates memory */
55 void set_string_nth(F_STRING* string, CELL index, CELL ch)
58 set_string_nth_fast(string,index,ch);
60 set_string_nth_slow(string,index,ch);
63 /* Allocates memory */
64 F_STRING *allot_string_internal(CELL capacity)
66 F_STRING *string = allot<F_STRING>(string_size(capacity));
68 string->length = tag_fixnum(capacity);
75 /* Allocates memory */
76 void fill_string(F_STRING *string_, CELL start, CELL capacity, CELL fill)
78 gc_root<F_STRING> string(string_);
81 memset((void *)SREF(string.untagged(),start),fill,capacity - start);
86 for(i = start; i < capacity; i++)
87 set_string_nth(string.untagged(),i,fill);
91 /* Allocates memory */
92 F_STRING *allot_string(CELL capacity, CELL fill)
94 gc_root<F_STRING> string(allot_string_internal(capacity));
95 fill_string(string.untagged(),0,capacity,fill);
96 return string.untagged();
99 void primitive_string(void)
101 CELL initial = to_cell(dpop());
102 CELL length = unbox_array_size();
103 dpush(tag_object(allot_string(length,initial)));
106 static bool reallot_string_in_place_p(F_STRING *string, CELL capacity)
108 return in_zone(&nursery,(CELL)string) && capacity <= string_capacity(string);
111 F_STRING* reallot_string(F_STRING *string_, CELL capacity)
113 gc_root<F_STRING> string(string_);
115 if(reallot_string_in_place_p(string.untagged(),capacity))
117 string->length = tag_fixnum(capacity);
121 F_BYTE_ARRAY *aux = untag_byte_array_fast(string->aux);
122 aux->capacity = tag_fixnum(capacity * 2);
125 return string.untagged();
129 CELL to_copy = string_capacity(string.untagged());
130 if(capacity < to_copy)
133 gc_root<F_STRING> new_string(allot_string_internal(capacity));
135 memcpy(new_string.untagged() + 1,string.untagged() + 1,to_copy);
139 F_BYTE_ARRAY *new_aux = allot_byte_array(capacity * sizeof(u16));
141 write_barrier(new_string.value());
142 new_string->aux = tag_object(new_aux);
144 F_BYTE_ARRAY *aux = untag_byte_array_fast(string->aux);
145 memcpy(new_aux + 1,aux + 1,to_copy * sizeof(u16));
148 fill_string(new_string.untagged(),to_copy,capacity,'\0');
149 return new_string.untagged();
153 void primitive_resize_string(void)
155 F_STRING* string = untag_string(dpop());
156 CELL capacity = unbox_array_size();
157 dpush(tag_object(reallot_string(string,capacity)));
160 void primitive_string_nth(void)
162 F_STRING *string = untag_string_fast(dpop());
163 CELL index = untag_fixnum_fast(dpop());
164 dpush(tag_fixnum(string_nth(string,index)));
167 void primitive_set_string_nth(void)
169 F_STRING *string = untag_string_fast(dpop());
170 CELL index = untag_fixnum_fast(dpop());
171 CELL value = untag_fixnum_fast(dpop());
172 set_string_nth(string,index,value);
175 void primitive_set_string_nth_fast(void)
177 F_STRING *string = untag_string_fast(dpop());
178 CELL index = untag_fixnum_fast(dpop());
179 CELL value = untag_fixnum_fast(dpop());
180 set_string_nth_fast(string,index,value);
183 void primitive_set_string_nth_slow(void)
185 F_STRING *string = untag_string_fast(dpop());
186 CELL index = untag_fixnum_fast(dpop());
187 CELL value = untag_fixnum_fast(dpop());
188 set_string_nth_slow(string,index,value);