void *obj_deref_debug(void *object, const char *file, int line) { object_t *o = object; fprintf(stderr,"%s:%i obj_deref(%p <%s>)\n",file,line,object,obj_type(object)->name); o->refcount -= 2; if (o->refcount <= 1) { if (o->refcount >= 0) { o->type->nr_freed++; if (o->type->kill) o->type->kill(object); fprintf(stderr,"obj_deref(): freeing object of type %s\n",obj_type(object)->name); unregister_object(object); free(object); } else { fprintf(stderr,"obj_deref(): Orphan or dying object dereferenced (refcount var = %i)\n", o->refcount); BUG("Error: Orphan or dying object dereferenced, have to quit."); } } else { fprintf(stderr,"obj_deref(): Refcount of %s object down to %i.\n",obj_type(object)->name,o->refcount/2); } return 0; }
void tp_set(tp_vm *tp, tp_obj self, tp_obj k, tp_obj v) { objtype type = obj_type(self); assert(type <= TP_DATA); if (type == TP_DICT) { _tp_dict_set(tp, tp_dict_val(self), k, v); return; } else if (type == TP_LIST) { if (obj_type(k) == TP_NUMBER) { _tp_list_set(tp, tp_list_val(self), tp_number_val(k), v, "tp_set"); return; } else if (obj_type(k) == TP_NONE) { _tp_list_append(tp, tp_list_val(self),v); return; } else if (obj_type(k) == TP_STRING) { if (strcmp("*", STR(k)) == 0) { tp_params_v(tp, 2, self, v); tp_extend(tp); return; } } } else if (type == TP_DATA) { tp_data_meta(self)->set(tp, self, k, v); return; } tp_raise(,"tp_set(%s,%s,%s)",STR(self),STR(k),STR(v)); }
tp_obj tp_iter(TP,tp_obj self, tp_obj k) { int type = obj_type(self); if (type == TP_LIST || type == TP_STRING) { return tp_get(tp,self,k); } if (type == TP_DICT && obj_type(k) == TP_NUMBER) { return tp_dict_val(self)->items[_tp_dict_next(tp, tp_dict_val(self))].key; } tp_raise(None,"tp_iter(%s,%s)",STR(self),STR(k)); }
tp_obj tp_has(tp_vm *tp, tp_obj self, tp_obj k) { int type = obj_type(self); if (type == TP_DICT) { if (_tp_dict_find(tp, tp_dict_val(self), k) != -1) { return True; } return False; } else if (type == TP_STRING && obj_type(k) == TP_STRING) { char *p = strstr(STR(self),STR(k)); return tp_number(tp, p != 0); } else if (type == TP_LIST) { return tp_number(tp, _tp_list_find(tp,tp_list_val(self),k)!=-1); } tp_raise(None,"tp_has(%s,%s)",STR(self),STR(k)); }
int tp_iget(TP,tp_obj *r, tp_obj self, tp_obj k) { if (obj_type(self) == TP_DICT) { int n = _tp_dict_find(tp, tp_dict_val(self),k); if (n == -1) { return 0; } *r = tp_dict_val(self)->items[n].val; tp_grey(tp,*r); return 1; } if (obj_type(self) == TP_LIST && !tp_list_val(self)->len) { return 0; } *r = tp_get(tp,self,k); tp_grey(tp,*r); return 1; }
tp_obj tp_mul(tp_vm *tp, tp_obj a, tp_obj b) { if (obj_type(a) == TP_NUMBER && obj_type(a) == obj_type(b)) { return tp_number(tp, tp_number_val(a) * tp_number_val(b)); } else if (obj_type(a) == TP_STRING && obj_type(b) == TP_NUMBER) { int al = tp_str_len(a); int n = tp_number_val(b); tp_obj r = tp_string_t(tp,al*n); char *s = tp_str_val(r); int i; for (i=0; i<n; i++) { memcpy(s+al*i, tp_str_val(a),al); } return tp_track(tp,r); } tp_raise(None,"tp_mul(%s,%s)",STR(a),STR(b)); }
void *obj_ref_debug(void *object, const object_type_t *type,const char *file, int line) { object_t *o = object; fprintf(stderr,"%s:%i obj_ref(%p <%s>, %s)\n",file,line,object,obj_type(object)->name,type ? type->name : "NULL"); if (obj_has_type(object,type)) { o->refcount += 2; fprintf(stderr,"obj_ref(): Refcount of %s object up to %i.\n",obj_type(object)->name,o->refcount/2); } else { fprintf(stderr,"Error in obj_ref(): Expected object of type %s, got %s.\n",type ? type->name : "NULL",o->type->name); assert(o->type != type); } return object; }
void tp_del(TP,tp_obj self, tp_obj k) { int type = obj_type(self); if (type == TP_DICT) { _tp_dict_del(tp, tp_dict_val(self), k, "tp_del"); return; } tp_raise(,"tp_del(%s,%s)",STR(self),STR(k)); }
void obj_unlock_debug(void *obj, const char *file, int line) { if (obj) { fprintf(stderr,"%s:%i obj_unlock(%p <%s id: %lu>)\n",file,line,obj,obj_type(obj)->name,obj_id(obj)); obj_deref(obj); } }
double _tp_len(tp_obj v) { int type = obj_type(v); if (type == TP_STRING) { return tp_str_len(v); } else if (type == TP_DICT) { return tp_dict_val(v)->len; } else if (type == TP_LIST) { return tp_list_val(v)->len; } return -1.0; }
int tp_bool(TP,tp_obj v) { switch(obj_type(v)) { case TP_NUMBER: return tp_number_val(v) != 0; case TP_NONE: return 0; case TP_STRING: return tp_str_len(v) != 0; case TP_LIST: return tp_list_val(v)->len != 0; case TP_DICT: return tp_dict_val(v)->len != 0; default: /* TP_FNC, TP_DATA */ return 1; } }
static int l_objtype(lua_State * L) { int n = lua_gettop(L); if (n != 1) luaL_error(L, "pdf.objtype() needs exactly 1 argument"); n = (int) luaL_checkinteger(L, 1); if (n < 0 || n > static_pdf->obj_ptr) lua_pushnil(L); else lua_pushstring(L, pdf_obj_typenames[obj_type(static_pdf, n)]); return 1; }
int objlist_insert(struct objlist *list, void *obj) { if (list->size >= list->max_size) { list->max_size *= 2; list->items = xrealloc(list->items, list->max_size*sizeof(*list->items)); } list->items[list->size] = obj_ref(obj,NULL); #ifdef OBJ_DEBUG printf("objlist_insert(): inserted object of type %s\n",obj_type(obj)->name); #endif return list->size++; }
tp_obj tp_add(tp_vm *tp, tp_obj a, tp_obj b) { if (obj_type(a) == TP_NUMBER && obj_type(a) == obj_type(b)) { return tp_number(tp, tp_number_val(a) + tp_number_val(b)); } else if (obj_type(a) == TP_STRING && obj_type(a) == obj_type(b)) { int al = tp_str_len(a), bl = tp_str_len(b); tp_obj r = tp_string_t(tp,al+bl); char *s = tp_str_val(r); memcpy(s, tp_str_val(a),al); memcpy(s+al, tp_str_val(b),bl); return tp_track(tp,r); } else if (obj_type(a) == TP_LIST && obj_type(a) == obj_type(b)) { tp_obj r; tp_params_v(tp,1,a); r = tp_copy(tp); tp_params_v(tp,2,r,b); tp_extend(tp); return r; } tp_raise(None,"tp_add(%s,%s)",STR(a),STR(b)); }
static size_t gc_sweep_page(pic_state *pic, struct heap_page *page) { union header *bp, *p, *head = NULL, *tail = NULL; struct object *obj; size_t alive = 0, nunits; for (bp = page->u.basep; ; bp = bp->s.ptr) { p = bp + (bp->s.size ? bp->s.size : 1); /* first bp's size is 0, so force advnce */ while (p != bp->s.ptr) { if (p < page->u.basep || page->u.basep + PAGE_UNITS <= p) { goto escape; } obj = (struct object *) p; nunits = unitsof(obj_type(pic, obj)); if (obj->u.basic.tt & GC_MARK) { obj->u.basic.tt &= ~GC_MARK; alive += nunits; } else { gc_finalize_object(pic, obj); if (head == NULL) { head = p; } if (tail != NULL) { tail->s.ptr = p; } tail = p; tail->s.size = nunits; tail->s.ptr = NULL; /* We can safely reuse ptr field of dead object */ } p += nunits; } } escape: /* free! */ while (head != NULL) { p = head; head = head->s.ptr; free_chunk(pic, p); } return alive; }
tp_obj tp_str(tp_vm *tp, tp_obj self) { int type = obj_type(self); if (type == TP_STRING) { return self; } if (type == TP_NUMBER) { tp_num v = tp_number_val(self); if ((fabs(v)-fabs((long)v)) < 0.000001) { return tp_printf(tp,"%ld",(long)v); } return tp_printf(tp,"%f",v); } else if(type == TP_DICT) { return tp_printf(tp,"<dict 0x%x>", tp_dict_val(self)); } else if(type == TP_LIST) { return tp_printf(tp,"<list 0x%x>",tp_list_val(self)); } else if (type == TP_NONE) { return tp_string(tp, "None"); } else if (type == TP_DATA) { return tp_printf(tp,"<data 0x%x>", tp_data_val(self)); } else if (type == TP_FNC) { return tp_printf(tp,"<fnc 0x%x>", tp_fnc_val(self)); } return tp_string(tp, "<?>"); }
static int tags_shell_fun(int argc, const char *argv[]) { if (argc > 0) { shell_print("Usage: tags\n"); shell_print("List currently defined tags and sprite types\n"); } else { int i; shell_print("Currently defined sprite tags:\n"); for (i=0; i<sprite_tags->len; i++) { sprite_t *s = obj_lock(sprite_tags->def[i].value,&sprite_type); if (s) { shell_print("%s\t (%s)\n",sprite_tags->def[i].name,obj_type(s)->name); obj_unlock(s); } } } return 0; }
int tp_cmp(tp_vm *tp, tp_obj a, tp_obj b) { if (obj_type(a) != obj_type(b)) { return obj_type(a) - obj_type(b); } switch (obj_type(a)) { case TP_NONE: return 0; case TP_NUMBER: return _tp_sign(tp_number_val(a) - tp_number_val(b)); case TP_STRING: { int minlen = _tp_min(tp_str_len(a), tp_str_len(b)); int v = memcmp(tp_str_val(a), tp_str_val(b), minlen); if (v == 0) { v = tp_str_len(a) - tp_str_len(b); } return v; } case TP_LIST: { int n,v; int minlen = _tp_min(tp_list_val(a)->len,tp_list_val(b)->len); for (n=0; n < minlen; n++) { tp_obj aa = tp_list_val(a)->items[n]; tp_obj bb = tp_list_val(b)->items[n]; if (obj_type(aa) == TP_LIST && obj_type(bb) == TP_LIST) { v = tp_list_val(aa) - tp_list_val(bb); } else { v = tp_cmp(tp,aa,bb); } if (v) { return v; } } return tp_list_val(a)->len - tp_list_val(b)->len; } case TP_DICT: return tp_dict_val(a) - tp_dict_val(b); case TP_FNC: return tp_fnc_val(a) - tp_fnc_val(b); case TP_DATA: return (char*)tp_data_val(a) - (char*)tp_data_val(b); } tp_raise(0,"tp_cmp(%s,%s)",STR(a),STR(b)); }
tp_obj tp_get(tp_vm *tp, tp_obj self, tp_obj k) { int type = obj_type(self); tp_obj r; if (type == TP_DICT) { return _tp_dict_get(tp, tp_dict_val(self), k, "tp_get"); } else if (type == TP_LIST) { if (obj_type(k) == TP_NUMBER) { int l = tp_number_val(tp_len(tp,self)); int n = tp_number_val(k); n = (n<0?l+n:n); return _tp_list_get(tp,tp_list_val(self),n,"tp_get"); } else if (obj_type(k) == TP_STRING) { if (strcmp("append",STR(k)) == 0) { return tp_method(tp,self,tp_append); } else if (strcmp("pop",STR(k)) == 0) { return tp_method(tp,self,tp_pop); } else if (strcmp("index",STR(k)) == 0) { return tp_method(tp,self,tp_index); } else if (strcmp("sort",STR(k)) == 0) { return tp_method(tp,self,tp_sort); } else if (strcmp("extend",STR(k)) == 0) { return tp_method(tp,self,tp_extend); } else if (strcmp("*",STR(k)) == 0) { tp_params_v(tp,1,self); r = tp_copy(tp); tp_list_val(self)->len=0; return r; } } else if (obj_type(k) == TP_NONE) { return _tp_list_pop(tp,tp_list_val(self),0,"tp_get"); } } else if (type == TP_STRING) { if (obj_type(k) == TP_NUMBER) { int l = tp_str_len(self); int n = tp_number_val(k); n = (n<0?l+n:n); if (n >= 0 && n < l) { return tp_string_n(tp, tp->chars[(unsigned char)tp_str_val(self)[n]],1); } } else if (obj_type(k) == TP_STRING) { if (strcmp("join",STR(k)) == 0) { return tp_method(tp,self,tp_join); } else if (strcmp("split",STR(k)) == 0) { return tp_method(tp,self,tp_split); } else if (strcmp("index",STR(k)) == 0) { return tp_method(tp,self,tp_str_index); } else if (strcmp("strip",STR(k)) == 0) { return tp_method(tp,self,tp_strip); } else if (strcmp("replace",STR(k)) == 0) { return tp_method(tp,self,tp_replace); } } } else if (type == TP_DATA) { return tp_data_meta(self)->get(tp,self,k); } if (obj_type(k) == TP_LIST) { int a,b,l; tp_obj tmp; l = tp_number_val(tp_len(tp,self)); tmp = tp_get(tp, k, tp_number(tp, 0)); if (obj_type(tmp) == TP_NUMBER) { a = tp_number_val(tmp); } else if (obj_type(tmp) == TP_NONE) { a = 0; } else { tp_raise(None,"%s is not a number",STR(tmp)); } tmp = tp_get(tp, k, tp_number(tp, 1)); if (obj_type(tmp) == TP_NUMBER) { b = tp_number_val(tmp); } else if (obj_type(tmp) == TP_NONE) { b = l; } else { tp_raise(None,"%s is not a number",STR(tmp)); } a = _tp_max(0,(a<0?l+a:a)); b = _tp_min(l,(b<0?l+b:b)); if (type == TP_LIST) { return tp_list_n(tp,b-a, &tp_list_val(self)->items[a]); } else if (type == TP_STRING) { tp_obj r = tp_string_t(tp, b-a); char *ptr = tp_str_val(r); memcpy(ptr,tp_str_val(self)+a,b-a); ptr[b-a]=0; return tp_track(tp,r); } } tp_raise(None,"tp_get(%s,%s)",STR(self),STR(k)); }
void obj_kill_debug(void *object, const char *file, int line) { fprintf(stderr,"%s:%i obj_kill(%p <%s>)\n",file,line,object,obj_type(object)->name); ((object_t *)object)->refcount |= 1; }
static void gc_mark_object(pic_state *pic, struct object *obj) { loop: if (is_alive(obj)) return; mark(obj); #define LOOP(o) obj = (struct object *)(o); goto loop switch (obj_type(pic, obj)) { case PIC_TYPE_PAIR: { gc_mark(pic, obj->u.pair.car); if (obj_p(pic, obj->u.pair.cdr)) { LOOP(obj_ptr(pic, obj->u.pair.cdr)); } break; } case PIC_TYPE_FRAME: { int i; for (i = 0; i < obj->u.frame.regc; ++i) { gc_mark(pic, obj->u.frame.regs[i]); } if (obj->u.frame.up) { LOOP(obj->u.frame.up); } break; } case PIC_TYPE_PROC_FUNC: { if (obj->u.proc.env) { LOOP(obj->u.proc.env); } break; } case PIC_TYPE_PROC_IREP: { if (obj->u.proc.env) { gc_mark_object(pic, (struct object *)obj->u.proc.env); } LOOP(obj->u.proc.u.irep); break; } case PIC_TYPE_IREP: { size_t i; for (i = 0; i < obj->u.irep.objc; ++i) { gc_mark(pic, obj->u.irep.obj[i]); } for (i = 0; i < obj->u.irep.irepc; ++i) { gc_mark_object(pic, (struct object *)obj->u.irep.irep[i]); } break; } case PIC_TYPE_PORT: { break; } case PIC_TYPE_ERROR: { gc_mark_object(pic, (struct object *)obj->u.err.type); gc_mark(pic, obj->u.err.irrs); LOOP(obj->u.err.msg); break; } case PIC_TYPE_STRING: { break; } case PIC_TYPE_VECTOR: { int i; for (i = 0; i < obj->u.vec.len; ++i) { gc_mark(pic, obj->u.vec.data[i]); } break; } case PIC_TYPE_BLOB: { break; } case PIC_TYPE_DATA: { break; } case PIC_TYPE_DICT: { pic_value key, val; int it = 0; while (pic_dict_next(pic, obj_value(pic, &obj->u.dict), &it, &key, &val)) { gc_mark(pic, key); gc_mark(pic, val); } break; } case PIC_TYPE_RECORD: { gc_mark(pic, obj->u.rec.datum); LOOP(obj->u.rec.type); break; } case PIC_TYPE_SYMBOL: { LOOP(obj->u.sym.str); break; } case PIC_TYPE_WEAK: { struct weak *weak = (struct weak *)obj; weak->prev = pic->heap->weaks; pic->heap->weaks = weak; break; } default: PIC_UNREACHABLE(); } }
/* * This function initiates a connection to the server assigned to this session * (s->target, s->si[1].addr.to). It will assign a server if none * is assigned yet. * It can return one of : * - SN_ERR_NONE if everything's OK * - SN_ERR_SRVTO if there are no more servers * - SN_ERR_SRVCL if the connection was refused by the server * - SN_ERR_PRXCOND if the connection has been limited by the proxy (maxconn) * - SN_ERR_RESOURCE if a system resource is lacking (eg: fd limits, ports, ...) * - SN_ERR_INTERNAL for any other purely internal errors * Additionnally, in the case of SN_ERR_RESOURCE, an emergency log will be emitted. * The server-facing stream interface is expected to hold a pre-allocated connection * in s->si[1].conn. */ int connect_server(struct session *s) { struct connection *cli_conn; struct connection *srv_conn; struct server *srv; int reuse = 0; int err; srv_conn = objt_conn(s->si[1].end); if (srv_conn) reuse = s->target == srv_conn->target; if (reuse) { /* Disable connection reuse if a dynamic source is used. * As long as we don't share connections between servers, * we don't need to disable connection reuse on no-idempotent * requests nor when PROXY protocol is used. */ srv = objt_server(s->target); if (srv && srv->conn_src.opts & CO_SRC_BIND) { if ((srv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_DYN) reuse = 0; } else if (s->be->conn_src.opts & CO_SRC_BIND) { if ((s->be->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_DYN) reuse = 0; } } srv_conn = si_alloc_conn(&s->si[1], reuse); if (!srv_conn) return SN_ERR_RESOURCE; if (!(s->flags & SN_ADDR_SET)) { err = assign_server_address(s); if (err != SRV_STATUS_OK) return SN_ERR_INTERNAL; } if (!conn_xprt_ready(srv_conn)) { /* the target was only on the session, assign it to the SI now */ srv_conn->target = s->target; /* set the correct protocol on the output stream interface */ if (objt_server(s->target)) { conn_prepare(srv_conn, protocol_by_family(srv_conn->addr.to.ss_family), objt_server(s->target)->xprt); } else if (obj_type(s->target) == OBJ_TYPE_PROXY) { /* proxies exclusively run on raw_sock right now */ conn_prepare(srv_conn, protocol_by_family(srv_conn->addr.to.ss_family), &raw_sock); if (!objt_conn(s->si[1].end) || !objt_conn(s->si[1].end)->ctrl) return SN_ERR_INTERNAL; } else return SN_ERR_INTERNAL; /* how did we get there ? */ /* process the case where the server requires the PROXY protocol to be sent */ srv_conn->send_proxy_ofs = 0; if (objt_server(s->target) && objt_server(s->target)->pp_opts) { srv_conn->send_proxy_ofs = 1; /* must compute size */ cli_conn = objt_conn(s->si[0].end); if (cli_conn) conn_get_to_addr(cli_conn); } si_attach_conn(&s->si[1], srv_conn); assign_tproxy_address(s); } else { /* the connection is being reused, just re-attach it */ si_attach_conn(&s->si[1], srv_conn); s->flags |= SN_SRV_REUSED; } /* flag for logging source ip/port */ if (s->fe->options2 & PR_O2_SRC_ADDR) s->si[1].flags |= SI_FL_SRC_ADDR; /* disable lingering */ if (s->be->options & PR_O_TCP_NOLING) s->si[1].flags |= SI_FL_NOLINGER; err = si_connect(&s->si[1]); if (err != SN_ERR_NONE) return err; /* set connect timeout */ s->si[1].exp = tick_add_ifset(now_ms, s->be->timeout.connect); srv = objt_server(s->target); if (srv) { s->flags |= SN_CURR_SESS; srv->cur_sess++; if (srv->cur_sess > srv->counters.cur_sess_max) srv->counters.cur_sess_max = srv->cur_sess; if (s->be->lbprm.server_take_conn) s->be->lbprm.server_take_conn(srv); } return SN_ERR_NONE; /* connection is OK */ }
static void gc_finalize_object(pic_state *pic, struct object *obj) { switch (obj_type(obj)) { case PIC_TYPE_VECTOR: { struct vector *vec = (struct vector *) obj; pic_free(pic, vec->data); break; } case PIC_TYPE_BLOB: { struct blob *blob = (struct blob *) obj; pic_free(pic, blob->data); break; } case PIC_TYPE_DATA: { struct data *data = (struct data *) obj; if (data->type->dtor) { data->type->dtor(pic, data->data); } break; } case PIC_TYPE_DICT: { struct dict *dict = (struct dict *) obj; kh_destroy(dict, &dict->hash); break; } case PIC_TYPE_SYMBOL: { /* TODO: remove this symbol's entry from pic->syms immediately */ break; } case PIC_TYPE_ATTR: { struct attr *attr = (struct attr *) obj; kh_destroy(attr, &attr->hash); break; } case PIC_TYPE_IREP: { struct irep *irep = (struct irep *) obj; if ((irep->flags & IREP_CODE_STATIC) == 0) { pic_free(pic, (code_t *) irep->code); } pic_free(pic, irep->obj); pic_free(pic, irep->irep); break; } case PIC_TYPE_FRAME: { struct frame *frame = (struct frame *) obj; pic_free(pic, frame->regs); break; } case PIC_TYPE_ROPE_LEAF: { struct rope_leaf *leaf = (struct rope_leaf *) obj; pic_free(pic, (char *) leaf->str); break; } case PIC_TYPE_STRING: case PIC_TYPE_ROPE_NODE: case PIC_TYPE_PAIR: case PIC_TYPE_RECORD: case PIC_TYPE_PROC_FUNC: case PIC_TYPE_PROC_IREP: break; default: PIC_UNREACHABLE(); } }
static void gc_finalize_object(pic_state *pic, struct object *obj) { switch (obj_type(pic, obj)) { case PIC_TYPE_VECTOR: { pic_free(pic, obj->u.vec.data); break; } case PIC_TYPE_BLOB: { pic_free(pic, obj->u.blob.data); break; } case PIC_TYPE_STRING: { pic_rope_decref(pic, obj->u.str.rope); break; } case PIC_TYPE_DATA: { if (obj->u.data.type->dtor) { obj->u.data.type->dtor(pic, obj->u.data.data); } break; } case PIC_TYPE_DICT: { kh_destroy(dict, &obj->u.dict.hash); break; } case PIC_TYPE_SYMBOL: { /* TODO: remove this symbol's entry from pic->syms immediately */ break; } case PIC_TYPE_WEAK: { kh_destroy(weak, &obj->u.weak.hash); break; } case PIC_TYPE_IREP: { struct irep *irep = &obj->u.irep; if ((irep->flags & IREP_CODE_STATIC) == 0) { pic_free(pic, (code_t *) irep->code); } pic_free(pic, irep->obj); pic_free(pic, irep->irep); break; } case PIC_TYPE_PORT: { pic_fclose(pic, obj_value(pic, obj)); /* FIXME */ break; } case PIC_TYPE_FRAME: { pic_free(pic, obj->u.frame.regs); break; } case PIC_TYPE_PAIR: case PIC_TYPE_ERROR: case PIC_TYPE_RECORD: case PIC_TYPE_PROC_FUNC: case PIC_TYPE_PROC_IREP: break; default: PIC_UNREACHABLE(); } }
inline obj_type randg(const uword n_rows, const uword n_cols, const distr_param& param = distr_param(), const typename arma_Mat_Col_Row_only<obj_type>::result* junk = 0) { arma_extra_debug_sigprint(); arma_ignore(junk); #if defined(ARMA_USE_CXX11) { if(is_Col<obj_type>::value == true) { arma_debug_check( (n_cols != 1), "randg(): incompatible size" ); } else if(is_Row<obj_type>::value == true) { arma_debug_check( (n_rows != 1), "randg(): incompatible size" ); } obj_type out(n_rows, n_cols); double a; double b; if(param.state == 0) { a = double(1); b = double(1); } else if(param.state == 1) { a = double(param.a_int); b = double(param.b_int); } else { a = param.a_double; b = param.b_double; } arma_debug_check( ((a <= double(0)) || (b <= double(0))), "randg(): a and b must be greater than zero" ); #if defined(ARMA_USE_EXTERN_CXX11_RNG) { arma_rng_cxx11_instance.randg_fill(out.memptr(), out.n_elem, a, b); } #else { arma_rng_cxx11 local_arma_rng_cxx11_instance; typedef typename arma_rng_cxx11::seed_type seed_type; local_arma_rng_cxx11_instance.set_seed( seed_type(arma_rng::randi<seed_type>()) ); local_arma_rng_cxx11_instance.randg_fill(out.memptr(), out.n_elem, a, b); } #endif return out; } #else { arma_ignore(n_rows); arma_ignore(n_cols); arma_ignore(param); arma_stop("randg(): C++11 compiler required"); return obj_type(); } #endif }
static void gc_mark_object(pic_state *pic, struct object *obj) { loop: if (is_alive(obj)) return; mark(obj); #define LOOP(o) obj = (struct object *)(o); goto loop switch (obj_type(obj)) { case PIC_TYPE_PAIR: { struct pair *pair = (struct pair *) obj; gc_mark(pic, pair->car); if (pic_obj_p(pic, pair->cdr)) { LOOP(pic_ptr(pic, pair->cdr)); } break; } case PIC_TYPE_FRAME: { struct frame *frame = (struct frame *) obj; int i; for (i = 0; i < frame->regc; ++i) { gc_mark(pic, frame->regs[i]); } if (frame->up) { LOOP(frame->up); } break; } case PIC_TYPE_PROC_FUNC: { struct proc *proc = (struct proc *) obj; if (proc->env) { LOOP(proc->env); } break; } case PIC_TYPE_PROC_IREP: { struct proc *proc = (struct proc *) obj; if (proc->env) { gc_mark_object(pic, (struct object *) proc->env); } LOOP(proc->u.irep); break; } case PIC_TYPE_IREP: { struct irep *irep = (struct irep *) obj; size_t i; for (i = 0; i < irep->objc; ++i) { gc_mark(pic, irep->obj[i]); } for (i = 0; i < irep->irepc; ++i) { gc_mark_object(pic, (struct object *) irep->irep[i]); } break; } case PIC_TYPE_VECTOR: { struct vector *vec = (struct vector *) obj; int i; for (i = 0; i < vec->len; ++i) { gc_mark(pic, vec->data[i]); } break; } case PIC_TYPE_DICT: { struct dict *dict = (struct dict *) obj; khash_t(dict) *h = &dict->hash; int it; for (it = 0; it != kh_end(h); ++it) { if (kh_exist(h, it)) { gc_mark_object(pic, (struct object *) kh_key(h, it)); gc_mark(pic, kh_val(h, it)); } } break; } case PIC_TYPE_RECORD: { struct record *rec = (struct record *) obj; gc_mark(pic, rec->datum); LOOP(rec->type); break; } case PIC_TYPE_SYMBOL: { struct symbol *sym = (struct symbol *) obj; LOOP(sym->str); break; } case PIC_TYPE_ATTR: { struct attr *attr = (struct attr *) obj; attr->prev = pic->gc_attrs; pic->gc_attrs = attr; break; } case PIC_TYPE_STRING: { struct string *str = (struct string *) obj; LOOP(str->rope); break; } case PIC_TYPE_ROPE_NODE: { struct rope_node *node = (struct rope_node *) obj; gc_mark_object(pic, (struct object *) node->s1); LOOP(node->s2); break; } case PIC_TYPE_ROPE_LEAF: case PIC_TYPE_BLOB: case PIC_TYPE_DATA: break; default: PIC_UNREACHABLE(); } }