2 * Regular Pattern Analyzer (RPA)
3 * Copyright (c) 2009-2010 Martin Stoilov
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 * Martin Stoilov <martin@rpasearch.com>
21 #include "rlib/rmem.h"
22 #include "rvm/rvmreg.h"
23 #include "rlib/rref.h"
27 * Recursively go over array data to unref any GC managed
28 * objects. We need this because when GC is destroying arrays,
29 * array's oncleanup might try to destroy the data, that should really
30 * be destroyed by the GC. To avoid any attempts the same data
31 * to be destroyed twice we remove the references of all GC managed
32 * data from the arrays and leave the destruction of such data to
35 void rvm_reg_array_unref_gcdata(robject_t *obj)
37 unsigned long i, size;
40 if (obj->type == R_OBJECT_ARRAY) {
41 rarray_t *array = (rarray_t*)obj;
42 if ((size = r_array_length(array)) > 0) {
44 * set the size to 0, to prevent circular references to come back here
46 r_array_setlength(array, 0);
47 for (i = 0; i < size; i++) {
48 r = (rvmreg_t*) r_array_slot(array, i);
49 if (rvm_reg_tstflag(r, RVM_INFOBIT_ROBJECT)) {
50 robject_t *p = RVM_REG_GETP(r);
51 if (!r_list_empty(&p->lnk)) {
53 * if this entry is robject_t that is on GC
54 * list, it can be RVM_REG_CLEARed. It will be
55 * cleaned up by the GC.
57 rvm_reg_array_unref_gcdata(p);
66 r_array_setlength(array, size);
68 } else if (obj->type == R_OBJECT_CARRAY || obj->type == R_OBJECT_HARRAY) {
69 rcarray_t *array = (rcarray_t*)obj;
70 if (obj->type == R_OBJECT_HARRAY)
71 array = ((rharray_t*)obj)->members;
72 if ((size = r_carray_length(array)) > 0) {
74 * set the size to 0, to prevent circular references to come back here
76 array->alloc_size = 0;
77 for (i = 0; i < size; i++) {
78 r = (rvmreg_t*) r_carray_slot(array, i);
79 if (rvm_reg_tstflag(r, RVM_INFOBIT_ROBJECT)) {
80 robject_t *p = RVM_REG_GETP(r);
81 if (!r_list_empty(&p->lnk)) {
83 * if this entry is robject_t that is on GC
84 * list, it can be RVM_REG_CLEARed. It will be
85 * cleaned up by the GC.
87 rvm_reg_array_unref_gcdata(p);
96 array->alloc_size = size;
102 rvmreg_t rvm_reg_create_string_ansi(const char *s)
105 r_memset(&r, 0, sizeof(r));
106 RVM_REG_SETP(&r, r_string_create_from_ansistr(s));
107 RVM_REG_SETTYPE(&r, RVM_DTYPE_STRING);
108 RVM_REG_SETFLAG(&r, RVM_INFOBIT_ROBJECT);
113 rvmreg_t rvm_reg_create_string(const rstr_t *s)
116 r_memset(&r, 0, sizeof(r));
117 RVM_REG_SETP(&r, r_string_create_from_rstr(s));
118 RVM_REG_SETTYPE(&r, RVM_DTYPE_STRING);
119 RVM_REG_SETFLAG(&r, RVM_INFOBIT_ROBJECT);
124 void rvm_reg_setstring(rvmreg_t *r, rstring_t *ptr)
126 r_memset(r, 0, sizeof(*r));
127 RVM_REG_SETP(r, ptr);
128 RVM_REG_SETTYPE(r, RVM_DTYPE_STRING);
129 RVM_REG_SETFLAG(r, RVM_INFOBIT_ROBJECT);
133 void rvm_reg_setpair(rvmreg_t *r, ruint32 p1, ruint32 p2)
135 r_memset(r, 0, sizeof(*r));
136 RVM_REG_SETPAIR(r, p1, p2);
137 RVM_REG_SETTYPE(r, RVM_DTYPE_PAIR);
141 void rvm_reg_setstrptr(rvmreg_t *r, char *s, unsigned int size)
143 r_memset(r, 0, sizeof(*r));
144 RVM_REG_SETSTR(r, s, size);
145 RVM_REG_SETTYPE(r, RVM_DTYPE_STRPTR);
149 void rvm_reg_setarray(rvmreg_t *r, robject_t *ptr)
151 r_memset(r, 0, sizeof(*r));
152 RVM_REG_SETP(r, ptr);
153 RVM_REG_SETTYPE(r, RVM_DTYPE_ARRAY);
154 RVM_REG_SETFLAG(r, RVM_INFOBIT_ROBJECT);
158 void rvm_reg_setmap(rvmreg_t *r, robject_t *ptr)
160 r_memset(r, 0, sizeof(*r));
161 RVM_REG_SETP(r, ptr);
162 RVM_REG_SETTYPE(r, RVM_DTYPE_MAP);
163 RVM_REG_SETFLAG(r, RVM_INFOBIT_ROBJECT);
167 void rvm_reg_setjsobject(rvmreg_t *r, robject_t *ptr)
169 rvm_reg_setmap(r, ptr);
173 void rvm_reg_setharray(rvmreg_t *r, robject_t *ptr)
175 r_memset(r, 0, sizeof(*r));
176 RVM_REG_SETP(r, ptr);
177 RVM_REG_SETTYPE(r, RVM_DTYPE_HARRAY);
178 RVM_REG_SETFLAG(r, RVM_INFOBIT_ROBJECT);
182 void rvm_reg_setswi(rvmreg_t *r, ruword swiid)
184 r_memset(r, 0, sizeof(*r));
185 RVM_REG_SETU(r, swiid);
186 RVM_REG_SETTYPE(r, RVM_DTYPE_SWIID);
190 rvmreg_t rvm_reg_create_swi(ruword swiid)
193 rvm_reg_setswi(&r, swiid);
198 rvmreg_t rvm_reg_create_pair(ruint32 p1, ruint32 p2)
201 rvm_reg_setpair(&r, p1, p2);
206 rvmreg_t rvm_reg_create_strptr(char *s, unsigned int size)
209 rvm_reg_setstrptr(&r, s, size);
214 rvmreg_t rvm_reg_create_double(double d)
217 rvm_reg_setdouble(&r, d);
222 rvmreg_t rvm_reg_create_signed(rword l)
225 rvm_reg_setsigned(&r, l);
230 rvmreg_t rvm_reg_create_pointer(rpointer p)
233 rvm_reg_setpointer(&r, p);
238 rvmreg_t rvm_reg_create_ophandler(rpointer p)
241 rvm_reg_setophandler(&r, p);
246 rvmreg_t rvm_reg_create_prophandler(rpointer p)
249 rvm_reg_setprophandler(&r, p);
254 void rvm_reg_cleanup(rvmreg_t *reg)
260 void rvm_reg_init(rvmreg_t *reg)
266 rvmreg_t *rvm_reg_copy(rvmreg_t *dst, const rvmreg_t *src)
270 if (rvm_reg_tstflag(dst, RVM_INFOBIT_ROBJECT))
271 dst->v.p = r_object_v_copy(dst->v.p);
276 void rvm_reg_settype(rvmreg_t *r, unsigned int type)
278 RVM_REG_SETTYPE(r, type);
282 rvmreg_type_t rvm_reg_gettype(const rvmreg_t *r)
284 rvmreg_type_t type = RVM_REG_GETTYPE(r);
289 rboolean rvm_reg_tstflag(const rvmreg_t *r, ruint16 flag)
291 return RVM_REG_TSTFLAG(r, flag);
295 void rvm_reg_setflag(rvmreg_t *r, ruint16 flag)
297 RVM_REG_SETFLAG(r, flag);
301 void rvm_reg_clrflag(rvmreg_t *r, ruint16 flag)
303 RVM_REG_CLRFLAG(r, flag);
307 void rvm_reg_setundef(rvmreg_t *r)
309 r_memset(r, 0, sizeof(*r));
310 RVM_REG_SETTYPE(r, RVM_DTYPE_UNDEF);
314 void rvm_reg_setunsigned(rvmreg_t *r, ruword u)
316 r_memset(r, 0, sizeof(*r));
318 RVM_REG_SETTYPE(r, RVM_DTYPE_UNSIGNED);
322 void rvm_reg_setsigned(rvmreg_t *r, rword l)
324 r_memset(r, 0, sizeof(*r));
326 RVM_REG_SETTYPE(r, RVM_DTYPE_SIGNED);
330 void rvm_reg_setboolean(rvmreg_t *r, rboolean b)
332 r_memset(r, 0, sizeof(*r));
333 RVM_REG_SETU(r, b ? 1 : 0);
334 RVM_REG_SETTYPE(r, RVM_DTYPE_BOOLEAN);
338 void rvm_reg_setdouble(rvmreg_t *r, double d)
340 r_memset(r, 0, sizeof(*r));
342 RVM_REG_SETTYPE(r, RVM_DTYPE_DOUBLE);
346 void rvm_reg_setpointer(rvmreg_t *r, rpointer p)
348 r_memset(r, 0, sizeof(*r));
350 RVM_REG_SETTYPE(r, RVM_DTYPE_POINTER);
354 void rvm_reg_setophandler(rvmreg_t *r, rpointer p)
356 r_memset(r, 0, sizeof(*r));
358 RVM_REG_SETTYPE(r, RVM_DTYPE_OPHANDLER);
362 void rvm_reg_setprophandler(rvmreg_t *r, rpointer p)
364 r_memset(r, 0, sizeof(*r));
366 RVM_REG_SETTYPE(r, RVM_DTYPE_PROPHANDLER);
370 int rvm_reg_str2num(rvmreg_t *dst, const rvmreg_t *src)
376 l = r_strtol(R_STRING2ANSI(RVM_REG_GETP(src)), &lptr, 10);
380 rvm_reg_setsigned(dst, l);
383 d = r_strtod(R_STRING2ANSI(RVM_REG_GETP(src)), &dptr);
386 rvm_reg_setdouble(dst, d);
391 int rvm_reg_str2signed(rvmreg_t *dst, const rvmreg_t *src)
396 d = r_strtod(R_STRING2ANSI(RVM_REG_GETP(src)), &dptr);
399 rvm_reg_setsigned(dst, (rword)d);
404 int rvm_reg_str2double(rvmreg_t *dst, const rvmreg_t *src)
409 d = r_strtod(R_STRING2ANSI(RVM_REG_GETP(src)), &dptr);
412 rvm_reg_setdouble(dst, d);
417 int rvm_reg_int(const rvmreg_t *src)
420 return (int)RVM_REG_GETL(src);
424 rword rvm_reg_signed(const rvmreg_t *src)
427 return (long)RVM_REG_GETL(src);
431 rboolean rvm_reg_boolean(const rvmreg_t *src)
434 return (rboolean)(RVM_REG_GETL(src) ? 1 : 0);
438 double rvm_reg_double(const rvmreg_t *src)
441 return (double)RVM_REG_GETL(src);
445 rpointer rvm_reg_pointer(const rvmreg_t *src)
448 return (rpointer)RVM_REG_GETP(src);
452 rstring_t *rvm_reg_string(const rvmreg_t *src)
454 R_ASSERT(src && rvm_reg_gettype(src) == RVM_DTYPE_STRING);
455 return (rstring_t*)RVM_REG_GETP(src);
459 rmap_t *rvm_reg_jsobject(const rvmreg_t *src)
461 R_ASSERT(src && rvm_reg_gettype(src) == RVM_DTYPE_MAP);
462 return (rmap_t*)RVM_REG_GETP(src);