void setup_romvec(void) { /* SPARC32 is slightly unusual in that before invoking any loaders, a romvec array needs to be set up to pass certain parameters using a C struct. Hence this function extracts the relevant boot information and places it in obp_arg. */ int intprop, proplen, target, device, i; unsigned int *intprop_ptr; phandle_t chosen; char *prop, *id, *name; static char bootpathbuf[128], bootargsbuf[128], buf[128]; struct linux_mlist_v0 **pp; /* Get the stdin and stdout paths */ chosen = find_dev("/chosen"); intprop = get_int_property(chosen, "stdin", &proplen); PUSH(intprop); fword("get-instance-path"); ((struct linux_romvec *)romvec)->pv_stdin = pop_fstr_copy(); intprop = get_int_property(chosen, "stdout", &proplen); PUSH(intprop); fword("get-instance-path"); ((struct linux_romvec *)romvec)->pv_stdout = pop_fstr_copy(); /* Get the name of the selected boot device, along with the device and unit number */ prop = get_property(chosen, "bootpath", &proplen); strncpy(bootpathbuf, prop, proplen); prop = get_property(chosen, "bootargs", &proplen); strncpy(bootargsbuf, prop, proplen); /* Set bootpath pointer used in romvec table to the bootpath */ push_str(bootpathbuf); fword("pathres-resolve-aliases"); bootpath = pop_fstr_copy(); printk("bootpath: %s\n", bootpath); /* Now do some work to get hold of the target, partition etc. */ push_str(bootpathbuf); feval("open-dev"); feval("ihandle>boot-device-handle drop to my-self"); push_str("name"); fword("get-my-property"); POP(); name = pop_fstr_copy(); if (!strncmp(name, "sd", 2)) { /* Old-style SunOS disk paths are given in the form: sd(c,t,d):s where: c = controller (Nth controller in system, usually 0) t = target (my-unit phys.hi) d = device/LUN (my-unit phys.lo) s = slice/partition (my-args) */ /* Controller currently always 0 */ obp_arg.boot_dev_ctrl = 0; /* Get the target, device and slice */ fword("my-unit"); target = POP(); device = POP(); fword("my-args"); id = pop_fstr_copy(); if (id != NULL) { snprintf(buf, sizeof(buf), "sd(0,%d,%d):%c", target, device, id[0]); obp_arg.dev_partition = id[0] - 'a'; } else { snprintf(buf, sizeof(buf), "sd(0,%d,%d)", target, device); obp_arg.dev_partition = 0; } obp_arg.boot_dev_unit = target; obp_arg.boot_dev[0] = buf[0]; obp_arg.boot_dev[1] = buf[1]; obp_arg.argv[0] = buf; obp_arg.argv[1] = bootargsbuf; } else if (!strncmp(name, "SUNW,fdtwo", 10)) { obp_arg.boot_dev_ctrl = 0; obp_arg.boot_dev_unit = 0; obp_arg.dev_partition = 0; strcpy(buf, "fd()"); obp_arg.boot_dev[0] = buf[0]; obp_arg.boot_dev[1] = buf[1]; obp_arg.argv[0] = buf; obp_arg.argv[1] = bootargsbuf; } else if (!strncmp(name, "le", 2)) { obp_arg.boot_dev_ctrl = 0; obp_arg.boot_dev_unit = 0; obp_arg.dev_partition = 0; strcpy(buf, "le()"); obp_arg.boot_dev[0] = buf[0]; obp_arg.boot_dev[1] = buf[1]; obp_arg.argv[0] = buf; obp_arg.argv[1] = bootargsbuf; } /* Generate the totphys (total memory available) list */ prop = get_property(s_phandle_memory, "reg", &proplen); intprop_ptr = (unsigned int *)prop; for (pp = &totphyslist, i = 0; i < (proplen / sizeof(int)); pp = &(**pp).theres_more, i+=3) { *pp = (struct linux_mlist_v0 *)malloc(sizeof(struct linux_mlist_v0)); (**pp).theres_more = NULL; (**pp).start_adr = (char *)intprop_ptr[1]; (**pp).num_bytes = intprop_ptr[2]; intprop_ptr += 3; } /* Generate the avail (physical memory available) list */ prop = get_property(s_phandle_memory, "available", &proplen); intprop_ptr = (unsigned int *)prop; for (pp = &availlist, i = 0; i < (proplen / sizeof(int)); pp = &(**pp).theres_more, i+=3) { *pp = (struct linux_mlist_v0 *)malloc(sizeof(struct linux_mlist_v0)); (**pp).theres_more = NULL; (**pp).start_adr = (char *)intprop_ptr[1]; (**pp).num_bytes = intprop_ptr[2]; intprop_ptr += 3; } /* Generate the prommap (taken virtual memory) list from inverse of available */ prop = get_property(s_phandle_mmu, "available", &proplen); intprop_ptr = (unsigned int *)prop; for (pp = &prommaplist, i = 0; i < (proplen / sizeof(int)); pp = &(**pp).theres_more, i+=3) { *pp = (struct linux_mlist_v0 *)malloc(sizeof(struct linux_mlist_v0)); (**pp).theres_more = NULL; (**pp).start_adr = (char *)(intprop_ptr[1] + intprop_ptr[2]); if (i + 3 < (proplen / sizeof(int))) { /* Size from next entry */ (**pp).num_bytes = (intprop_ptr[4] + intprop_ptr[5]) - (intprop_ptr[1] + intprop_ptr[2]); } else { /* Tail (size from top of virtual memory) */ (**pp).num_bytes = ofmem_arch_get_virt_top() - 1 - (intprop_ptr[1] + intprop_ptr[2]) + 1; } intprop_ptr += 3; } /* Finally set the memory properties */ ((struct linux_romvec *)romvec)->pv_v0mem.v0_totphys = &totphyslist; ((struct linux_romvec *)romvec)->pv_v0mem.v0_available = &availlist; ((struct linux_romvec *)romvec)->pv_v0mem.v0_prommap = &prommaplist; }
void prim_array_regfilter_prop(PRIM_PROTOTYPE) { char buf[BUFFER_LEN]; struct inst *in; stk_array *arr; stk_array *nu; char* prop; const char* ptr; muf_re* re; int flags; int matchcnt = 0; const char* errstr = NULL; CHECKOP(4); oper4 = POP(); /* int pcreflags */ oper3 = POP(); /* str pattern */ oper2 = POP(); /* str propname */ oper1 = POP(); /* refarr Array */ if (oper1->type != PROG_ARRAY) abort_interp("Argument not an array. (1)"); if (!array_is_homogenous(oper1->data.array, PROG_OBJECT)) abort_interp("Argument not an array of dbrefs. (1)"); if (oper2->type != PROG_STRING || !oper2->data.string) abort_interp("Argument not a non-null string. (2)"); if (oper3->type != PROG_STRING) abort_interp("Argument not a string pattern. (3)"); if (oper4->type != PROG_INTEGER) abort_interp("Non-integer argument (4)"); ptr = oper2->data.string->data; while ((ptr = index(ptr, PROPDIR_DELIMITER))) if (!(*(++ptr))) abort_interp("Cannot access a propdir directly."); nu = new_array_packed(0); arr = oper1->data.array; flags = PCRE_NO_AUTO_CAPTURE; if (oper4->data.number & MUF_RE_ICASE) flags |= PCRE_CASELESS; if (oper4->data.number & MUF_RE_EXTENDED) flags |= PCRE_EXTENDED; re = regmatch_re_get(oper3->data.string, flags, &errstr); if (errstr) abort_interp(errstr) if (re && !re->extra && array_count(arr) > 2) { /* This pattern is getting used 3 or more times, let's study it. A null * return is okay, that just means there's nothing to optimize. */ re->extra = pcre_study(re->re, 0, &errstr); if (errstr) abort_interp(errstr); } prop = (char *) DoNullInd(oper2->data.string); if (array_first(arr, &temp1)) { do { in = array_getitem(arr, &temp1); if (valid_object(in)) { ref = in->data.objref; CHECKREMOTE(ref); if (prop_read_perms(ProgUID, ref, prop, mlev)) { ptr = get_property_class(ref, prop); if (ptr) strcpy(buf, ptr); else strcpy(buf, ""); if ((matchcnt = regmatch_exec(re, buf)) < 0) { if (matchcnt != PCRE_ERROR_NOMATCH) abort_interp(muf_re_error(matchcnt)); } else { array_appenditem(&nu, in); } } } } while (array_next(arr, &temp1)); } CLEAR(oper4); CLEAR(oper3); CLEAR(oper2); CLEAR(oper1); PushArrayRaw(nu); }
cell amx_exec_run(AMX *amx,cell *retval,unsigned char *data) { static const void * const amx_opcodelist[] = { /* core set */ &&op_nop, &&op_load_pri, &&op_load_alt, &&op_load_s_pri, &&op_load_s_alt, &&op_lref_s_pri, &&op_lref_s_alt, &&op_load_i, &&op_lodb_i, &&op_const_pri, &&op_const_alt, &&op_addr_pri, &&op_addr_alt, &&op_stor, &&op_stor_s, &&op_sref_s, &&op_stor_i, &&op_strb_i, &&op_align_pri, &&op_lctrl, &&op_sctrl, &&op_xchg, &&op_push_pri, &&op_push_alt, &&op_pushr_pri, &&op_pop_pri, &&op_pop_alt, &&op_pick, &&op_stack, &&op_heap, &&op_proc, &&op_ret, &&op_retn, &&op_call, &&op_jump, &&op_jzer, &&op_jnz, &&op_shl, &&op_shr, &&op_sshr, &&op_shl_c_pri, &&op_shl_c_alt, &&op_smul, &&op_sdiv, &&op_add, &&op_sub, &&op_and, &&op_or, &&op_xor, &&op_not, &&op_neg, &&op_invert, &&op_eq, &&op_neq, &&op_sless, &&op_sleq, &&op_sgrtr, &&op_sgeq, &&op_inc_pri, &&op_inc_alt, &&op_inc_i, &&op_dec_pri, &&op_dec_alt, &&op_dec_i, &&op_movs, &&op_cmps, &&op_fill, &&op_halt, &&op_bounds, &&op_sysreq, &&op_switch, &&op_swap_pri, &&op_swap_alt, &&op_break, &&op_casetbl, /* patched instructions */ /* if op_sysreq_d and/or op_sysreq_nd are not implemented, their entries * in this table must be NULL */ &&op_sysreq_d, &&op_sysreq_nd, /* overlay instructions */ &&op_call_ovl, &&op_retn_ovl, &&op_switch_ovl, &&op_casetbl_ovl, /* supplemental and macro instructions */ #if !defined AMX_NO_MACRO_INSTR &&op_lidx, &&op_lidx_b, &&op_idxaddr, &&op_idxaddr_b, &&op_push_c, &&op_push, &&op_push_s, &&op_push_adr, &&op_pushr_c, &&op_pushr_s, &&op_pushr_adr, &&op_jeq, &&op_jneq, &&op_jsless, &&op_jsleq, &&op_jsgrtr, &&op_jsgeq, &&op_sdiv_inv, &&op_sub_inv, &&op_add_c, &&op_smul_c, &&op_zero_pri, &&op_zero_alt, &&op_zero, &&op_zero_s, &&op_eq_c_pri, &&op_eq_c_alt, &&op_inc, &&op_inc_s, &&op_dec, &&op_dec_s, &&op_sysreq_n, &&op_pushm_c, &&op_pushm, &&op_pushm_s, &&op_pushm_adr, &&op_pushrm_c, &&op_pushrm_s, &&op_pushrm_adr, &&op_load2, &&op_load2_s, &&op_const, &&op_const_s, #endif #if !defined AMX_NO_PACKED_OPC &&op_load_p_pri, &&op_load_p_alt, &&op_load_p_s_pri,&&op_load_p_s_alt, &&op_lref_p_s_pri,&&op_lref_p_s_alt,&&op_lodb_p_i, &&op_const_p_pri, &&op_const_p_alt, &&op_addr_p_pri, &&op_addr_p_alt, &&op_stor_p, &&op_stor_p_s, &&op_sref_p_s, &&op_strb_p_i, &&op_lidx_p_b, &&op_idxaddr_p_b, &&op_align_p_pri, &&op_push_p_c, &&op_push_p, &&op_push_p_s, &&op_push_p_adr, &&op_pushr_p_c, &&op_pushr_p_s, &&op_pushr_p_adr, &&op_pushm_p_c, &&op_pushm_p, &&op_pushm_p_s, &&op_pushm_p_adr, &&op_pushrm_p_c, &&op_pushrm_p_s, &&op_pushrm_p_adr, &&op_stack_p, &&op_heap_p, &&op_shl_p_c_pri, &&op_shl_p_c_alt, &&op_add_p_c, &&op_smul_p_c, &&op_zero_p, &&op_zero_p_s, &&op_eq_p_c_pri, &&op_eq_p_c_alt, &&op_inc_p, &&op_inc_p_s, &&op_dec_p, &&op_dec_p_s, &&op_movs_p, &&op_cmps_p, &&op_fill_p, &&op_halt_p, &&op_bounds_p, #endif }; AMX_HEADER *hdr; cell pri,alt,stk,frm,hea; cell reset_stk, reset_hea, *cip; cell offs,val; int num,i; #if !defined AMX_NO_PACKED_OPC int op; #endif assert(amx!=NULL); /* HACK: return label table and opcode count (for VerifyPcode()) if amx * structure has the flags set to all ones (see amx_exec_list() above) */ if (amx->flags==~0) { assert(sizeof(cell)==sizeof(void *)); assert(data==NULL); assert(retval!=NULL); *retval=(cell)amx_opcodelist; return sizearray(amx_opcodelist); } /* if */ /* set up the registers */ hdr=(AMX_HEADER *)amx->base; assert(hdr->magic==AMX_MAGIC); assert(hdr->file_version>=11); cip=(cell*)amx->cip; hea=amx->hea; stk=amx->stk; reset_stk=stk; reset_hea=hea; alt=frm=pri=0;/* just to avoid compiler warnings */ num=0; /* just to avoid compiler warnings */ /* start running */ assert(amx->code!=NULL); assert(data!=NULL); cip=(cell *)(amx->code+(int)amx->cip); NEXT(cip,op); op_nop: NEXT(cip,op); op_load_pri: GETPARAM(offs); pri=_R(data,offs); NEXT(cip,op); op_load_alt: GETPARAM(offs); alt=_R(data,offs); NEXT(cip,op); op_load_s_pri: GETPARAM(offs); pri=_R(data,frm+offs); NEXT(cip,op); op_load_s_alt: GETPARAM(offs); alt=_R(data,frm+offs); NEXT(cip,op); op_lref_s_pri: GETPARAM(offs); offs=_R(data,frm+offs); pri=_R(data,offs); NEXT(cip,op); op_lref_s_alt: GETPARAM(offs); offs=_R(data,frm+offs); alt=_R(data,offs); NEXT(cip,op); op_load_i: /* verify address */ if (pri>=hea && pri<stk || (ucell)pri>=(ucell)amx->stp) ABORT(amx,AMX_ERR_MEMACCESS); pri=_R(data,pri); NEXT(cip,op); op_lodb_i: GETPARAM(offs); __lodb_i: /* verify address */ if (pri>=hea && pri<stk || (ucell)pri>=(ucell)amx->stp) ABORT(amx,AMX_ERR_MEMACCESS); switch (offs) { case 1: pri=_R8(data,pri); break; case 2: pri=_R16(data,pri); break; case 4: pri=_R32(data,pri); break; } /* switch */ NEXT(cip,op); op_const_pri: GETPARAM(pri); NEXT(cip,op); op_const_alt: GETPARAM(alt); NEXT(cip,op); op_addr_pri: GETPARAM(pri); pri+=frm; NEXT(cip,op); op_addr_alt: GETPARAM(alt); alt+=frm; NEXT(cip,op); op_stor: GETPARAM(offs); _W(data,offs,pri); NEXT(cip,op); op_stor_s: GETPARAM(offs); _W(data,frm+offs,pri); NEXT(cip,op); op_sref_s: GETPARAM(offs); offs=_R(data,frm+offs); _W(data,offs,pri); NEXT(cip,op); op_stor_i: /* verify address */ if (alt>=hea && alt<stk || (ucell)alt>=(ucell)amx->stp) ABORT(amx,AMX_ERR_MEMACCESS); _W(data,alt,pri); NEXT(cip,op); op_strb_i: GETPARAM(offs); __strb_i: /* verify address */ if (alt>=hea && alt<stk || (ucell)alt>=(ucell)amx->stp) ABORT(amx,AMX_ERR_MEMACCESS); switch (offs) { case 1: _W8(data,alt,pri); break; case 2: _W16(data,alt,pri); break; case 4: _W32(data,alt,pri); break; } /* switch */ NEXT(cip,op); op_align_pri: GETPARAM(offs); #if BYTE_ORDER==LITTLE_ENDIAN if (offs<(int)sizeof(cell)) pri ^= sizeof(cell)-offs; #endif NEXT(cip,op); op_lctrl: GETPARAM(offs); switch (offs) { case 0: pri=hdr->cod; break; case 1: pri=hdr->dat; break; case 2: pri=hea; break; case 3: pri=amx->stp; break; case 4: pri=stk; break; case 5: pri=frm; break; case 6: pri=(cell)((unsigned char *)cip - amx->code); break; } /* switch */ NEXT(cip,op); op_sctrl: GETPARAM(offs); switch (offs) { case 0: case 1: case 3: /* cannot change these parameters */ break; case 2: hea=pri; break; case 4: stk=pri; break; case 5: frm=pri; break; case 6: cip=(cell *)(amx->code + (int)pri); break; } /* switch */ NEXT(cip,op); op_xchg: offs=pri; /* offs is a temporary variable */ pri=alt; alt=offs; NEXT(cip,op); op_push_pri: PUSH(pri); NEXT(cip,op); op_push_alt: PUSH(alt); NEXT(cip,op); op_pushr_pri: PUSH(data+pri); NEXT(cip,op); op_pop_pri: POP(pri); NEXT(cip,op); op_pop_alt: POP(alt); NEXT(cip,op); op_pick: GETPARAM(offs); pri=_R(data,stk+offs); NEXT(cip,op); op_stack: GETPARAM(offs); alt=stk; stk+=offs; CHKMARGIN(); CHKSTACK(); NEXT(cip,op); op_heap: GETPARAM(offs); alt=hea; hea+=offs; CHKMARGIN(); CHKHEAP(); NEXT(cip,op); op_proc: PUSH(frm); frm=stk; CHKMARGIN(); NEXT(cip,op); op_ret: POP(frm); POP(offs); /* verify the return address */ if ((long)offs>=amx->codesize) ABORT(amx,AMX_ERR_MEMACCESS); cip=(cell *)(amx->code+(int)offs); NEXT(cip,op); op_retn: POP(frm); POP(offs); /* verify the return address */ if ((long)offs>=amx->codesize) ABORT(amx,AMX_ERR_MEMACCESS); cip=(cell *)(amx->code+(int)offs); stk+= _R(data,stk) + sizeof(cell); /* remove parameters from the stack */ NEXT(cip,op); op_call: PUSH(((unsigned char *)cip-amx->code)+sizeof(cell));/* push address behind instruction */ cip=JUMPREL(cip); /* jump to the address */ NEXT(cip,op); op_jump: /* since the GETPARAM() macro modifies cip, you cannot * do GETPARAM(cip) directly */ cip=JUMPREL(cip); NEXT(cip,op); op_jzer: if (pri==0) cip=JUMPREL(cip); else SKIPPARAM(1); NEXT(cip,op); op_jnz: if (pri!=0) cip=JUMPREL(cip); else SKIPPARAM(1); NEXT(cip,op); op_shl: pri<<=alt; NEXT(cip,op); op_shr: pri=(ucell)pri >> (ucell)alt; NEXT(cip,op); op_sshr: pri>>=alt; NEXT(cip,op); op_shl_c_pri: GETPARAM(offs); pri<<=offs; NEXT(cip,op); op_shl_c_alt: GETPARAM(offs); alt<<=offs; NEXT(cip,op); op_smul: pri*=alt; NEXT(cip,op); op_sdiv: if (pri==0) ABORT(amx,AMX_ERR_DIVIDE); /* use floored division and matching remainder */ offs=pri; #if defined TRUNC_SDIV pri=alt/offs; alt=alt%offs; #else val=alt; /* portable routine for truncated division */ pri=IABS(alt)/IABS(offs); if ((cell)(val ^ offs)<0) pri=-pri; alt=val-pri*offs; /* calculate the matching remainder */ #endif /* now "fiddle" with the values to get floored division */ if (alt!=0 && (cell)(alt ^ offs)<0) { pri--; alt+=offs; } /* if */ NEXT(cip,op); op_add: pri+=alt; NEXT(cip,op); op_sub: pri=alt-pri; NEXT(cip,op); op_and: pri&=alt; NEXT(cip,op); op_or: pri|=alt; NEXT(cip,op); op_xor: pri^=alt; NEXT(cip,op); op_not: pri=!pri; NEXT(cip,op); op_neg: pri=-pri; NEXT(cip,op); op_invert: pri=~pri; NEXT(cip,op); op_eq: pri= pri==alt ? 1 : 0; NEXT(cip,op); op_neq: pri= pri!=alt ? 1 : 0; NEXT(cip,op); op_sless: pri= pri<alt ? 1 : 0; NEXT(cip,op); op_sleq: pri= pri<=alt ? 1 : 0; NEXT(cip,op); op_sgrtr: pri= pri>alt ? 1 : 0; NEXT(cip,op); op_sgeq: pri= pri>=alt ? 1 : 0; NEXT(cip,op); op_inc_pri: pri++; NEXT(cip,op); op_inc_alt: alt++; NEXT(cip,op); op_inc_i: #if defined _R_DEFAULT *(cell *)(data+(int)pri) += 1; #else val=_R(data,pri); _W(data,pri,val+1); #endif NEXT(cip,op); op_dec_pri: pri--; NEXT(cip,op); op_dec_alt: alt--; NEXT(cip,op); op_dec_i: #if defined _R_DEFAULT *(cell *)(data+(int)pri) -= 1; #else val=_R(data,pri); _W(data,pri,val-1); #endif NEXT(cip,op); op_movs: GETPARAM(offs); __movs: /* verify top & bottom memory addresses, for both source and destination * addresses */ if (pri>=hea && pri<stk || (ucell)pri>=(ucell)amx->stp) ABORT(amx,AMX_ERR_MEMACCESS); if ((pri+offs)>hea && (pri+offs)<stk || (ucell)(pri+offs)>(ucell)amx->stp) ABORT(amx,AMX_ERR_MEMACCESS); if (alt>=hea && alt<stk || (ucell)alt>=(ucell)amx->stp) ABORT(amx,AMX_ERR_MEMACCESS); if ((alt+offs)>hea && (alt+offs)<stk || (ucell)(alt+offs)>(ucell)amx->stp) ABORT(amx,AMX_ERR_MEMACCESS); #if defined _R_DEFAULT memcpy(data+(int)alt, data+(int)pri, (int)offs); #else for (i=0; i+4<offs; i+=4) { val=_R32(data,pri+i); _W32(data,alt+i,val); } /* for */ for ( ; i<offs; i++) { val=_R8(data,pri+i); _W8(data,alt+i,val); } /* for */ #endif NEXT(cip,op); op_cmps: GETPARAM(offs); __cmps: /* verify top & bottom memory addresses, for both source and destination * addresses */ if (pri>=hea && pri<stk || (ucell)pri>=(ucell)amx->stp) ABORT(amx,AMX_ERR_MEMACCESS); if ((pri+offs)>hea && (pri+offs)<stk || (ucell)(pri+offs)>(ucell)amx->stp) ABORT(amx,AMX_ERR_MEMACCESS); if (alt>=hea && alt<stk || (ucell)alt>=(ucell)amx->stp) ABORT(amx,AMX_ERR_MEMACCESS); if ((alt+offs)>hea && (alt+offs)<stk || (ucell)(alt+offs)>(ucell)amx->stp) ABORT(amx,AMX_ERR_MEMACCESS); #if defined _R_DEFAULT pri=memcmp(data+(int)alt, data+(int)pri, (int)offs); #else pri=0; for (i=0; i+4<offs && pri==0; i+=4) pri=_R32(data,alt+i)-_R32(data,pri+i); for ( ; i<offs && pri==0; i++) pri=_R8(data,alt+i)-_R8(data,pri+i); #endif NEXT(cip,op); op_fill: GETPARAM(offs); __fill: /* verify top & bottom memory addresses */ if (alt>=hea && alt<stk || (ucell)alt>=(ucell)amx->stp) ABORT(amx,AMX_ERR_MEMACCESS); if ((alt+offs)>hea && (alt+offs)<stk || (ucell)(alt+offs)>(ucell)amx->stp) ABORT(amx,AMX_ERR_MEMACCESS); for (i=(int)alt; offs>=(int)sizeof(cell); i+=sizeof(cell), offs-=sizeof(cell)) _W32(data,i,pri); NEXT(cip,op); op_halt: GETPARAM(offs); __halt: if (retval!=NULL) *retval=pri; /* store complete status (stk and hea are already set in the ABORT macro) */ amx->frm=frm; amx->pri=pri; amx->alt=alt; amx->cip=(cell)((unsigned char*)cip-amx->code); if (offs==AMX_ERR_SLEEP) { amx->stk=stk; amx->hea=hea; amx->reset_stk=reset_stk; amx->reset_hea=reset_hea; return (int)offs; } /* if */ ABORT(amx,(int)offs); op_bounds: GETPARAM(offs); if ((ucell)pri>(ucell)offs) { amx->cip=(cell)((unsigned char *)cip-amx->code); ABORT(amx,AMX_ERR_BOUNDS); } /* if */ NEXT(cip,op); op_sysreq: GETPARAM(offs); /* save a few registers */ amx->cip=(cell)((unsigned char *)cip-amx->code); amx->hea=hea; amx->frm=frm; amx->stk=stk; num=amx->callback(amx,offs,&pri,(cell *)(data+(int)stk)); if (num!=AMX_ERR_NONE) { if (num==AMX_ERR_SLEEP) { amx->pri=pri; amx->alt=alt; amx->reset_stk=reset_stk; amx->reset_hea=reset_hea; return num; } /* if */ ABORT(amx,num); } /* if */ NEXT(cip,op); op_switch: { cell *cptr=JUMPREL(cip)+1; /* +1, to skip the "casetbl" opcode */ cip=JUMPREL(cptr+1); /* preset to "none-matched" case */ num=(int)*cptr; /* number of records in the case table */ for (cptr+=2; num>0 && *cptr!=pri; num--,cptr+=2) /* nothing */; if (num>0) cip=JUMPREL(cptr+1); /* case found */ NEXT(cip,op); } op_swap_pri: offs=_R(data,stk); _W(data,stk,pri); pri=offs; NEXT(cip,op); op_swap_alt: offs=_R(data,stk); _W(data,stk,alt); alt=offs; NEXT(cip,op); op_break: assert((amx->flags & AMX_FLAG_VERIFY)==0); if (amx->debug!=NULL) { /* store status */ amx->frm=frm; amx->stk=stk; amx->hea=hea; amx->cip=(cell)((unsigned char*)cip-amx->code); num=amx->debug(amx); if (num!=AMX_ERR_NONE) { if (num==AMX_ERR_SLEEP) { amx->pri=pri; amx->alt=alt; amx->reset_stk=reset_stk; amx->reset_hea=reset_hea; return num; } /* if */ ABORT(amx,num); } /* if */ } /* if */ NEXT(cip,op); op_casetbl: assert(0); /* this should not occur during execution */ ABORT(amx,AMX_ERR_INVINSTR); op_sysreq_d: /* see op_sysreq */ #if !defined AMX_DONT_RELOCATE GETPARAM(offs); /* save a few registers */ amx->cip=(cell)((unsigned char *)cip-amx->code); amx->hea=hea; amx->frm=frm; amx->stk=stk; pri=((AMX_NATIVE)offs)(amx,(cell *)(data+(int)stk)); if (amx->error!=AMX_ERR_NONE) { if (amx->error==AMX_ERR_SLEEP) { amx->pri=pri; amx->alt=alt; amx->reset_stk=reset_stk; amx->reset_hea=reset_hea; return AMX_ERR_SLEEP; } /* if */ ABORT(amx,amx->error); } /* if */ NEXT(cip,op); #else ABORT(amx,AMX_ERR_INVINSTR); #endif op_sysreq_nd: /* see op_sysreq_n */ #if !defined AMX_NO_MACRO_INSTR && !defined AMX_DONT_RELOCATE GETPARAM(offs); GETPARAM(val); PUSH(val); /* save a few registers */ amx->cip=(cell)((unsigned char *)cip-amx->code); amx->hea=hea; amx->frm=frm; amx->stk=stk; pri=((AMX_NATIVE)offs)(amx,(cell *)(data+(int)stk)); stk+=val+4; if (amx->error!=AMX_ERR_NONE) { if (amx->error==AMX_ERR_SLEEP) { amx->pri=pri; amx->alt=alt; amx->stk=stk; amx->reset_stk=reset_stk; amx->reset_hea=reset_hea; return AMX_ERR_SLEEP; } /* if */ ABORT(amx,amx->error); } /* if */ NEXT(cip,op); #else ABORT(amx,AMX_ERR_INVINSTR); #endif /* overlay instructions */ #if !defined AMX_NO_OVERLAY op_call_ovl: offs=(unsigned char *)cip-amx->code+sizeof(cell); /* skip address */ assert(offs>=0 && offs<(1<<(sizeof(cell)*4))); PUSH((offs<<(sizeof(cell)*4)) | amx->ovl_index); amx->ovl_index=(int)*cip; assert(amx->overlay!=NULL); if ((num=amx->overlay(amx,amx->ovl_index))!=AMX_ERR_NONE) ABORT(amx,num); cip=(cell*)amx->code; NEXT(cip,op); op_retn_ovl: assert(amx->overlay!=NULL); POP(frm); POP(offs); amx->ovl_index=offs & (((ucell)~0)>>4*sizeof(cell)); offs=(ucell)offs >> (sizeof(cell)*4); /* verify the index */ stk+=_R(data,stk)+sizeof(cell); /* remove parameters from the stack */ num=amx->overlay(amx,amx->ovl_index); /* reload overlay */ if (num!=AMX_ERR_NONE || (long)offs>=amx->codesize) ABORT(amx,AMX_ERR_MEMACCESS); cip=(cell *)(amx->code+(int)offs); NEXT(cip,op); op_switch_ovl: { cell *cptr=JUMPREL(cip)+1; /* +1, to skip the "icasetbl" opcode */ amx->ovl_index=*(cptr+1); /* preset to "none-matched" case */ num=(int)*cptr; /* number of records in the case table */ for (cptr+=2; num>0 && *cptr!=pri; num--,cptr+=2) /* nothing */; if (num>0) amx->ovl_index=*(cptr+1); /* case found */ assert(amx->overlay!=NULL); if ((num=amx->overlay(amx,amx->ovl_index))!=AMX_ERR_NONE) ABORT(amx,num); cip=(cell*)amx->code; NEXT(cip,op); } #else op_call_ovl: op_retn_ovl: op_switch_ovl: ABORT(amx,AMX_ERR_INVINSTR); #endif op_casetbl_ovl: assert(0); /* this should not occur during execution */ ABORT(amx,AMX_ERR_INVINSTR); /* supplemental and macro instructions */ #if !defined AMX_NO_MACRO_INSTR op_lidx: offs=pri*sizeof(cell)+alt; /* implicit shift value for a cell */ /* verify address */ if (offs>=hea && offs<stk || (ucell)offs>=(ucell)amx->stp) ABORT(amx,AMX_ERR_MEMACCESS); pri=_R(data,offs); NEXT(cip,op); op_lidx_b: GETPARAM(offs); offs=(pri << (int)offs)+alt; /* verify address */ if (offs>=hea && offs<stk || (ucell)offs>=(ucell)amx->stp) ABORT(amx,AMX_ERR_MEMACCESS); pri=_R(data,offs); NEXT(cip,op); op_idxaddr: pri=pri*sizeof(cell)+alt; NEXT(cip,op); op_idxaddr_b: GETPARAM(offs); pri=(pri << (int)offs)+alt; NEXT(cip,op); op_push_c: GETPARAM(offs); PUSH(offs); NEXT(cip,op); op_push: GETPARAM(offs); PUSH(_R(data,offs)); NEXT(cip,op); op_push_s: GETPARAM(offs); PUSH(_R(data,frm+offs)); NEXT(cip,op); op_push_adr: GETPARAM(offs); PUSH(frm+offs); NEXT(cip,op); op_pushr_c: GETPARAM(offs); PUSH(data+offs); NEXT(cip,op); op_pushr_s: GETPARAM(offs); PUSH(data+_R(data,frm+offs)); NEXT(cip,op); op_pushr_adr: GETPARAM(offs); PUSH(data+frm+offs); NEXT(cip,op); op_jeq: if (pri==alt) cip=JUMPREL(cip); else SKIPPARAM(1); NEXT(cip,op); op_jneq: if (pri!=alt) cip=JUMPREL(cip); else SKIPPARAM(1); NEXT(cip,op); op_jsless: if (pri<alt) cip=JUMPREL(cip); else SKIPPARAM(1); NEXT(cip,op); op_jsleq: if (pri<=alt) cip=JUMPREL(cip); else SKIPPARAM(1); NEXT(cip,op); op_jsgrtr: if (pri>alt) cip=JUMPREL(cip); else SKIPPARAM(1); NEXT(cip,op); op_jsgeq: if (pri>=alt) cip=JUMPREL(cip); else SKIPPARAM(1); NEXT(cip,op); op_sdiv_inv: if (alt==0) ABORT(amx,AMX_ERR_DIVIDE); /* use floored division and matching remainder */ offs=alt; #if defined TRUNC_SDIV pri=pri/offs; alt=pri%offs; #else val=pri; /* portable routine for truncated division */ pri=IABS(pri)/IABS(offs); if ((cell)(val ^ offs)<0) pri=-pri; alt=val-pri*offs; /* calculate the matching remainder */ #endif /* now "fiddle" with the values to get floored division */ if (alt!=0 && (cell)(alt ^ offs)<0) { pri--; alt+=offs; } /* if */ NEXT(cip,op); op_sub_inv: pri-=alt; NEXT(cip,op); op_add_c: GETPARAM(offs); pri+=offs; NEXT(cip,op); op_smul_c: GETPARAM(offs); pri*=offs; NEXT(cip,op); op_zero_pri: pri=0; NEXT(cip,op); op_zero_alt: alt=0; NEXT(cip,op); op_zero: GETPARAM(offs); _W(data,offs,0); NEXT(cip,op); op_zero_s: GETPARAM(offs); _W(data,frm+offs,0); NEXT(cip,op); op_eq_c_pri: GETPARAM(offs); pri= pri==offs ? 1 : 0; NEXT(cip,op); op_eq_c_alt: GETPARAM(offs); pri= alt==offs ? 1 : 0; NEXT(cip,op); op_inc: GETPARAM(offs); #if defined _R_DEFAULT *(cell *)(data+(int)offs) += 1; #else val=_R(data,offs); _W(data,offs,val+1); #endif NEXT(cip,op); op_inc_s: GETPARAM(offs); #if defined _R_DEFAULT *(cell *)(data+(int)(frm+offs)) += 1; #else val=_R(data,frm+offs); _W(data,frm+offs,val+1); #endif NEXT(cip,op); op_dec: GETPARAM(offs); #if defined _R_DEFAULT *(cell *)(data+(int)offs) -= 1; #else val=_R(data,offs); _W(data,offs,val-1); #endif NEXT(cip,op); op_dec_s: GETPARAM(offs); #if defined _R_DEFAULT *(cell *)(data+(int)(frm+offs)) -= 1; #else val=_R(data,frm+offs); _W(data,frm+offs,val-1); #endif NEXT(cip,op); op_sysreq_n: GETPARAM(offs); GETPARAM(val); PUSH(val); /* save a few registers */ amx->cip=(cell)((unsigned char *)cip-amx->code); amx->hea=hea; amx->frm=frm; amx->stk=stk; num=amx->callback(amx,offs,&pri,(cell *)(data+(int)stk)); stk+=val+4; if (num!=AMX_ERR_NONE) { if (num==AMX_ERR_SLEEP) { amx->pri=pri; amx->alt=alt; amx->stk=stk; amx->reset_stk=reset_stk; amx->reset_hea=reset_hea; return num; } /* if */ ABORT(amx,num); } /* if */ NEXT(cip,op); op_pushm_c: GETPARAM(val); while (val--) { GETPARAM(offs); PUSH(offs); } /* while */ NEXT(cip,op); op_pushm: GETPARAM(val); while (val--) { GETPARAM(offs); PUSH(_R(data,offs)); } /* while */ NEXT(cip,op); op_pushm_s: GETPARAM(val); while (val--) { GETPARAM(offs); PUSH(_R(data,frm+offs)); } /* while */ NEXT(cip,op); op_pushm_adr: GETPARAM(val); while (val--) { GETPARAM(offs); PUSH(frm+offs); } /* while */ NEXT(cip,op); op_pushrm_c: GETPARAM(val); while (val--) { GETPARAM(offs); PUSH(data+offs); } /* while */ NEXT(cip,op); op_pushrm_s: GETPARAM(val); while (val--) { GETPARAM(offs); PUSH(data+_R(data,frm+offs)); } /* while */ NEXT(cip,op); op_pushrm_adr: GETPARAM(val); while (val--) { GETPARAM(offs); PUSH(data+frm+offs); } /* while */ NEXT(cip,op); op_load2: GETPARAM(offs); pri=_R(data,offs); GETPARAM(offs); alt=_R(data,offs); NEXT(cip,op); op_load2_s: GETPARAM(offs); pri=_R(data,frm+offs); GETPARAM(offs); alt=_R(data,frm+offs); NEXT(cip,op); op_const: GETPARAM(offs); GETPARAM(val); _W(data,offs,val); NEXT(cip,op); op_const_s: GETPARAM(offs); GETPARAM(val); _W(data,frm+offs,val); NEXT(cip,op); #endif #if !defined AMX_NO_PACKED_OPC op_load_p_pri: GETPARAM_P(offs,op); pri=_R(data,offs); NEXT(cip,op); op_load_p_alt: GETPARAM_P(offs,op); alt=_R(data,offs); NEXT(cip,op); op_load_p_s_pri: GETPARAM_P(offs,op); pri=_R(data,frm+offs); NEXT(cip,op); op_load_p_s_alt: GETPARAM_P(offs,op); alt=_R(data,frm+offs); NEXT(cip,op); op_lref_p_s_pri: GETPARAM_P(offs,op); offs=_R(data,frm+offs); pri=_R(data,offs); NEXT(cip,op); op_lref_p_s_alt: GETPARAM_P(offs,op); offs=_R(data,frm+offs); alt=_R(data,offs); NEXT(cip,op); op_lodb_p_i: GETPARAM_P(offs,op); goto __lodb_i; op_const_p_pri: GETPARAM_P(pri,op); NEXT(cip,op); op_const_p_alt: GETPARAM_P(alt,op); NEXT(cip,op); op_addr_p_pri: GETPARAM_P(pri,op); pri+=frm; NEXT(cip,op); op_addr_p_alt: GETPARAM_P(alt,op); alt+=frm; NEXT(cip,op); op_stor_p: GETPARAM_P(offs,op); _W(data,offs,pri); NEXT(cip,op); op_stor_p_s: GETPARAM_P(offs,op); _W(data,frm+offs,pri); NEXT(cip,op); op_sref_p_s: GETPARAM_P(offs,op); offs=_R(data,frm+offs); _W(data,offs,pri); NEXT(cip,op); op_strb_p_i: GETPARAM_P(offs,op); goto __strb_i; op_lidx_p_b: GETPARAM_P(offs,op); offs=(pri << (int)offs)+alt; /* verify address */ if (offs>=hea && offs<stk || (ucell)offs>=(ucell)amx->stp) ABORT(amx,AMX_ERR_MEMACCESS); pri=_R(data,offs); NEXT(cip,op); op_idxaddr_p_b: GETPARAM_P(offs,op); pri=(pri << (int)offs)+alt; NEXT(cip,op); op_align_p_pri: GETPARAM_P(offs,op); #if BYTE_ORDER==LITTLE_ENDIAN if ((size_t)offs<sizeof(cell)) pri ^= sizeof(cell)-offs; #endif NEXT(cip,op); op_push_p_c: GETPARAM_P(offs,op); PUSH(offs); NEXT(cip,op); op_push_p: GETPARAM_P(offs,op); PUSH(_R(data,offs)); NEXT(cip,op); op_push_p_s: GETPARAM_P(offs,op); PUSH(_R(data,frm+offs)); NEXT(cip,op); op_push_p_adr: GETPARAM_P(offs,op); PUSH(frm+offs); NEXT(cip,op); op_pushr_p_c: GETPARAM_P(offs,op); PUSH(data+offs); NEXT(cip,op); op_pushr_p_s: GETPARAM_P(offs,op); PUSH(data+_R(data,frm+offs)); NEXT(cip,op); op_pushr_p_adr: GETPARAM_P(offs,op); PUSH(data+frm+offs); NEXT(cip,op); op_pushm_p_c: GETPARAM_P(val,op); while (val--) { GETPARAM(offs); PUSH(offs); } /* while */ NEXT(cip,op); op_pushm_p: GETPARAM_P(val,op); while (val--) { GETPARAM(offs); PUSH(_R(data,offs)); } /* while */ NEXT(cip,op); op_pushm_p_s: GETPARAM_P(val,op); while (val--) { GETPARAM(offs); PUSH(_R(data,frm+offs)); } /* while */ NEXT(cip,op); op_pushm_p_adr: GETPARAM_P(val,op); while (val--) { GETPARAM(offs); PUSH(frm+offs); } /* while */ NEXT(cip,op); op_pushrm_p_c: GETPARAM_P(val,op); while (val--) { GETPARAM(offs); PUSH(data+offs); } /* while */ NEXT(cip,op); op_pushrm_p_s: GETPARAM_P(val,op); while (val--) { GETPARAM(offs); PUSH(data+_R(data,frm+offs)); } /* while */ NEXT(cip,op); op_pushrm_p_adr: GETPARAM_P(val,op); while (val--) { GETPARAM(offs); PUSH(data+frm+offs); } /* while */ NEXT(cip,op); op_stack_p: GETPARAM_P(offs,op); alt=stk; stk+=offs; CHKMARGIN(); CHKSTACK(); NEXT(cip,op); op_heap_p: GETPARAM_P(offs,op); alt=hea; hea+=offs; CHKMARGIN(); CHKHEAP(); NEXT(cip,op); op_shl_p_c_pri: GETPARAM_P(offs,op); pri<<=offs; NEXT(cip,op); op_shl_p_c_alt: GETPARAM_P(offs,op); alt<<=offs; NEXT(cip,op); op_add_p_c: GETPARAM_P(offs,op); pri+=offs; NEXT(cip,op); op_smul_p_c: GETPARAM_P(offs,op); pri*=offs; NEXT(cip,op); op_zero_p: GETPARAM_P(offs,op); _W(data,offs,0); NEXT(cip,op); op_zero_p_s: GETPARAM_P(offs,op); _W(data,frm+offs,0); NEXT(cip,op); op_eq_p_c_pri: GETPARAM_P(offs,op); pri= pri==offs ? 1 : 0; NEXT(cip,op); op_eq_p_c_alt: GETPARAM_P(offs,op); pri= alt==offs ? 1 : 0; NEXT(cip,op); op_inc_p: GETPARAM_P(offs,op); #if defined _R_DEFAULT *(cell *)(data+(int)offs) += 1; #else val=_R(data,offs); _W(data,offs,val+1); #endif NEXT(cip,op); op_inc_p_s: GETPARAM_P(offs,op); #if defined _R_DEFAULT *(cell *)(data+(int)(frm+offs)) += 1; #else val=_R(data,frm+offs); _W(data,frm+offs,val+1); #endif NEXT(cip,op); op_dec_p: GETPARAM_P(offs,op); #if defined _R_DEFAULT *(cell *)(data+(int)offs) -= 1; #else val=_R(data,offs); _W(data,offs,val-1); #endif NEXT(cip,op); op_dec_p_s: GETPARAM_P(offs,op); #if defined _R_DEFAULT *(cell *)(data+(int)(frm+offs)) -= 1; #else val=_R(data,frm+offs); _W(data,frm+offs,val-1); #endif NEXT(cip,op); op_movs_p: GETPARAM_P(offs,op); goto __movs; op_cmps_p: GETPARAM_P(offs,op); goto __cmps; op_fill_p: GETPARAM_P(offs,op); goto __fill; op_halt_p: GETPARAM_P(offs,op); goto __halt; op_bounds_p: GETPARAM_P(offs,op); if ((ucell)pri>(ucell)offs) { amx->cip=(cell)((unsigned char *)cip-amx->code); ABORT(amx,AMX_ERR_BOUNDS); } /* if */ NEXT(cip,op); #endif } void amx_exec_list(const AMX *amx,const cell **opcodelist,int *numopcodes) { /* since the opcode list of the GNU GCC version of the abstract machine core * must be a local variable (as it references code labels, which are local * too), we use a trick to get the opcode list: call amx_Exec() while a * special flags value is set in the AMX header. */ int orgflags; AMX *amxptr=(AMX*)amx; assert(amx!=NULL); assert(opcodelist!=NULL); assert(numopcodes!=NULL); orgflags=amx->flags; amxptr->flags=~0; *numopcodes=amx_exec_run(amxptr, (cell*)opcodelist, NULL); amxptr->flags=orgflags; }
void prim_regexp(PRIM_PROTOTYPE) { stk_array* nu_val = 0; stk_array* nu_idx = 0; int matches[MATCH_ARR_SIZE]; muf_re* re; char* text; int flags = 0; int len, i; int matchcnt = 0; const char* errstr; CHECKOP(3); oper3 = POP(); /* int:Flags */ oper2 = POP(); /* str:Pattern */ oper1 = POP(); /* str:Text */ if (oper1->type != PROG_STRING) abort_interp("Non-string argument (1)"); if (oper2->type != PROG_STRING) abort_interp("Non-string argument (2)"); if (oper3->type != PROG_INTEGER) abort_interp("Non-integer argument (3)"); if (!oper2->data.string) abort_interp("Empty string argument (2)"); if (oper3->data.number & MUF_RE_ICASE) flags |= PCRE_CASELESS; if (oper3->data.number & MUF_RE_EXTENDED) flags |= PCRE_EXTENDED; if ((re = muf_re_get(oper2->data.string, flags, &errstr)) == NULL) abort_interp(errstr); text = (char *)DoNullInd(oper1->data.string); len = strlen(text); if ((matchcnt = pcre_exec(re->re, re->extra, text, len, 0, 0, matches, MATCH_ARR_SIZE)) < 0) { if (matchcnt != PCRE_ERROR_NOMATCH) { abort_interp(muf_re_error(matchcnt)); } if (((nu_val = new_array_packed(0)) == NULL) || ((nu_idx = new_array_packed(0)) == NULL)) { if (nu_val != NULL) array_free(nu_val); if (nu_idx != NULL) array_free(nu_idx); abort_interp("Out of memory"); } } else { if (((nu_val = new_array_packed(matchcnt)) == NULL) || ((nu_idx = new_array_packed(matchcnt)) == NULL)) { if (nu_val != NULL) array_free(nu_val); if (nu_idx != NULL) array_free(nu_idx); abort_interp("Out of memory"); } for(i = 0; i < matchcnt; i++) { int substart = matches[i*2]; int subend = matches[i*2+1]; struct inst idx, val; stk_array* nu; if ((substart >= 0) && (subend >= 0) && (substart < len)) snprintf(buf, BUFFER_LEN, "%.*s", (int)(subend - substart), &text[substart]); else buf[0] = '\0'; idx.type = PROG_INTEGER; idx.data.number = i; val.type = PROG_STRING; val.data.string = alloc_prog_string(buf); array_setitem(&nu_val, &idx, &val); CLEAR(&idx); CLEAR(&val); if ((nu = new_array_packed(2)) == NULL) { array_free(nu_val); array_free(nu_idx); abort_interp("Out of memory"); } idx.type = PROG_INTEGER; idx.data.number = 0; val.type = PROG_INTEGER; val.data.number = substart + 1; array_setitem(&nu, &idx, &val); CLEAR(&idx); CLEAR(&val); idx.type = PROG_INTEGER; idx.data.number = 1; val.type = PROG_INTEGER; val.data.number = subend - substart; array_setitem(&nu, &idx, &val); CLEAR(&idx); CLEAR(&val); idx.type = PROG_INTEGER; idx.data.number = i; val.type = PROG_ARRAY; val.data.array = nu; array_setitem(&nu_idx, &idx, &val); CLEAR(&idx); CLEAR(&val); } } CLEAR(oper3); CLEAR(oper2); CLEAR(oper1); PushArrayRaw(nu_val); PushArrayRaw(nu_idx); }
void prim_array_regsub(PRIM_PROTOTYPE) { struct inst *in; stk_array *arr; stk_array *nw; int matches[MATCH_ARR_SIZE]; int flags = 0; char* write_ptr = buf; int write_left = BUFFER_LEN - 1; muf_re* re; char* text; char* textstart; const char* errstr; int matchcnt, len; CHECKOP(4); oper4 = POP(); /* int:Flags */ oper3 = POP(); /* str:Replace */ oper2 = POP(); /* str:Pattern */ oper1 = POP(); /* str:Text */ if (oper1->type != PROG_ARRAY) abort_interp("Argument not an array of strings. (1)"); if (!array_is_homogenous(oper1->data.array, PROG_STRING)) abort_interp("Argument not an array of strings. (1)"); if (oper2->type != PROG_STRING) abort_interp("Non-string argument (2)"); if (oper3->type != PROG_STRING) abort_interp("Non-string argument (3)"); if (oper4->type != PROG_INTEGER) abort_interp("Non-integer argument (4)"); if (!oper2->data.string) abort_interp("Empty string argument (2)"); if (oper4->data.number & MUF_RE_ICASE) flags |= PCRE_CASELESS; if (oper4->data.number & MUF_RE_EXTENDED) flags |= PCRE_EXTENDED; if ((re = muf_re_get(oper2->data.string, flags, &errstr)) == NULL) abort_interp(errstr); nw = new_array_dictionary(); arr = oper1->data.array; if (!re->extra && ((oper4->data.number & MUF_RE_ALL ) || array_count(arr) > 2)) { /* Study the pattern if the user requested recursive substitution, or * if the input array contains at least three items. */ re->extra = pcre_study(re->re, 0, &errstr); if (errstr) abort_interp(errstr); } if (array_first(arr, &temp1)) { do { write_ptr = buf; write_left = BUFFER_LEN - 1; in = array_getitem(arr, &temp1); textstart = text = (char *)DoNullInd(in->data.string); len = strlen(textstart); while((*text != '\0') && (write_left > 0)) { if ((matchcnt = pcre_exec(re->re, re->extra, textstart, len, text-textstart, 0, matches, MATCH_ARR_SIZE)) < 0) { if (matchcnt != PCRE_ERROR_NOMATCH) { abort_interp(muf_re_error(matchcnt)); } while((write_left > 0) && (*text != '\0')) { *write_ptr++ = *text++; write_left--; } break; } else { int allstart = matches[0]; int allend = matches[1]; int substart = -1; int subend = -1; char* read_ptr = (char *)DoNullInd(oper3->data.string); int count; for(count = allstart-(text-textstart); (write_left > 0) && (*text != '\0') && (count > 0); count--) { *write_ptr++ = *text++; write_left--; } while((write_left > 0) && (*read_ptr != '\0')) { if (*read_ptr == '\\') { if (!isdigit(*(++read_ptr))) { *write_ptr++ = *read_ptr++; write_left--; } else { int idx = (*read_ptr++) - '0'; if ((idx < 0) || (idx >= matchcnt)) { abort_interp("Invalid \\subexp in substitution string. (3)"); } substart = matches[idx*2]; subend = matches[idx*2+1]; if ((substart >= 0) && (subend >= 0) && (substart < len)) { char* ptr = &textstart[substart]; count = subend - substart; if (count > write_left) { abort_interp("Operation would result in overflow"); } for(; (write_left > 0) && (count > 0) && (*ptr != '\0'); count--) { *write_ptr++ = *ptr++; write_left--; } } } } else { *write_ptr++ = *read_ptr++; write_left--; } } for(count = allend - allstart; (*text != '\0') && (count > 0); count--) text++; if (allstart == allend && *text) { *write_ptr++ = *text++; write_left--; } } if ((oper4->data.number & MUF_RE_ALL) == 0) { while((write_left > 0) && (*text != '\0')) { *write_ptr++ = *text++; write_left--; } break; } } if (*text != '\0') abort_interp("Operation would result in overflow"); *write_ptr = '\0'; temp2.type = PROG_STRING; temp2.data.string = alloc_prog_string(buf); array_setitem(&nw, &temp1, &temp2); CLEAR(&temp2); } while (array_next(arr, &temp1)); } CLEAR(oper4); CLEAR(oper3); CLEAR(oper2); CLEAR(oper1); PushArrayRaw(nw); }
term_t eval_term(struct lisp0_state*state,term_t term){ X = term; CALL(L_eval); return X; L_eval: if(IS_ERROR(X)){ RETURN(X); } if(IS_ATOM(X)){ RETURN(subst(ENV,X)); } if(!IS_LIST(X)){ RETURN(ERR(E_BAD_EXPR)); } PUSH(CDR(X)); X = CAR(X); CALL(L_eval); Y = POP(); switch(TAG(X)){ case TAG_ERROR: RETURN(X); case TAG_PRIMITIVE: switch(VALUE(X)){ case PRIM_QUOTE: goto L_quote; case PRIM_ATOM: goto L_atom; case PRIM_EQ: goto L_eq; case PRIM_COND: goto L_cond; case PRIM_CAR: goto L_car; case PRIM_CDR: goto L_cdr; case PRIM_CONS: goto L_cons; case PRIM_LABEL: goto L_label; case PRIM_LAMBDA: goto L_lambda; case PRIM_MACRO: goto L_macro; default: break; }; break; case TAG_POINTER: if(!X) break; switch(PTAG(X)){ case PTAG_LAMBDA: goto L_eval_lambda; case PTAG_MACRO: goto L_eval_macro; default: break; }; default: break; } RETURN(ERR(E_NOT_CALLABLE)); L_quote: PARSE_ARG1(); RETURN(X); L_atom: PARSE_AND_EVAL_ARG1(); RETURN(((!X)||IS_ATOM(X))?TRUE:FALSE); L_eq: PARSE_AND_EVAL_ARG2(); RETURN(eq(Y,X)?TRUE:FALSE); L_cond: PARSE_ARG(); PUSH(CDR(Y)); Y = CAR(Y); PARSE_ARG2(); PUSH(Y); CLEAR(Y); CALL(L_eval); Y = POP(); switch(X){ case TRUE: X = Y; CLEAR(Y); goto L_eval; case FALSE: Y = POP(); goto L_cond; default: RETURN(ERR(E_COND_END)); }; L_car: PARSE_AND_EVAL_ARG1(); if(!IS_LIST(X)){ RETURN(ERR(E_ARGUMENT)); } RETURN(CAR(X)); L_cdr: PARSE_AND_EVAL_ARG1(); if(!IS_LIST(X)){ RETURN(ERR(E_ARGUMENT)); } RETURN(CDR(X)); L_cons: PARSE_AND_EVAL_ARG2(); L_cons_1: RETURN(cons(state,Y,X)); L_label: PARSE_ARG2(); PUSH(X); X = Y; CLEAR(Y); CALL(L_eval); RETURN_ERROR(X); Y = POP(); CALL(L_cons_1); Y = X; X = ENV; CALL(L_cons_1); ENV = X; RETURN(CDR(CAR(ENV))); L_lambda: PARSE_ARG2(); RETURN(mklist(state,X,Y,PTAG_LAMBDA)); L_macro: PARSE_ARG2(); RETURN(mklist(state,X,Y,PTAG_MACRO)); L_eval_lambda: PUSH(X); push_list_builder(state); CALL(L_eval_list); Y = pop_list_builder(state,NIL); RETURN_ERROR(X); X = POP(); PUSH(CDR(X)); X = CAR(X); push_list_builder(state); CALL(L_zip); Y = POP(); PUSH(ENV); ENV = pop_list_builder(state,ENV); RETURN_ERROR(X); X = Y; CLEAR(Y); CALL(L_eval); RETURN_ERROR(ENV); ENV = POP(); RETURN(X); L_eval_list: if(!Y){ RETURN(Y); } PARSE_ARG(); X = CAR(Y); PUSH(CDR(Y)); CLEAR(Y); CALL(L_eval); RETURN_ERROR(X); list_builder_add_term(state,X); Y = POP(); goto L_eval_list; L_eval_macro: PUSH(CDR(X)); X = CAR(X); push_list_builder(state); CALL(L_zip); Y = POP(); PUSH(ENV); ENV = pop_list_builder(state,ENV); RETURN_ERROR(X); X = Y; CLEAR(Y); CALL(L_eval); ENV = POP(); goto L_eval; L_zip: if((!X)||(!Y)) goto L_zip_finish; RETURN_ERROR(X); RETURN_ERROR(Y); if(!IS_LIST(X)){ RETURN(ERR(E_IMPROPER_LIST)); } if(!IS_LIST(Y)){ RETURN(ERR(E_IMPROPER_LIST)); } list_builder_add_term(state,cons(state,CAR(X),CAR(Y))); X = CDR(X); Y = CDR(Y); goto L_zip; L_zip_finish: if(X||Y){ RETURN(ERR(E_ARGUMENT)); } RETURN(NIL); }
void ifpack_multilist_sort (int *const pbase, double *const daux, size_t total_elems) { int itemp; double dtemp; const size_t size = 1; register int *base_ptr = (int *) pbase; /* Allocating SIZE bytes for a pivot buffer facilitates a better algorithm below since we can do comparisons directly on the pivot. */ int pivot_buffer[1]; const size_t max_thresh = MAX_THRESH * size; /* edmond: return if total_elems less than zero */ if (total_elems <= 0) /* Avoid lossage with unsigned arithmetic below. */ return; if (total_elems > MAX_THRESH) { int *lo = base_ptr; int *hi = &lo[size * (total_elems - 1)]; /* Largest size needed for 32-bit int!!! */ stack_node stack[STACK_SIZE]; stack_node *top = stack + 1; while (STACK_NOT_EMPTY) { int *left_ptr; int *right_ptr; int *pivot = pivot_buffer; /* Select median value from among LO, MID, and HI. Rearrange LO and HI so the three values are sorted. This lowers the probability of picking a pathological pivot value and skips a comparison for both the LEFT_PTR and RIGHT_PTR. */ int *mid = lo + size * ((hi - lo) / size >> 1); if (*mid - *lo < 0) SWAP (mid, lo); if (*hi - *mid < 0) SWAP (mid, hi); else goto jump_over; if (*mid - *lo < 0) SWAP (mid, lo); jump_over:; *pivot = *mid; pivot = pivot_buffer; left_ptr = lo + size; right_ptr = hi - size; /* Here's the famous ``collapse the walls'' section of quicksort. Gotta like those tight inner loops! They are the main reason that this algorithm runs much faster than others. */ do { while (*left_ptr - *pivot < 0) left_ptr += size; while (*pivot - *right_ptr < 0) right_ptr -= size; if (left_ptr < right_ptr) { SWAP (left_ptr, right_ptr); left_ptr += size; right_ptr -= size; } else if (left_ptr == right_ptr) { left_ptr += size; right_ptr -= size; break; } } while (left_ptr <= right_ptr); /* Set up pointers for next iteration. First determine whether left and right partitions are below the threshold size. If so, ignore one or both. Otherwise, push the larger partition's bounds on the stack and continue sorting the smaller one. */ if ((size_t) (right_ptr - lo) <= max_thresh) { if ((size_t) (hi - left_ptr) <= max_thresh) /* Ignore both small partitions. */ POP (lo, hi); else /* Ignore small left partition. */ lo = left_ptr; } else if ((size_t) (hi - left_ptr) <= max_thresh) /* Ignore small right partition. */ hi = right_ptr; else if ((right_ptr - lo) > (hi - left_ptr)) { /* Push larger left partition indices. */ PUSH (lo, right_ptr); lo = left_ptr; } else { /* Push larger right partition indices. */ PUSH (left_ptr, hi); hi = right_ptr; } } }
static int esil_commit (RAnalEsil *c, const char *op) { const char *q = POP(); const char *p = POP(); //const char *o = op; int ss = c->opsize; if (ss) { // eprintf (";; GET %d[%s]\n", ss, q); // eprintf ("PSUH %s %s\n", p, q); eprintf (";; -> this means that we have to resolve before accessing memory %d\n", c->opsize); c->opsize = 0; PUSH (p); PUSH (q); return 0; } if (!op) { eprintf ("COMMIT UNKNOWN OP.. THIs IS []\n"); return 0; } //eprintf (";;; COMMIT ;;; (%s) %s (%s)\n", p, o, q); if (IS ("[=")) { eprintf ("EQUAL------SET\n"); } else if (IS ("+")) { // push (get (p)+get (q)); ut64 n = esil_get (c, p) + esil_get (c, q); char *ns = malloc (32); // XXX memleak sprintf (ns, "0x%"PFMT64x, n); PUSH (ns); eprintf (";;; %s %s\n", p, q); //eprintf (" (((0x%llx)))\n", esil_get (c, p)); eprintf (";;; +EQUAL! (%s)\n", ns); } else if (IS ("-")) { // push (get (p)+get (q)); ut64 n = esil_get (c, p) - esil_get (c, q); char *ns = malloc (32); // XXX memleak sprintf (ns, "0x%"PFMT64x, n); PUSH (ns); eprintf (";;; %s %s\n", p, q); eprintf (";;; -EQUAL! (%s)\n", ns); } else if (IS ("*")) { // push (get (p)+get (q)); ut64 n = esil_get (c, p) * esil_get (c, q); char *ns = malloc (32); // XXX memleak sprintf (ns, "0x%"PFMT64x, n); PUSH (ns); eprintf (";;; %s %s\n", p, q); eprintf (";;; *EQUAL! (%s)\n", ns); } if (IS ("=")) { if (p == NULL || q == NULL) { eprintf ("Invalid construction\n"); return -1; } // set (p, get (q)) c->set (c, p, c->get (c, q)); eprintf (";;; EQUAL! (%s=%s)\n", p, q); } return 0; }
static int toyvm_function_interpret (toyvm_function *fn, int arg, FILE *trace) { toyvm_frame frame; #define PUSH(ARG) (toyvm_frame_push (&frame, (ARG))) #define POP(ARG) (toyvm_frame_pop (&frame)) frame.frm_function = fn; frame.frm_pc = 0; frame.frm_cur_depth = 0; PUSH (arg); while (1) { toyvm_op *op; int x, y; assert (frame.frm_pc < fn->fn_num_ops); op = &fn->fn_ops[frame.frm_pc++]; if (trace) { toyvm_frame_dump_stack (&frame, trace); toyvm_function_disassemble_op (fn, op, frame.frm_pc, trace); } switch (op->op_opcode) { /* Ops taking no operand. */ case DUP: x = POP (); PUSH (x); PUSH (x); break; case ROT: y = POP (); x = POP (); PUSH (y); PUSH (x); break; case BINARY_ADD: y = POP (); x = POP (); PUSH (x + y); break; case BINARY_SUBTRACT: y = POP (); x = POP (); PUSH (x - y); break; case BINARY_MULT: y = POP (); x = POP (); PUSH (x * y); break; case BINARY_COMPARE_LT: y = POP (); x = POP (); PUSH (x < y); break; case RECURSE: x = POP (); x = toyvm_function_interpret (fn, x, trace); PUSH (x); break; case RETURN: return POP (); /* Ops taking an operand. */ case PUSH_CONST: PUSH (op->op_operand); break; case JUMP_ABS_IF_TRUE: x = POP (); if (x) frame.frm_pc = op->op_operand; break; default: assert (0); /* unknown opcode */ } /* end of switch on opcode */ } /* end of while loop */ #undef PUSH #undef POP }
void Agc_trace( SEGCTLPTR *heap_segments ) { AREA heap; AREA area; /* The current area being traced */ TRACINGSTACK tstack; /* Stack of areas to be traced */ SEGCTLPTR segctlp; SEGCTLPTR *segctlpp; SIZE temp; #ifndef A_FUNNY_STEPAREAPTR /* cop-out for weird architectures */ { /* Check that STEPAREAPTR works correctly on this machine for this nastily aligned structure */ /* If C compiler does tight packing, this could be a problem for the garbage collector */ ASSERT_DECL( struct { PTR p1; char c; PTR p2; } *ass_struct = NIL ) ASSERT_INIT( ( area.addr = (PTR)&ass_struct->c , area.size = sizeof(*ass_struct) ) ); ASSERT_INIT( STEPAREA( area ) ); ASSERT(area.addr == (PTR)&ass_struct->p2,Agc_collect,STEPAREA misbehaving); } #endif heap.addr = SEGSTART( *heap_segments ); heap.size = 0 ;/* inital values to be improved in loop*/ REPORT1(3, "%s\n", "Started trace... setting up bitmaps..."); for ( segctlp = *heap_segments; segctlp != NIL; segctlp = segctlp->next ) { REPORT6(6,"Agc_collect{mark}: segctlp=0x%p, elsize=%d, start=0x%p, end=0x%p, size=%d,els=%d\n", (void *)segctlp,SEGELSIZE(segctlp),(void *)SEGSTART(segctlp),(void *)SEGEND(segctlp),SEGSIZE(segctlp),SEGELS(segctlp)); if ( ! ( SEGELSIZE( segctlp ) > 0 && (char *)SEGEND( segctlp ) > (char *)SEGSTART( segctlp ) ) ) { /* Segment control information has been corrupted. */ /* Most likely this is because of a user scope/bound error, or CTRANS bug; though possibly a collector bug. */ GC_ERROR(HEAP segments corrupt); } if ( (char *)SEGSTART( segctlp ) < (char *)(heap.addr) ) { heap.size += (SIZE)((char *)(heap.addr) - (char *)SEGSTART( segctlp )); heap.addr = SEGSTART( segctlp ); } if ( SEGEND( segctlp ) > (PTR)((char *)(heap.addr)+heap.size) ) heap.size = (SIZE)((char *)SEGEND( segctlp ) - (char*)(heap.addr)); GRAB_BITMAP( segctlp->bitmap, SEGELS( segctlp ) + 3 ); SETMARK( segctlp->bitmap, SEGELS( segctlp ) + 0 ); ASSERT(!TSTMARK(segctlp->bitmap,SEGELS(segctlp)+1),Agc_collect,bitmap trailer set at grab); SETMARK( segctlp->bitmap, SEGELS( segctlp ) + 2 ); /* create an artificial endpoint which can be scanned to */ REPORT2(6,"Agc_collect:\t\tbitmap, ptr=0x%p, size=%d\n", (void *)(segctlp->bitmap), SEGELS( segctlp )); } REPORT2(5,"Agc_collect: heap address=0x%p, heap size=%d\n",(void *)heap.addr,heap.size); INIT_STACK(tstack); ASSERT_INIT(PUSH(tstack,(PTR)Agc_collect,-42)); /* Assertion mark */ PUSH(tstack, NIL, 0); /* identifies exhausted stack */ REPORT1(3, "%s\n", "Initialising stack scan..."); INIT_AREA(area); /* set area to first area to search - could also PUSH any additional areas (or use NEXT_AREA) */ do { for ( ; !NILAREA(area); /* POP() at end of loop as it may contain statements */ ) { REPORT3(6,"Agc_collect: AREA scan, ptr=0x%p -> 0x%p, size=%d\n", (void *)area.addr,(void *)((char *)area.addr+area.size),area.size); ASSERT(area.size >= 0 && area.size < 100*1024*1024 /* 100Mb */,Agc_collect,area size not sensible); for ( ; area.size >= sizeof(PTR); STEPAREA(area) ) { SIZE els, el_in_seg; PTR p = * (PTR *) area.addr; /* View word as a pointer */ REPORT3(9,"Agc_collect: AREA scan step, ptr=0x%p, size=%d, p=0x%p\n", (void *)area.addr,area.size,(void *)p); /* Continue loop if 'p' is unlikely to be a heap pointer. */ /* Keeping the loop small may help some machines with small instruction caches. */ if ( !VALIDPTR( p ) || !PTRINAREA(p,heap) ) continue; /* p is very likely to be a heap pointer */ for ( segctlpp = heap_segments; (segctlp = *segctlpp) != NIL; segctlpp = &((segctlp)->next )) { if ( (char *)p >= (char *)SEGSTART(segctlp) && (char *)p < (char *)SEGEND(segctlp) ) { /* Segment for heap pointer */ goto found_segment; } } /* Not a valid heap pointer */ continue; /* back to STEPAREA loop */ found_segment: REPORT3(6,"Agc_collect, found_segment: ptr=0x%p, segctlp=0x%p, elsize=%d\n", (void *)p,(void *)segctlp,SEGELSIZE(segctlp)); /* ** Move segment to front of segment list, to effect a 'cacheing' as in allocation. ** We believe that there is locality in types of heap pointers, ** (consider lists and trees) so it is likely that next ** lookup will immediately succeed. ** However a fast search startegy might be better ??? ** ** Note that typical programs only have a small number of segs, ** many of which are infrequently used. ** Multics Algol68 compiler uses 12 segs; ** ELLA uses ??? segs. */ *segctlpp = segctlp->next; segctlp->next = *heap_segments; *heap_segments = segctlp; #ifdef MUST_POINT_TO_WORD /* * Ignore pointers that are not word aligned, * unless in a segment of objects of size that is not a multiple of word. */ if ( (SEGELSIZE(segctlp) & (WORDSIZE-1)) == 0 && (((CODEDPTR)(p) & (WORDSIZE-1)) != 0) ) continue; /* p not to word aligned object, forget it */ #endif #ifdef MUST_POINT_TO_LWORD /* * Ignore pointers that are not long word aligned, * unless in a segment of objects of size that is not a multiple of long word. */ if ( (SEGELSIZE(segctlp) & (sizeof(long)-1)) == 0 && (((CODEDPTR)(p) & (sizeof(long)-1)) != 0) ) continue; /* p not to long aligned object, forget it */ #endif IDENTIFY_ALIGN_EL( p, el_in_seg, segctlp ); #ifdef MUST_POINT_TO_START /* Ignore pointers that point within objects */ /* This could be implemented more efficiently */ if ( p != * (PTR *) area.addr ) continue; /* p not to start of element, forget it */ #endif #ifdef NO_GCMARK els = 1; #else ANAL_DESC( els, p, area ); #endif REPORT3(6,"Agc_collect, aligned and analysed ptr: ptr=0x%p, element in seg=%d, elements=%d\n", (void *)p,el_in_seg,els); #ifdef A_GC_HALFWORD_ALIGNED /* Interpret this as half word aligned (2byte) DJS 8/12/94 */ /* +++ !!! ??? ** Crappy quick fix to keep elements word aligned for the Apollo ** (also done for Sun/68000, though it has not been proved that this is necessary). ** Apollo does not permit word objects to be aligned at any byte boundry, ** even though 68020/68030 does. This must be because C compiler generates ** strange code, or page faults for words that straddle page boundries are ** handled badly. */ if ( SEGELSIZE(segctlp) == 1 ) { if ( (long)p & 1 ) { p--; el_in_seg--; els++; } if ( els & 1 ) { els++; } if ( els <= 1 || els > SEGELS(segctlp) || p+(els*SEGELSIZE(segctlp)) > SEGEND(segctlp) ) { els = 2; } REPORT3(6,"Agc_collect, adjusted to: ptr=0x%x, element in seg=%d, elements=%d\n", p,el_in_seg,els); goto els_sensible; } #endif #ifdef A_GC_WORD_ALIGNED /* +++ !!! ??? ** Crappy quick fix to keep elements word aligned. */ if ( SEGELSIZE(segctlp) == 1 ) { if ( !WORDALIGNED(p) ) { int offset = (int)((CODEDPTR)p & (WORDSIZE-1)); p = (char *)p - offset; el_in_seg -= offset; els += offset; } if ( !WORDALIGNED(els) ) { els = (SIZE)ALIGN_NEXT(els,WORDSIZE); } if ( (els < WORDSIZE) || (els > SEGELS(segctlp)) || ((char *)p+(els*SEGELSIZE(segctlp)) > (char *)SEGEND(segctlp) )) { els = WORDSIZE; } REPORT3(6,"Agc_collect, adjusted to: ptr=0x%p, element in seg=%d, elements=%d\n", (void *)p,el_in_seg,els); goto els_sensible; } #endif /* 'els' may be a very silly number, check it is reasonable */ /* before doing arithmetic that may overflow. */ if ( els <= 1 || els > SEGELS(segctlp) || (char *)p+(els*SEGELSIZE(segctlp)) > (char *)SEGEND(segctlp) ) { /* els = 1; assumed in case array descriptor mis analysed, the ptr is still valid */ if ( !TSTMARK( segctlp->bitmap, el_in_seg ) ) { SETMARK( segctlp->bitmap, el_in_seg ); if ( SEGELSIZE(segctlp) >= PTRSIZE ) { /* need only scan elements that are large enough to hold pointer */ PUSH( tstack, p, SEGELSIZE(segctlp) ); REPORT2(6,"Agc_collect: PUSH( ptr=0x%p, size=%d )\n", (void *)p,SEGELSIZE(segctlp)); } } } else { els_sensible: CALCTSTMARKS( segctlp->bitmap, el_in_seg, els, temp ); if ( !RESTSTMARKS( segctlp->bitmap, el_in_seg, els, temp ) ) { /* ** At least one element in area has not been marked before. ** ** We could just mark and push unmarked areas, ** but this complicates logic for a fairly rare eventuality, ** mainly caused by the trimming of heap rows. */ SETMARKS( segctlp->bitmap, el_in_seg, els ); if ( SEGELSIZE(segctlp) >= PTRSIZE ) { /* need only scan elements that are large enough to hold pointer */ PUSH( tstack, p, els*SEGELSIZE(segctlp) ); REPORT2(6,"Agc_collect: PUSH( ptr=0x%p, size=%d )\n", (void *)p,els*SEGELSIZE(segctlp)); } } } } area = POP(tstack); } /* Stack is exhausted, replace end marker */ PUSH(tstack, NIL, 0); /* identifies exhausted stack */ NEXT_AREA(area); REPORT2(6,"Agc_collect: NEXT_AREA, ptr=0x%p, size=%d\n",(void *)area.addr,area.size); } while( area.addr != NIL ); area = POP(tstack); /* pop of (NIL, 0) to leave stack empty and tidy before calling FREE_STACK() */ ASSERT_INIT( area=POP(tstack) ); ASSERT(area.addr == (PTR)Agc_collect && area.size == -42,Agc_collect,tracing stack misuse); FREE_STACK(tstack); REPORT1(3, "%s\n", "End of trace"); }
void qsort( void * base, size_t nmemb, size_t size, int (*compar)( const void *, const void * ) ) { char * i; char * j; _PDCLIB_size_t thresh = T * size; char * base_ = (char *)base; char * limit = base_ + nmemb * size; PREPARE_STACK; for ( ;; ) { if ( (size_t)( limit - base_ ) > thresh ) /* QSort for more than T elements. */ { /* We work from second to last - first will be pivot element. */ i = base_ + size; j = limit - size; /* We swap first with middle element, then sort that with second and last element so that eventually first element is the median of the three - avoiding pathological pivots. TODO: Instead of middle element, chose one randomly. */ memswp( ( ( ( (size_t)( limit - base_ ) ) / size ) / 2 ) * size + base_, base_, size ); if ( compar( i, j ) > 0 ) memswp( i, j, size ); if ( compar( base_, j ) > 0 ) memswp( base_, j, size ); if ( compar( i, base_ ) > 0 ) memswp( i, base_, size ); /* Now we have the median for pivot element, entering main Quicksort. */ for ( ;; ) { do { /* move i right until *i >= pivot */ i += size; } while ( compar( i, base_ ) < 0 ); do { /* move j left until *j <= pivot */ j -= size; } while ( compar( j, base_ ) > 0 ); if ( i > j ) { /* break loop if pointers crossed */ break; } /* else swap elements, keep scanning */ memswp( i, j, size ); } /* move pivot into correct place */ memswp( base_, j, size ); /* larger subfile base / limit to stack, sort smaller */ if ( j - base_ > limit - i ) { /* left is larger */ PUSH( base_, j ); base_ = i; } else { /* right is larger */ PUSH( i, limit ); limit = j; } } else /* insertion sort for less than T elements */ { for ( j = base_, i = j + size; i < limit; j = i, i += size ) { for ( ; compar( j, j + size ) > 0; j -= size ) { memswp( j, j + size, size ); if ( j == base_ ) { break; } } } if ( stackptr != stack ) /* if any entries on stack */ { POP( base_, limit ); } else /* else stack empty, done */ { break; } } } }
int main(int argc, char *argv[]) { //sgenrand(time(NULL)); int k, curr_pos, check; int chunk; /* Repeat experiment in chunks. */ srand(SEED); printf("# Info: $Header: /home/ma/p/pruess/.cvsroot/manna_range/dmitry_20151021/manna_stack_clean_edited.c,v 1.2 2015/10/21 11:37:00 pruess Exp $\n"); preamble(argc, argv); PRINT_PARAM(SEED, "%lu"); PRINT_PARAM(LENGTH, "%lu"); PRINT_PARAM(DROP_LOCATION, "%lu"); PRINT_PARAM(total_malloced, "%lli"); printf("# Info: Expected avalanche size: <s>(x) = 1+(1/2) (<s>(x+1)+<s>(x-1)), BC <s>(0)=0, <s>(L+1)=0, solved by <s>(x)=(L+1-x)x/2.\n"); printf("# Info: Here L=LENGTH=%lu and x=DROP_LOCATION+1=%lu, so expect %g\n", LENGTH, DROP_LOCATION+1, ((double)(DROP_LOCATION+1))*((double)(LENGTH-DROP_LOCATION))/2.); for (chunk=1; ((chunk<=NUM_CHUNKS) || (NUM_CHUNKS<0)); chunk++) { MOMENTS_INIT(size); for (drop = 0; drop < N_ROLLS; drop++) { // big droppping cycle size=0; /* printf("(%i.)", drop); for(k = 0; k<LENGTH; k++) { printf("\%i", lattice[k]); } printf("\n"); */ #if (1) if(check_cell(DROP_LOCATION) == 0) { lattice[DROP_LOCATION] = 1; } else { stack_push(DROP_LOCATION); stack_push(DROP_LOCATION); lattice[DROP_LOCATION] = 0; } /* If validated, optimse by turning stack operations into macros, * optime random number drawing (rather than having doubles in the tree * have integers there and draw an integer to compare against), * optimise the shuffling of particles. * * I have added MOMENT macros for size. */ while(stack_used != 0) { curr_pos = stack_pop(); /* This code with the "check" looks clumsy. I suppose * you are "following through" topplings? I would think * there is no point doing this later. Anyway, we validate * this code and take it from there. */ do { curr_pos = move_ball(curr_pos); if(curr_pos >= LENGTH || curr_pos < 0) { check = 0 ; } /* Why not just "else" instead of the "if"? */ if(curr_pos < LENGTH && curr_pos >= 0) { check = check_cell(curr_pos); if (check == 1) { stack_push(curr_pos); } else { check = 0; } } }while(check != 0); }/* end of while(stack_used != 0) look */ #endif #if (0) { int npos; #define PUSH(a) stack[stack_used++]=(a) #define POP(a) (a)=stack[--stack_used] if (lattice[DROP_LOCATION]++==1) { PUSH(DROP_LOCATION); while(stack_used) { size++; POP(curr_pos); do { lattice[curr_pos]-=2; npos=curr_pos+ ( (rand()>RAND_MAX/2) ? 1 : -1); if ((npos>=0) && (npos<LENGTH)) { if (lattice[npos]++==1) {PUSH(npos);} } if ((npos>=0) && (npos<LENGTH)) { if (lattice[npos]++==1) {PUSH(npos);} } } while (lattice[curr_pos]>1); } } } #endif //printf("size is %i\n", size); MOMENTS(size,size); } /* end of iterations loop */ MOMENTS_OUT(size); } /* chunk */ }
/* * Function that does the real stuff. */ bpf_filter_func bpf_jit_compile(struct bpf_insn *prog, u_int nins, size_t *size) { bpf_bin_stream stream; struct bpf_insn *ins; int flags, fret, fpkt, fmem, fjmp, fadk; int save_esp; u_int i, pass; /* * NOTE: Do not modify the name of this variable, as it's used by * the macros to emit code. */ emit_func emitm; flags = bpf_jit_optimize(prog, nins); fret = (flags & BPF_JIT_FRET) != 0; fpkt = (flags & BPF_JIT_FPKT) != 0; fmem = (flags & BPF_JIT_FMEM) != 0; fjmp = (flags & BPF_JIT_FJMP) != 0; fadk = (flags & BPF_JIT_FADK) != 0; save_esp = (fpkt || fmem || fadk); /* Stack is used. */ if (fret) nins = 1; memset(&stream, 0, sizeof(stream)); /* Allocate the reference table for the jumps. */ if (fjmp) { #ifdef _KERNEL stream.refs = malloc((nins + 1) * sizeof(u_int), M_BPFJIT, M_NOWAIT | M_ZERO); #else stream.refs = calloc(nins + 1, sizeof(u_int)); #endif if (stream.refs == NULL) return (NULL); } /* * The first pass will emit the lengths of the instructions * to create the reference table. */ emitm = emit_length; for (pass = 0; pass < 2; pass++) { ins = prog; /* Create the procedure header. */ if (save_esp) { PUSH(EBP); MOVrd(ESP, EBP); } if (fmem) SUBib(BPF_MEMWORDS * sizeof(uint32_t), ESP); if (save_esp) PUSH(ESI); if (fpkt) { PUSH(EDI); PUSH(EBX); MOVodd(8, EBP, EBX); MOVodd(16, EBP, EDI); } for (i = 0; i < nins; i++) { stream.bpf_pc++; switch (ins->code) { default: #ifdef _KERNEL return (NULL); #else abort(); #endif case BPF_RET|BPF_K: MOVid(ins->k, EAX); if (save_esp) { if (fpkt) { POP(EBX); POP(EDI); } POP(ESI); LEAVE(); } RET(); break; case BPF_RET|BPF_A: if (save_esp) { if (fpkt) { POP(EBX); POP(EDI); } POP(ESI); LEAVE(); } RET(); break; case BPF_LD|BPF_W|BPF_ABS: MOVid(ins->k, ESI); CMPrd(EDI, ESI); JAb(12); MOVrd(EDI, ECX); SUBrd(ESI, ECX); CMPid(sizeof(int32_t), ECX); JAEb(7); ZEROrd(EAX); POP(EBX); POP(EDI); POP(ESI); LEAVE(); RET(); MOVobd(EBX, ESI, EAX); BSWAP(EAX); break; case BPF_LD|BPF_H|BPF_ABS: ZEROrd(EAX); MOVid(ins->k, ESI); CMPrd(EDI, ESI); JAb(12); MOVrd(EDI, ECX); SUBrd(ESI, ECX); CMPid(sizeof(int16_t), ECX); JAEb(5); POP(EBX); POP(EDI); POP(ESI); LEAVE(); RET(); MOVobw(EBX, ESI, AX); SWAP_AX(); break; case BPF_LD|BPF_B|BPF_ABS: ZEROrd(EAX); MOVid(ins->k, ESI); CMPrd(EDI, ESI); JBb(5); POP(EBX); POP(EDI); POP(ESI); LEAVE(); RET(); MOVobb(EBX, ESI, AL); break; case BPF_LD|BPF_W|BPF_LEN: if (save_esp) MOVodd(12, EBP, EAX); else { MOVrd(ESP, ECX); MOVodd(12, ECX, EAX); } break; case BPF_LDX|BPF_W|BPF_LEN: if (save_esp) MOVodd(12, EBP, EDX); else { MOVrd(ESP, ECX); MOVodd(12, ECX, EDX); } break; case BPF_LD|BPF_W|BPF_IND: CMPrd(EDI, EDX); JAb(27); MOVid(ins->k, ESI); MOVrd(EDI, ECX); SUBrd(EDX, ECX); CMPrd(ESI, ECX); JBb(14); ADDrd(EDX, ESI); MOVrd(EDI, ECX); SUBrd(ESI, ECX); CMPid(sizeof(int32_t), ECX); JAEb(7); ZEROrd(EAX); POP(EBX); POP(EDI); POP(ESI); LEAVE(); RET(); MOVobd(EBX, ESI, EAX); BSWAP(EAX); break; case BPF_LD|BPF_H|BPF_IND: ZEROrd(EAX); CMPrd(EDI, EDX); JAb(27); MOVid(ins->k, ESI); MOVrd(EDI, ECX); SUBrd(EDX, ECX); CMPrd(ESI, ECX); JBb(14); ADDrd(EDX, ESI); MOVrd(EDI, ECX); SUBrd(ESI, ECX); CMPid(sizeof(int16_t), ECX); JAEb(5); POP(EBX); POP(EDI); POP(ESI); LEAVE(); RET(); MOVobw(EBX, ESI, AX); SWAP_AX(); break; case BPF_LD|BPF_B|BPF_IND: ZEROrd(EAX); CMPrd(EDI, EDX); JAEb(13); MOVid(ins->k, ESI); MOVrd(EDI, ECX); SUBrd(EDX, ECX); CMPrd(ESI, ECX); JAb(5); POP(EBX); POP(EDI); POP(ESI); LEAVE(); RET(); ADDrd(EDX, ESI); MOVobb(EBX, ESI, AL); break; case BPF_LDX|BPF_MSH|BPF_B: MOVid(ins->k, ESI); CMPrd(EDI, ESI); JBb(7); ZEROrd(EAX); POP(EBX); POP(EDI); POP(ESI); LEAVE(); RET(); ZEROrd(EDX); MOVobb(EBX, ESI, DL); ANDib(0x0f, DL); SHLib(2, EDX); break; case BPF_LD|BPF_IMM: MOVid(ins->k, EAX); break; case BPF_LDX|BPF_IMM: MOVid(ins->k, EDX); break; case BPF_LD|BPF_MEM: MOVrd(EBP, ECX); MOVid(((int)ins->k - BPF_MEMWORDS) * sizeof(uint32_t), ESI); MOVobd(ECX, ESI, EAX); break; case BPF_LDX|BPF_MEM: MOVrd(EBP, ECX); MOVid(((int)ins->k - BPF_MEMWORDS) * sizeof(uint32_t), ESI); MOVobd(ECX, ESI, EDX); break; case BPF_ST: /* * XXX this command and the following could * be optimized if the previous instruction * was already of this type */ MOVrd(EBP, ECX); MOVid(((int)ins->k - BPF_MEMWORDS) * sizeof(uint32_t), ESI); MOVomd(EAX, ECX, ESI); break; case BPF_STX: MOVrd(EBP, ECX); MOVid(((int)ins->k - BPF_MEMWORDS) * sizeof(uint32_t), ESI); MOVomd(EDX, ECX, ESI); break; case BPF_JMP|BPF_JA: JUMP(ins->k); break; case BPF_JMP|BPF_JGT|BPF_K: case BPF_JMP|BPF_JGE|BPF_K: case BPF_JMP|BPF_JEQ|BPF_K: case BPF_JMP|BPF_JSET|BPF_K: case BPF_JMP|BPF_JGT|BPF_X: case BPF_JMP|BPF_JGE|BPF_X: case BPF_JMP|BPF_JEQ|BPF_X: case BPF_JMP|BPF_JSET|BPF_X: if (ins->jt == ins->jf) { JUMP(ins->jt); break; } switch (ins->code) { case BPF_JMP|BPF_JGT|BPF_K: CMPid(ins->k, EAX); JCC(JA, JBE); break; case BPF_JMP|BPF_JGE|BPF_K: CMPid(ins->k, EAX); JCC(JAE, JB); break; case BPF_JMP|BPF_JEQ|BPF_K: CMPid(ins->k, EAX); JCC(JE, JNE); break; case BPF_JMP|BPF_JSET|BPF_K: TESTid(ins->k, EAX); JCC(JNE, JE); break; case BPF_JMP|BPF_JGT|BPF_X: CMPrd(EDX, EAX); JCC(JA, JBE); break; case BPF_JMP|BPF_JGE|BPF_X: CMPrd(EDX, EAX); JCC(JAE, JB); break; case BPF_JMP|BPF_JEQ|BPF_X: CMPrd(EDX, EAX); JCC(JE, JNE); break; case BPF_JMP|BPF_JSET|BPF_X: TESTrd(EDX, EAX); JCC(JNE, JE); break; } break; case BPF_ALU|BPF_ADD|BPF_X: ADDrd(EDX, EAX); break; case BPF_ALU|BPF_SUB|BPF_X: SUBrd(EDX, EAX); break; case BPF_ALU|BPF_MUL|BPF_X: MOVrd(EDX, ECX); MULrd(EDX); MOVrd(ECX, EDX); break; case BPF_ALU|BPF_DIV|BPF_X: case BPF_ALU|BPF_MOD|BPF_X: TESTrd(EDX, EDX); if (save_esp) { if (fpkt) { JNEb(7); ZEROrd(EAX); POP(EBX); POP(EDI); } else { JNEb(5); ZEROrd(EAX); } POP(ESI); LEAVE(); } else { JNEb(3); ZEROrd(EAX); } RET(); MOVrd(EDX, ECX); ZEROrd(EDX); DIVrd(ECX); if (BPF_OP(ins->code) == BPF_MOD) MOVrd(EDX, EAX); MOVrd(ECX, EDX); break; case BPF_ALU|BPF_AND|BPF_X: ANDrd(EDX, EAX); break; case BPF_ALU|BPF_OR|BPF_X: ORrd(EDX, EAX); break; case BPF_ALU|BPF_XOR|BPF_X: XORrd(EDX, EAX); break; case BPF_ALU|BPF_LSH|BPF_X: MOVrd(EDX, ECX); SHL_CLrb(EAX); break; case BPF_ALU|BPF_RSH|BPF_X: MOVrd(EDX, ECX); SHR_CLrb(EAX); break; case BPF_ALU|BPF_ADD|BPF_K: ADD_EAXi(ins->k); break; case BPF_ALU|BPF_SUB|BPF_K: SUB_EAXi(ins->k); break; case BPF_ALU|BPF_MUL|BPF_K: MOVrd(EDX, ECX); MOVid(ins->k, EDX); MULrd(EDX); MOVrd(ECX, EDX); break; case BPF_ALU|BPF_DIV|BPF_K: case BPF_ALU|BPF_MOD|BPF_K: MOVrd(EDX, ECX); ZEROrd(EDX); MOVid(ins->k, ESI); DIVrd(ESI); if (BPF_OP(ins->code) == BPF_MOD) MOVrd(EDX, EAX); MOVrd(ECX, EDX); break; case BPF_ALU|BPF_AND|BPF_K: ANDid(ins->k, EAX); break; case BPF_ALU|BPF_OR|BPF_K: ORid(ins->k, EAX); break; case BPF_ALU|BPF_XOR|BPF_K: XORid(ins->k, EAX); break; case BPF_ALU|BPF_LSH|BPF_K: SHLib((ins->k) & 0xff, EAX); break; case BPF_ALU|BPF_RSH|BPF_K: SHRib((ins->k) & 0xff, EAX); break; case BPF_ALU|BPF_NEG: NEGd(EAX); break; case BPF_MISC|BPF_TAX: MOVrd(EAX, EDX); break; case BPF_MISC|BPF_TXA: MOVrd(EDX, EAX); break; } ins++; } if (pass > 0) continue; *size = stream.cur_ip; #ifdef _KERNEL stream.ibuf = malloc(*size, M_BPFJIT, M_NOWAIT); if (stream.ibuf == NULL) break; #else stream.ibuf = mmap(NULL, *size, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); if (stream.ibuf == MAP_FAILED) { stream.ibuf = NULL; break; } #endif /* * Modify the reference table to contain the offsets and * not the lengths of the instructions. */ if (fjmp) for (i = 1; i < nins + 1; i++) stream.refs[i] += stream.refs[i - 1]; /* Reset the counters. */ stream.cur_ip = 0; stream.bpf_pc = 0; /* The second pass creates the actual code. */ emitm = emit_code; } /* * The reference table is needed only during compilation, * now we can free it. */ if (fjmp) #ifdef _KERNEL free(stream.refs, M_BPFJIT); #else free(stream.refs); #endif #ifndef _KERNEL if (stream.ibuf != NULL && mprotect(stream.ibuf, *size, PROT_READ | PROT_EXEC) != 0) { munmap(stream.ibuf, *size); stream.ibuf = NULL; } #endif return ((bpf_filter_func)(void *)stream.ibuf); }
static void NAME (SCM *const base_ptr, size_t nr_elems, INC_PARAM SCM less) { /* Stack node declarations used to store unfulfilled partition obligations. */ typedef struct { size_t lo; size_t hi; } stack_node; static const char s_buggy_less[] = "buggy less predicate used when sorting"; #define ELT(i) base_ptr[(i)*INC] if (nr_elems == 0) /* Avoid lossage with unsigned arithmetic below. */ return; if (nr_elems > MAX_THRESH) { size_t lo = 0; size_t hi = nr_elems-1; stack_node stack[STACK_SIZE]; stack_node *top = stack + 1; while (STACK_NOT_EMPTY) { size_t left; size_t right; size_t mid = lo + (hi - lo) / 2; SCM pivot; /* Select median value from among LO, MID, and HI. Rearrange LO and HI so the three values are sorted. This lowers the probability of picking a pathological pivot value and skips a comparison for both the left and right. */ SCM_TICK; if (scm_is_true (scm_call_2 (less, ELT(mid), ELT(lo)))) SWAP (ELT(mid), ELT(lo)); if (scm_is_true (scm_call_2 (less, ELT(hi), ELT(mid)))) SWAP (ELT(mid), ELT(hi)); else goto jump_over; if (scm_is_true (scm_call_2 (less, ELT(mid), ELT(lo)))) SWAP (ELT(mid), ELT(lo)); jump_over:; pivot = ELT(mid); left = lo + 1; right = hi - 1; /* Here's the famous ``collapse the walls'' section of quicksort. Gotta like those tight inner loops! They are the main reason that this algorithm runs much faster than others. */ do { while (scm_is_true (scm_call_2 (less, ELT(left), pivot))) { left += 1; /* The comparison predicate may be buggy */ if (left > hi) scm_misc_error (NULL, s_buggy_less, SCM_EOL); } while (scm_is_true (scm_call_2 (less, pivot, ELT(right)))) { right -= 1; /* The comparison predicate may be buggy */ if (right < lo) scm_misc_error (NULL, s_buggy_less, SCM_EOL); } if (left < right) { SWAP (ELT(left), ELT(right)); left += 1; right -= 1; } else if (left == right) { left += 1; right -= 1; break; } } while (left <= right); /* Set up pointers for next iteration. First determine whether left and right partitions are below the threshold size. If so, ignore one or both. Otherwise, push the larger partition's bounds on the stack and continue sorting the smaller one. */ if ((size_t) (right - lo) <= MAX_THRESH) { if ((size_t) (hi - left) <= MAX_THRESH) /* Ignore both small partitions. */ POP (lo, hi); else /* Ignore small left partition. */ lo = left; } else if ((size_t) (hi - left) <= MAX_THRESH) /* Ignore small right partition. */ hi = right; else if ((right - lo) > (hi - left)) { /* Push larger left partition indices. */ PUSH (lo, right); lo = left; } else { /* Push larger right partition indices. */ PUSH (left, hi); hi = right; } } } /* Once the BASE_PTR array is partially sorted by quicksort the rest is completely sorted using insertion sort, since this is efficient for partitions below MAX_THRESH size. BASE_PTR points to the beginning of the array to sort, and END idexes the very last element in the array (*not* one beyond it!). */ { size_t tmp = 0; size_t end = nr_elems-1; size_t thresh = min (end, MAX_THRESH); size_t run; /* Find smallest element in first threshold and place it at the array's beginning. This is the smallest array element, and the operation speeds up insertion sort's inner loop. */ for (run = tmp + 1; run <= thresh; run += 1) if (scm_is_true (scm_call_2 (less, ELT(run), ELT(tmp)))) tmp = run; if (tmp != 0) SWAP (ELT(tmp), ELT(0)); /* Insertion sort, running from left-hand-side up to right-hand-side. */ run = 1; while (++run <= end) { SCM_TICK; tmp = run - 1; while (scm_is_true (scm_call_2 (less, ELT(run), ELT(tmp)))) { /* The comparison predicate may be buggy */ if (tmp == 0) scm_misc_error (NULL, s_buggy_less, SCM_EOL); tmp -= 1; } tmp += 1; if (tmp != run) { SCM to_insert = ELT(run); size_t hi, lo; for (hi = lo = run; --lo >= tmp; hi = lo) ELT(hi) = ELT(lo); ELT(hi) = to_insert; } } } }
static package bf_parse_json(Var arglist, Byte next, void *vdata, Objid progr) { yajl_handle hand; yajl_parser_config cfg = { 1, 1 }; yajl_status stat; struct parse_context pctx; pctx.top = &pctx.stack; pctx.stack.v.type = TYPE_INT; pctx.stack.v.v.num = 0; pctx.mode = MODE_COMMON_SUBSET; const char *str = arglist.v.list[1].v.str; size_t len = strlen(str); package pack; int done = 0; if (1 < arglist.v.list[0].v.num) { if (!mystrcasecmp(arglist.v.list[2].v.str, "common-subset")) { pctx.mode = MODE_COMMON_SUBSET; } else if (!mystrcasecmp(arglist.v.list[2].v.str, "embedded-types")) { pctx.mode = MODE_EMBEDDED_TYPES; } else { free_var(arglist); return make_error_pack(E_INVARG); } } hand = yajl_alloc(&callbacks, &cfg, NULL, (void *)&pctx); while (!done) { if (len == 0) done = 1; if (done) stat = yajl_parse_complete(hand); else stat = yajl_parse(hand, (const unsigned char *)str, len); len = 0; if (done) { if (stat != yajl_status_ok) { /* clean up the stack */ while (pctx.top != &pctx.stack) { Var v = POP(pctx.top); free_var(v); } pack = make_error_pack(E_INVARG); } else { Var v = POP(pctx.top); pack = make_var_pack(v); } } } yajl_free(hand); free_var(arglist); return pack; }
int main(int argc, char *argv[]) { //global timing clock_t start_g=clock(), diff_g; //////////////////////////test function starts\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ char buffer[1024]; FILE *fp = fopen("dist.in", "r"); int num, i; char comment[20]; char arr_data[800]; int fin_num; for(i=0; i<799; i++){arr_data[i] = 'x';} int run = 0; //read file into num of test, comments and number char array while (fgets(buffer, sizeof(buffer), fp) != NULL) { sscanf(buffer, "%i;%s %s", &num, comment, arr_data); printf( "\n%i: %s\n", num, arr_data ); int k = 0; //count the number of numbers in the char array int num_count = 1; //one comma less then numbers while(arr_data[k] != 0 ) { if(arr_data[k] == ',') {num_count++;} k++; } printf("Nums in the array: %i", num_count); //initialise double array int data[num_count]; // = {[0 ... num_coun] = 0}; //converting char array to int array int acc_len = 0; for(i=0; i<num_count; i++){ fin_num = 0; int num_len = 0; while(arr_data[acc_len+num_len] != ',' && arr_data[acc_len+num_len] != 0){num_len++;} //printf("\n%i's num lenght is %i ,", i, num_len); acc_len = acc_len + num_len +1; //printf(" start of next number is %i", acc_len); int decim; for(decim = acc_len - num_len -1; decim < acc_len -1; decim++){ int d = arr_data[decim] - '0'; int pow_c; int out = 1; for(pow_c = 0; pow_c <acc_len-decim-2; pow_c++) {out = out*10;} //printf("\nNumber %i for %i", out*d, d); //(acc_len-decim-2) fin_num = fin_num + out*d; //printf("\nResulting number: \n%i on inter %i", fin_num, decim); if(decim == acc_len -2) { data[i] = fin_num; //printf("NUM FROM ARRAY: %i", data[i]); } } //printf("\n"); } printf("\nPrinting array as int array: "); for(i=0; i<num_count; i++){ printf("%i,", data[i]);} printf("\n"); //transferring data to X array int X[num_count]; for(i=0; i<num_count; i++){ X[i] = data[i];} //////////////////////////end of file to array parsing\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ int x_n = (int)(sizeof(X)/sizeof(*X)); int depth = (int) ((log(x_n)+0.1)/log(2)); double tree[depth][x_n]; double cdf[x_n]; int histogram[sizeof(X)/sizeof(*X)] ; int ddd; for (ddd=0; ddd<x_n; ddd++) {histogram[ddd] =0;} int hist[sizeof(X)/sizeof(*X)] ; int step_size; int num_of_points; int position_num; int i, j; //pdf to cdf cdf[0] = X[0]; for (i = 1; i < x_n; i++) { cdf[i] = cdf[i - 1] + X[i]; } //normalised cdf for (i = 0; i < x_n; i++) { cdf[i] = cdf[i]/cdf[x_n-1]; } //print cdf printf("cdf: "); for(i = 0; i < x_n; i++) { printf("%g ", cdf[i]); } printf("\n"); // cdf to tree array printf("TREE OUTPUT:\n "); for(i = 0; i < depth; i++) { step_size = x_n/pow(2, i); num_of_points = pow(2, i); position_num; for(j = 0; j < num_of_points; j++) { if(j == 0) {position_num = step_size *(j + 1)* 0.5 - 1;} else {position_num = step_size *j + step_size * 0.5 - 1;} tree[i][j] = cdf[position_num]; printf(" %g |", tree[i][j]); } printf("\n"); } printf("\n"); //tree array check /* for ( i = 0; i < depth; i++ ) { printf("\n"); for ( j = 0; j < x_n; j++ ) { printf("T[%d][%d] = %f ", i,j, tree[i][j] ); } } */ // tree walk //int err_count = 0; int jj; //global timing //sgenrand(time(NULL)); int curr_pos, check; int chunk; /* Repeat experiment in chunks. */ srand(SEED); printf("# Info: $Header: /home/ma/p/pruess/.cvsroot/manna_range/dmitry_20151021/manna_stack_clean_edited.c,v 1.2 2015/10/21 11:37:00 pruess Exp $\n"); preamble(argc, argv); PRINT_PARAM(SEED, "%lu"); PRINT_PARAM(LENGTH, "%lu"); PRINT_PARAM(DROP_LOCATION, "%lu"); PRINT_PARAM(total_malloced, "%lli"); printf("# Info: Expected avalanche size: <s>(x) = 1+(1/2) (<s>(x+1)+<s>(x-1)), BC <s>(0)=0, <s>(L+1)=0, solved by <s>(x)=(L+1-x)x/2.\n"); printf("# Info: Here L=LENGTH=%lu and x=DROP_LOCATION+1=%lu, so expect %g\n", LENGTH, DROP_LOCATION+1, ((double)(DROP_LOCATION+1))*((double)(LENGTH-DROP_LOCATION))/2.); for (chunk=1; ((chunk<=NUM_CHUNKS) || (NUM_CHUNKS<0)); chunk++) { MOMENTS_INIT(size); for (drop = 0; drop < N_ROLLS; drop++) { // big droppping cycle long long int size=0; #if (0) #define PUSH(a) stack[stack_used++]=(a) #define POP(a) (a)=stack[--stack_used] if(lattice[DROP_LOCATION] == 0) { lattice[DROP_LOCATION] = 1; } else { PUSH(DROP_LOCATION); PUSH(DROP_LOCATION); lattice[DROP_LOCATION] = 0; size++; } /* If validated, optimse by turning stack operations into macros, * optime random number drawing (rather than having doubles in the tree * have integers there and draw an integer to compare against), * optimise the shuffling of particles. * * I have added MOMENT macros for size. */ while(stack_used != 0) { POP(curr_pos); /* This code with the "check" looks clumsy. I suppose * you are "following through" topplings? I would think * there is no point doing this later. Anyway, we validate * this code and take it from there. */ do { double test_num = ((double)rand())/((double)RAND_MAX); //tree walk int x_pos = 0, y_pos = 0; for(y_pos = 0; y_pos < depth ; y_pos++) { if (test_num > tree[y_pos][x_pos]) {x_pos = (x_pos+1) * 2 - 1; } else {x_pos = x_pos * 2;} //printf("\nThe current position is : %i, %i", y_pos, x_pos); } curr_pos = curr_pos+ x_pos-1; //move_ball(curr_pos); //printf("\nshift: %i, RAND: %f", x_pos-1, test_num); if((curr_pos>=0) && (curr_pos<LENGTH)) { if(lattice[curr_pos] == 0) { lattice[curr_pos] = 1; } else { size++; lattice[curr_pos] = 0; PUSH(curr_pos); } } else {break;} }while( (lattice[curr_pos] != 1)); }/* end of while(stack_used != 0) look */ #endif #if (1) { int npos; #define PUSH(a) stack[stack_used++]=(a) #define POP(a) (a)=stack[--stack_used] if (lattice[DROP_LOCATION]++==1) { PUSH(DROP_LOCATION); while(stack_used) { POP(curr_pos); do { size++; lattice[curr_pos]-=2; double test_num = ((double)rand())/((double)RAND_MAX); // start of tree walk //tree walk int x_pos = 0, y_pos = 0; for(y_pos = 0; y_pos < depth ; y_pos++) { if (test_num > tree[y_pos][x_pos]) {x_pos = (x_pos+1) * 2 - 1; } else {x_pos = x_pos * 2;} //printf("\nThe current position is : %i, %i", y_pos, x_pos); } npos = curr_pos+ x_pos-1; //move_ball(curr_pos); //end of tree walk if ((npos>=0) && (npos<LENGTH)) { if (lattice[npos]++==1) {PUSH(npos);} } test_num = ((double)rand())/((double)RAND_MAX); // start of tree walk //tree walk x_pos = 0, y_pos = 0; for(y_pos = 0; y_pos < depth ; y_pos++) { if (test_num > tree[y_pos][x_pos]) {x_pos = (x_pos+1) * 2 - 1; } else {x_pos = x_pos * 2;} //printf("\nThe current position is : %i, %i", y_pos, x_pos); } npos = curr_pos+ x_pos-1; //move_ball(curr_pos); //end of tree walk if ((npos>=0) && (npos<LENGTH)) { if (lattice[npos]++==1) {PUSH(npos);} } } while (lattice[curr_pos]>1); } } } #endif //printf("size is %i\n", size); MOMENTS(size,size); } /* end of iterations loop */ MOMENTS_OUT(size); } /* chunk */ postamble(); } }
void stack_based_quicksort (void *const pbase, size_t total_elems, size_t size,size_t stride, int (*cmp)(const void*,const void*) ) { register char *base_ptr = (char *) pbase; const size_t max_thresh = MAX_THRESH * size; if (total_elems == 0) /* Avoid lossage with unsigned arithmetic below. */ return; if (total_elems > MAX_THRESH) { char *lo = base_ptr; char *hi = &lo[size * (total_elems - 1)]; stack_node stack[STACK_SIZE]; stack_node *top = stack; PUSH (NULL, NULL); while (STACK_NOT_EMPTY) { char *left_ptr; char *right_ptr; /* Select median value from among LO, MID, and HI. Rearrange LO and HI so the three values are sorted. This lowers the probability of picking a pathological pivot value and skips a comparison for both the LEFT_PTR and RIGHT_PTR in the while loops. */ char *mid = lo + size * ((hi - lo) / size >> 1); if ((*cmp) ((void *) mid, (void *) lo) < 0) { SWAP (mid, lo, stride); } if ((*cmp) ((void *) hi, (void *) mid) < 0) { SWAP (mid, hi, stride); } else { goto jump_over; } if ((*cmp) ((void *) mid, (void *) lo) < 0) { SWAP (mid, lo, stride); } jump_over:; left_ptr = lo + size; right_ptr = hi - size; /* Here's the famous ``collapse the walls'' section of quicksort. Gotta like those tight inner loops! They are the main reason that this algorithm runs much faster than others. */ do { while ((*cmp) ((void *) left_ptr, (void *) mid) < 0) left_ptr += size; while ((*cmp) ((void *) mid, (void *) right_ptr) < 0) right_ptr -= size; if (left_ptr < right_ptr) { SWAP (left_ptr, right_ptr, stride); if (mid == left_ptr) mid = right_ptr; else if (mid == right_ptr) mid = left_ptr; left_ptr += size; right_ptr -= size; } else if (left_ptr == right_ptr) { left_ptr += size; right_ptr -= size; break; } } while (left_ptr <= right_ptr); /* Set up pointers for next iteration. First determine whether left and right partitions are below the threshold size. If so, ignore one or both. Otherwise, push the larger partition's bounds on the stack and continue sorting the smaller one. */ if ((size_t) (right_ptr - lo) <= max_thresh) { if ((size_t) (hi - left_ptr) <= max_thresh) /* Ignore both small partitions. */ POP (lo, hi); else /* Ignore small left partition. */ lo = left_ptr; } else if ((size_t) (hi - left_ptr) <= max_thresh) /* Ignore small right partition. */ hi = right_ptr; else if ((right_ptr - lo) > (hi - left_ptr)) { /* Push larger left partition indices. */ PUSH (lo, right_ptr); lo = left_ptr; } else { /* Push larger right partition indices. */ PUSH (left_ptr, hi); hi = right_ptr; } } }
/* Trick: The hashtable contains positive integer after the walk pass. If we emit a reference tag N, we replace the entry's value to -N, so that we can distinguish whether we've already emitted the object or not. */ static void write_rec(ScmObj obj, ScmPort *port, ScmWriteContext *ctx) { char numbuf[50]; /* enough to contain long number */ ScmObj stack = SCM_NIL; ScmWriteState *st = port->writeState; ScmHashTable *ht = (st? st->sharedTable : NULL); int stack_depth = 0; #define PUSH(elt) \ do { \ stack = Scm_Cons(elt, stack); \ if (!ht && ++stack_depth > STACK_LIMIT) { \ Scm_Error("write recursed too deeply; " \ "maybe a circular structure?"); \ } \ } while (0) #define POP() \ do { \ stack = SCM_CDR(stack); \ if (ht) stack_depth--; \ } while (0) for (;;) { write1: if (ctx->flags & WRITE_LIMITED) { if (port->src.ostr.length >= ctx->limit) return; } /* number may be heap allocated, but we don't use srfi-38 notation. */ if (!SCM_PTRP(obj) || SCM_NUMBERP(obj)) { if (SCM_FALSEP(Scm__WritePrimitive(obj, port, ctx))) { Scm_Panic("write: got a bogus object: %08x", SCM_WORD(obj)); } goto next; } if ((SCM_STRINGP(obj) && SCM_STRING_SIZE(obj) == 0) || (SCM_VECTORP(obj) && SCM_VECTOR_SIZE(obj) == 0)) { /* we don't put a reference tag for these */ write_general(obj, port, ctx); goto next; } if (ht) { ScmObj e = Scm_HashTableRef(ht, obj, SCM_MAKE_INT(1)); long k = SCM_INT_VALUE(e); if (k <= 0) { /* This object is already printed. */ snprintf(numbuf, 50, "#%ld#", -k); Scm_PutzUnsafe(numbuf, -1, port); goto next; } else if (k > 1) { /* This object will be seen again. Put a reference tag. */ ScmWriteState *s = port->writeState; snprintf(numbuf, 50, "#%d=", s->sharedCounter); Scm_HashTableSet(ht, obj, SCM_MAKE_INT(-s->sharedCounter), 0); s->sharedCounter++; Scm_PutzUnsafe(numbuf, -1, port); } } /* Writes aggregates */ if (SCM_PAIRP(obj)) { /* special case for quote etc. NB: we need to check if we've seen SCM_CDR(obj), otherwise we'll get infinite recursion for the case like (cdr '#1='#1#). */ if (SCM_PAIRP(SCM_CDR(obj)) && SCM_NULLP(SCM_CDDR(obj)) && (!ht || SCM_FALSEP(Scm_HashTableRef(ht, SCM_CDR(obj), SCM_FALSE)))){ const char *prefix = NULL; if (SCM_CAR(obj) == SCM_SYM_QUOTE) { prefix = "'"; } else if (SCM_CAR(obj) == SCM_SYM_QUASIQUOTE) { prefix = "`"; } else if (SCM_CAR(obj) == SCM_SYM_UNQUOTE) { prefix = ","; } else if (SCM_CAR(obj) == SCM_SYM_UNQUOTE_SPLICING) { prefix = ",@"; } if (prefix) { Scm_PutzUnsafe(prefix, -1, port); obj = SCM_CADR(obj); goto write1; } } /* normal case */ Scm_PutcUnsafe('(', port); PUSH(Scm_Cons(SCM_TRUE, SCM_CDR(obj))); obj = SCM_CAR(obj); goto write1; } else if (SCM_VECTORP(obj)) { Scm_PutzUnsafe("#(", -1, port); PUSH(Scm_Cons(SCM_MAKE_INT(1), obj)); obj = SCM_VECTOR_ELEMENT(obj, 0); goto write1; } else { /* string or user-defined object */ write_general(obj, port, ctx); goto next; } next: while (SCM_PAIRP(stack)) { ScmObj top = SCM_CAR(stack); SCM_ASSERT(SCM_PAIRP(top)); if (SCM_INTP(SCM_CAR(top))) { /* we're processing a vector */ ScmObj v = SCM_CDR(top); int i = SCM_INT_VALUE(SCM_CAR(top)); int len = SCM_VECTOR_SIZE(v); if (i == len) { /* we've done this vector */ Scm_PutcUnsafe(')', port); POP(); } else { Scm_PutcUnsafe(' ', port); obj = SCM_VECTOR_ELEMENT(v, i); SCM_SET_CAR(top, SCM_MAKE_INT(i+1)); goto write1; } } else { /* we're processing a list */ ScmObj v = SCM_CDR(top); if (SCM_NULLP(v)) { /* we've done with this list */ Scm_PutcUnsafe(')', port); POP(); } else if (!SCM_PAIRP(v)) { Scm_PutzUnsafe(" . ", -1, port); obj = v; SCM_SET_CDR(top, SCM_NIL); goto write1; } else if (ht && !SCM_EQ(Scm_HashTableRef(ht, v, SCM_MAKE_INT(1)), SCM_MAKE_INT(1))) { /* cdr part is shared */ Scm_PutzUnsafe(" . ", -1, port); obj = v; SCM_SET_CDR(top, SCM_NIL); goto write1; } else { Scm_PutcUnsafe(' ', port); obj = SCM_CAR(v); SCM_SET_CDR(top, SCM_CDR(v)); goto write1; } } } break; } #undef PUSH #undef POP }
int pvsnfmt_int(pvsnfmt_vars *info, pvsnfmt_intparm_t *ip) { int number = 0; unsigned int unumber = 0; char numbersigned = 1; char iszero = 0; /* bool */ int base = 10; /* haleyjd: default to something valid */ int len = 0; /* length of number component (no sign or padding) */ char char10 = 0; char sign = 0; int widthpad = 0; int addprefix = 0; /* optional "0x" = 2 */ int totallen; int temp; /* haleyjd 07/19/03: bug fix */ /* Stack used to hold digits, which are generated backwards * and need to be popped off in the correct order */ char numstack[22]; /* largest 64 bit number has 22 octal digits */ char *stackpos = numstack; char fmt = *info->fmt; int flags = info->flags; int precision = info->precision; #define PUSH(x) \ *stackpos++ = (char)(x) #define POP() \ *(--stackpos) // haleyjd: init this array for safety memset(numstack, 0, sizeof(numstack)); /* Retrieve value */ switch (info->prefix) { case 'h': switch (fmt) { case 'd': case 'i': number = (signed short int) ip->i; break; case 'u': case 'o': case 'x': case 'X': unumber = (unsigned short int) ip->i; numbersigned = 0; break; case 'p': unumber = (unsigned int)((size_t)ip->p); // FIXME: Not x64 friendly numbersigned = 0; break; } break; case 'l': switch (fmt) { case 'd': case 'i': number = ip->i; break; case 'u': case 'o': case 'x': case 'X': unumber = (unsigned int) ip->i; numbersigned = 0; break; case 'p': unumber = (unsigned int)((size_t)ip->p); // FIXME: Not x64 friendly numbersigned = 0; break; } break; default: switch (fmt) { case 'd': case 'i': number = ip->i; break; case 'u': case 'o': case 'x': case 'X': unumber = (unsigned int) ip->i; numbersigned = 0; break; case 'p': unumber = (unsigned int)((size_t)ip->p); // FIXME: Not x64 friendly numbersigned = 0; break; } } /* switch fmt to retrieve number */ if (fmt == 'p') { fmt = 'x'; flags |= FLAG_HASH; } /* Discover base */ switch (fmt) { case 'd': case 'i': case 'u': base = 10; break; case 'o': base = 8; break; case 'X': base = 16; char10 = 'A'; break; case 'x': base = 16; char10 = 'a'; } if (numbersigned) { if (number < 0) { /* Deal with negativity */ sign = '-'; number = -number; } else if (flags & FLAG_SIGNED) { sign = '+'; } else if (flags & FLAG_SIGN_PAD) { sign = ' '; } } /* Create number */ if (numbersigned) { if (number == 0) iszero = 1; do { PUSH(number % base); number /= base; len++; } while (number != 0); } else { if (unumber == 0) iszero = 1; do { PUSH(unumber % base); unumber /= base; len++; } while (unumber != 0); } /* Octal hash character (alternate form) */ if (fmt == 'o' && (flags & FLAG_HASH) && precision <= len && precision != 0 && !iszero ) { precision = len + 1; } /* Determine width of sign, if any. */ if ( (fmt == 'x' || fmt == 'X') && (flags & FLAG_HASH) && !iszero ) addprefix = 2; else if (sign != 0) addprefix = 1; /* Make up precision (zero pad on left) */ while (len < precision) { PUSH(0); len++; } if (len + addprefix < info->width) { totallen = info->width; widthpad = info->width - (len + addprefix); } else totallen = len + addprefix; if (info->nmax <= 1) return totallen; /* Write sign or "0x" */ if (flags & FLAG_ZERO_PAD) { if (addprefix == 2) /* 0x */ { if (info->nmax > 1) { *(info->pinsertion) = '0'; info->pinsertion += 1; info->nmax -= 1; } if (info->nmax > 1) { *(info->pinsertion) = fmt; info->pinsertion += 1; info->nmax -= 1; } } else if (addprefix == 1) /* sign */ { if (info->nmax > 1) { *(info->pinsertion) = sign; info->pinsertion += 1; info->nmax -= 1; } } } /* Width pad */ if ( !(flags & FLAG_LEFT_ALIGN) ) { /* haleyjd 07/19/03: bug fix: nmax + 1 => nmax - 1 */ if (info->nmax <= 1) widthpad = 0; else if ((int) info->nmax - 1 < widthpad) widthpad = info->nmax - 1; if (flags & FLAG_ZERO_PAD) memset(info->pinsertion, '0', widthpad); else memset(info->pinsertion, ' ', widthpad); info->pinsertion += widthpad; info->nmax -= widthpad; } /* Write sign or "0x" */ if ( !(flags & FLAG_ZERO_PAD) ) { if (addprefix == 2) /* 0x */ { if (info->nmax > 1) { *(info->pinsertion) = '0'; info->pinsertion += 1; info->nmax -= 1; } if (info->nmax > 1) { *(info->pinsertion) = fmt; info->pinsertion += 1; info->nmax -= 1; } } else if (addprefix == 1) /* sign */ { if (info->nmax > 1) { *(info->pinsertion) = sign; info->pinsertion += 1; info->nmax -= 1; } } } /* haleyjd 07/19/03: bug fix: nmax + 1 => nmax - 1 */ /* Write number */ if (info->nmax <= 1) len = 0; else if ((int) info->nmax - 1 < len) len = info->nmax - 1; /* haleyjd 07/19/03: bug fix: Do NOT use len as the counter * variable for this loop. This messes up the length calculations * afterward, and allows writing off the end of the string buffer. * Special thanks to schepe for nailing this down. */ temp = len; for (; temp > 0; temp--) { char n = POP(); if (n <= 9) { *(info->pinsertion) = n + '0'; info->pinsertion += 1; } else { *(info->pinsertion) = n - 10 + char10; info->pinsertion += 1; } } info->nmax -= len; if (flags & FLAG_LEFT_ALIGN) { /* haleyjd 07/19/03: bug fix: nmax + 1 => nmax - 1 */ if (info->nmax <= 1) widthpad = 0; else if ((int) info->nmax - 1 < widthpad) widthpad = info->nmax - 1; if(widthpad) memset(info->pinsertion, ' ', widthpad); info->pinsertion += widthpad; info->nmax -= widthpad; } return totallen; }
static CvStatus icvSegmFloodFill_Stage1(uchar* pImage, int step, uchar* pMask, int maskStep, CvSize /*roi*/, CvPoint seed, int* newVal, int d_lw, int d_up, CvConnectedComp* region, void* pStack) { uchar* img = pImage + step * seed.y; uchar* mask = pMask + maskStep * (seed.y + 1); unsigned Interval = (unsigned)(d_up + d_lw); Seg* stack = (Seg*)pStack; int StIn = 0; int i, L, R; int area = 0; int sum[] = { 0, 0, 0 }; int XMin, XMax, YMin = seed.y, YMax = seed.y; int val0[3]; L = R = seed.x; img = pImage + seed.y * step; mask = pMask + seed.y * maskStep; mask[L] = 1; val0[0] = img[seed.x*3]; val0[1] = img[seed.x*3 + 1]; val0[2] = img[seed.x*3 + 2]; while (DIFF(img + (R + 1) * 3, /*img + R*3*/val0) && !mask[R + 1]) { mask[++R] = 2; } while (DIFF(img + (L - 1) * 3, /*img + L*3*/val0) && !mask[L - 1]) { mask[--L] = 2; } XMax = R; XMin = L; PUSH(seed.y, L, R, R + 1, R, UP); while (StIn) { int k, YC, PL, PR, flag/*, curstep*/; POP(YC, L, R, PL, PR, flag); int data[][3] = { { -flag, L, R}, {flag, L, PL - 1}, {flag, PR + 1, R}}; if (XMax < R) { XMax = R; } if (XMin > L) { XMin = L; } if (YMax < YC) { YMax = YC; } if (YMin > YC) { YMin = YC; } for (k = 0; k < 3; k++) { flag = data[k][0]; /*curstep = flag * step;*/ img = pImage + (YC + flag) * step; mask = pMask + (YC + flag) * maskStep; int left = data[k][1]; int right = data[k][2]; for (i = left; i <= right; i++) { if (!mask[i] && DIFF(img + i * 3, /*img - curstep + i*3*/val0)) { int j = i; mask[i] = 2; while (!mask[j - 1] && DIFF(img + (j - 1) * 3, /*img + j*3*/val0)) { mask[--j] = 2; } while (!mask[i + 1] && (DIFF(img + (i + 1) * 3, /*img + i*3*/val0) || (DIFF(img + (i + 1) * 3, /*img + (i+1)*3 - curstep*/val0) && i < R))) { mask[++i] = 2; } PUSH(YC + flag, j, i, L, R, -flag); i++; } } } img = pImage + YC * step; for (i = L; i <= R; i++) { sum[0] += img[i*3]; sum[1] += img[i*3 + 1]; sum[2] += img[i*3 + 2]; } area += R - L + 1; } region->area = area; region->rect.x = XMin; region->rect.y = YMin; region->rect.width = XMax - XMin + 1; region->rect.height = YMax - YMin + 1; region->value = cvScalarAll(0); { double inv_area = area ? 1. / area : 0; newVal[0] = cvRound(sum[0] * inv_area); newVal[1] = cvRound(sum[1] * inv_area); newVal[2] = cvRound(sum[2] * inv_area); } return CV_NO_ERR; }
void prim_regfindnext(PRIM_PROTOTYPE) { struct flgchkdat check; dbref who, item, ref, i; const char *name; muf_re* re; char* text; int flags; int matchcnt = 0; const char* errstr = NULL; CHECKOP(5); oper5 = POP(); /* int:pcreflags */ oper4 = POP(); /* str:objflags */ oper3 = POP(); /* str:namepattern */ oper2 = POP(); /* ref:owner */ oper1 = POP(); /* ref:currobj */ if (oper5->type != PROG_INTEGER) abort_interp("Non-integer argument (5)"); if (oper4->type != PROG_STRING) abort_interp("Expected string argument. (4)"); if (oper3->type != PROG_STRING) abort_interp("Expected string argument. (3)"); if (oper2->type != PROG_OBJECT) abort_interp("Expected dbref argument. (2)"); if (oper2->data.objref < NOTHING || oper2->data.objref >= db_top) abort_interp("Bad object. (2)"); if (oper1->type != PROG_OBJECT) abort_interp("Expected dbref argument. (1)"); if (oper1->data.objref < NOTHING || oper1->data.objref >= db_top) abort_interp("Bad object. (1)"); if (oper2->data.objref != NOTHING && Typeof(oper2->data.objref) == TYPE_GARBAGE) abort_interp("Owner dbref is garbage. (2)"); item = oper1->data.objref; who = oper2->data.objref; name = DoNullInd(oper3->data.string); if (mlev < 2) abort_interp("Permission denied. Requires at least Mucker Level 2."); if (mlev < 3) { if (who == NOTHING) { abort_interp ("Permission denied. Owner inspecific searches require Mucker Level 3."); } else if (who != ProgUID) { abort_interp ("Permission denied. Searching for other people's stuff requires Mucker Level 3."); } } flags = PCRE_NO_AUTO_CAPTURE; if (oper5->data.number & MUF_RE_ICASE) flags |= PCRE_CASELESS; if (oper5->data.number & MUF_RE_EXTENDED) flags |= PCRE_EXTENDED; re = regmatch_re_get(oper3->data.string, flags, &errstr); if (errstr) abort_interp(errstr) /* We're scanning a chunk of the DB, so studying should pay off. * A null return is fine, it just means we can't optimize further. */ if (re && !re->extra) { re->extra = pcre_study(re->re, 0, &errstr); if (errstr) abort_interp(errstr); } if (item == NOTHING) { item = 0; } else { item++; } ref = NOTHING; init_checkflags(PSafe, DoNullInd(oper4->data.string), &check); for (i = item; i < db_top; i++) { if ((who == NOTHING || OWNER(i) == who) && checkflags(i, check) && NAME(i)) { if (!*name) { ref = i; break; } else { text = (char *) NAME(i); if ((matchcnt = regmatch_exec(re, text)) < 0) { if (matchcnt != PCRE_ERROR_NOMATCH) abort_interp(muf_re_error(matchcnt)); } else { ref = i; break; } } } } CLEAR(oper1); CLEAR(oper2); CLEAR(oper3); CLEAR(oper4); CLEAR(oper5); PushObject(ref); }
void byte_load(fcode_env_t *env) { uchar_t *fcode_buffer; uchar_t *fcode_ptr; int fcode_incr; int offset_incr; int fcode_xt; int interpretting; int depth; int length; int past_eob = 0; int db; /* save any existing interpret state */ fcode_buffer = env->fcode_buffer; fcode_ptr = env->fcode_ptr; fcode_incr = env->fcode_incr; offset_incr = env->offset_incr; interpretting = env->interpretting; depth = DEPTH-2; /* Now init them */ CHECK_DEPTH(env, 2, "byte-load"); fcode_xt = POP(DS); env->fcode_ptr = env->fcode_buffer = (uchar_t *)POP(DS); if (fcode_xt != 1) { log_message(MSG_WARN, "byte-load: ignoring xt\n"); } length = (env->fcode_buffer[4] << 24) | (env->fcode_buffer[5] << 16) | (env->fcode_buffer[6] << 8) | env->fcode_buffer[7]; if (!check_fcode_header("byte-load", env->fcode_ptr, length)) log_message(MSG_WARN, "byte-load: header NOT OK\n"); env->fcode_incr = 1; env->offset_incr = 1; env->interpretting = 1; env->level = 0; db = get_interpreter_debug_level() & (DEBUG_BYTELOAD_DS|DEBUG_BYTELOAD_RS|DEBUG_BYTELOAD_TOKENS); debug_msg(db, "byte_load: %p, %d\n", env->fcode_buffer, fcode_xt); debug_msg(db, " header: %x, %x\n", env->fcode_buffer[0], env->fcode_buffer[1]); debug_msg(db, " crc: %x\n", (env->fcode_buffer[2]<<8)|(env->fcode_buffer[3])); debug_msg(db, " length: %x\n", length); env->fcode_ptr += 8; debug_msg(db, "Interpretting: %d\n", env->interpretting); while (env->interpretting) { int token; fcode_token *entry; acf_t apf; if (!past_eob && env->fcode_ptr >= env->fcode_buffer + length) { log_message(MSG_WARN, "byte-load: past EOB\n"); past_eob = 1; } env->last_fcode_ptr = env->fcode_ptr; token = get_next_token(env); entry = &env->table[token]; apf = entry->apf; DEBUGF(BYTELOAD_DS, output_data_stack(env, MSG_FC_DEBUG)); DEBUGF(BYTELOAD_RS, output_return_stack(env, 1, MSG_FC_DEBUG)); DEBUGF(BYTELOAD_TOKENS, log_message(MSG_FC_DEBUG, "%s: %04x %03x %s (%x)", ((env->state && (entry->flags & IMMEDIATE) == 0)) ? "Compile" : "Execute", env->last_fcode_ptr - env->fcode_buffer, token, entry->name ? entry->name : "???", entry->flags)); if (db) log_message(MSG_FC_DEBUG, "\n"); if (apf) { DEBUGF(TOKEN_USAGE, entry->usage++); PUSH(DS, (fstack_t)apf); if ((env->state) && ((entry->flags & IMMEDIATE) == 0)) { /* Compile in references */ compile_comma(env); } else { execute(env); } } } if (DEPTH != depth) { log_message(MSG_ERROR, "FCODE has net stack change of %d\n", DEPTH-depth); } /* restore old state */ env->fcode_ptr = fcode_ptr; env->fcode_buffer = fcode_buffer; env->fcode_incr = fcode_incr; env->offset_incr = offset_incr; env->interpretting = interpretting; }
void prim_regsub(PRIM_PROTOTYPE) { int matches[MATCH_ARR_SIZE]; int flags = 0; char* write_ptr = buf; int write_left = BUFFER_LEN - 1; muf_re* re; char* text; char* textstart; const char* errstr; int matchcnt, len; CHECKOP(4); oper4 = POP(); /* int:Flags */ oper3 = POP(); /* str:Replace */ oper2 = POP(); /* str:Pattern */ oper1 = POP(); /* str:Text */ if (oper1->type != PROG_STRING) abort_interp("Non-string argument (1)"); if (oper2->type != PROG_STRING) abort_interp("Non-string argument (2)"); if (oper3->type != PROG_STRING) abort_interp("Non-string argument (3)"); if (oper4->type != PROG_INTEGER) abort_interp("Non-integer argument (4)"); if (!oper2->data.string) abort_interp("Empty string argument (2)"); if (oper4->data.number & MUF_RE_ICASE) flags |= PCRE_CASELESS; if (oper4->data.number & MUF_RE_EXTENDED) flags |= PCRE_EXTENDED; if ((re = muf_re_get(oper2->data.string, flags, &errstr)) == NULL) abort_interp(errstr); if (!re->extra && (oper4->data.number & MUF_RE_ALL)) { /* User requested a recursive pattern search. This generally means * pcre_exec will be called at least twice unless the pattern doesn't * exist in the string at all. Presence of this option suggests that * the user anticipates the pattern occurring at least once, so it's * safest to go ahead and study the pattern. -brevantes */ re->extra = pcre_study(re->re, 0, &errstr); if (errstr) abort_interp(errstr); } textstart = text = (char *)DoNullInd(oper1->data.string); len = strlen(textstart); while((*text != '\0') && (write_left > 0)) { if ((matchcnt = pcre_exec(re->re, re->extra, textstart, len, text-textstart, 0, matches, MATCH_ARR_SIZE)) < 0) { if (matchcnt != PCRE_ERROR_NOMATCH) { abort_interp(muf_re_error(matchcnt)); } while((write_left > 0) && (*text != '\0')) { *write_ptr++ = *text++; write_left--; } break; } else { int allstart = matches[0]; int allend = matches[1]; int substart = -1; int subend = -1; char* read_ptr = (char *)DoNullInd(oper3->data.string); int count; for(count = allstart-(text-textstart); (write_left > 0) && (*text != '\0') && (count > 0); count--) { *write_ptr++ = *text++; write_left--; } while((write_left > 0) && (*read_ptr != '\0')) { if (*read_ptr == '\\') { if (!isdigit(*(++read_ptr))) { *write_ptr++ = *read_ptr++; write_left--; } else { int idx = (*read_ptr++) - '0'; if ((idx < 0) || (idx >= matchcnt)) { abort_interp("Invalid \\subexp in substitution string. (3)"); } substart = matches[idx*2]; subend = matches[idx*2+1]; if ((substart >= 0) && (subend >= 0) && (substart < len)) { char* ptr = &textstart[substart]; count = subend - substart; if (count > write_left) { abort_interp("Operation would result in overflow"); } for(; (write_left > 0) && (count > 0) && (*ptr != '\0'); count--) { *write_ptr++ = *ptr++; write_left--; } } } } else { *write_ptr++ = *read_ptr++; write_left--; } } for(count = allend - allstart; (*text != '\0') && (count > 0); count--) text++; if (allstart == allend && *text) { *write_ptr++ = *text++; write_left--; } } if ((oper4->data.number & MUF_RE_ALL) == 0) { while((write_left > 0) && (*text != '\0')) { *write_ptr++ = *text++; write_left--; } break; } } if (*text != '\0') abort_interp("Operation would result in overflow"); *write_ptr = '\0'; CLEAR(oper4); CLEAR(oper3); CLEAR(oper2); CLEAR(oper1); PushString(buf); }
static boolean propagate(int n, int *e, int *nblue, int *nred) /* Look at active vertices and propagate colourings */ { int i,j,v,w; while (!STACKISEMPTY) { POP(v); if (reddeg[v] == 2 && bluedeg[v] < 2) { for (i = 0; i < 4; ++i) { j = eno[4*v+i]; if (colour[j] == WHITE) { if (!makeblue(j,*nblue==n-1)) return FALSE; ++*nblue; } } } else if (bluedeg[v] == 2 && reddeg[v] < 2) { for (i = 0; i < 4; ++i) { j = eno[4*v+i]; if (colour[j] == WHITE) { if (!makered(j,*nred==n-1)) return FALSE; ++*nred; } } } if (bluedeg[v] == 1) { w = bluefarend[v]; for (i = 0; i < 4; ++i) if (e[4*v+i] == w) break; if (i < 4) { j = eno[4*v+i]; if (colour[j] == WHITE) { if (*nblue == n-1) { if (!makeblue(j,TRUE)) return FALSE; ++*nblue; } else { if (!makered(j,*nred==n-1)) return FALSE; ++*nred; } } } } if (reddeg[v] == 1) { w = redfarend[v]; for (i = 0; i < 4; ++i) if (e[4*v+i] == w) break; if (i < 4) { j = eno[4*v+i]; if (colour[j] == WHITE) { if (*nred == n-1) { if (!makered(j,TRUE)) return FALSE; ++*nred; } else { if (!makeblue(j,*nblue==n-1)) return FALSE; ++*nblue; } } } } } return TRUE; }
void prim_array_regmatchval(PRIM_PROTOTYPE) { struct inst *in; stk_array *arr; stk_array *nw; muf_re* re; char* text; int flags; int matchcnt = 0; const char* errstr = NULL; CHECKOP(3); oper3 = POP(); /* int pcreflags */ oper2 = POP(); /* str pattern */ oper1 = POP(); /* arr Array */ if (oper1->type != PROG_ARRAY) abort_interp("Argument not an array. (1)"); if (oper2->type != PROG_STRING) abort_interp("Argument not a string pattern. (2)"); if (oper3->type != PROG_INTEGER) abort_interp("Non-integer argument (3)"); flags = PCRE_NO_AUTO_CAPTURE; if (oper3->data.number & MUF_RE_ICASE) flags |= PCRE_CASELESS; if (oper3->data.number & MUF_RE_EXTENDED) flags |= PCRE_EXTENDED; re = regmatch_re_get(oper2->data.string, flags, &errstr); if (errstr) abort_interp(errstr) nw = new_array_dictionary(); arr = oper1->data.array; if (re && !re->extra && array_count(arr) > 2) { /* This pattern is getting used 3 or more times, let's study it. A null * return is okay, that just means there's nothing to optimize. */ re->extra = pcre_study(re->re, 0, &errstr); if (errstr) abort_interp(errstr); } if (array_first(arr, &temp1)) { do { in = array_getitem(arr, &temp1); if (in->type == PROG_STRING) { text = (char *)DoNullInd(in->data.string); if ((matchcnt = regmatch_exec(re, text)) < 0) { if (matchcnt != PCRE_ERROR_NOMATCH) abort_interp(muf_re_error(matchcnt)); } else { array_setitem(&nw, &temp1, in); } } else if (in->type == PROG_OBJECT) { text = (char *) NAME(in->data.objref); if ((matchcnt = regmatch_exec(re, text)) < 0) { if (matchcnt != PCRE_ERROR_NOMATCH) abort_interp(muf_re_error(matchcnt)); } else { array_setitem(&nw, &temp1, in); } } } while (array_next(arr, &temp1)); } CLEAR(oper3); CLEAR(oper2); CLEAR(oper1); PushArrayRaw(nw); }
void JitArm::stfXX(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(bJITLoadStoreFloatingOff); ARMReg rA = gpr.GetReg(); ARMReg rB = gpr.GetReg(); ARMReg RA; u32 a = inst.RA, b = inst.RB; s32 offset = inst.SIMM_16; bool single = false; bool update = false; bool zeroA = false; s32 offsetReg = -1; switch (inst.OPCD) { case 31: switch (inst.SUBOP10) { case 663: // stfsx single = true; zeroA = true; offsetReg = b; break; case 695: // stfsux single = true; offsetReg = b; break; case 727: // stfdx zeroA = true; offsetReg = b; break; case 759: // stfdux update = true; offsetReg = b; break; } break; case 53: // stfsu update = true; single = true; break; case 52: // stfs single = true; zeroA = true; break; case 55: // stfdu update = true; break; case 54: // stfd zeroA = true; break; } ARMReg v0 = fpr.R0(inst.FS); if (update) { RA = gpr.R(a); // Update path /always/ uses RA if (offsetReg == -1) // uses SIMM_16 { MOVI2R(rB, offset); ADD(rB, rB, RA); } else { ADD(rB, gpr.R(offsetReg), RA); } } else { if (zeroA) { if (offsetReg == -1) { if (a) { RA = gpr.R(a); MOVI2R(rB, offset); ADD(rB, rB, RA); } else { MOVI2R(rB, (u32)offset); } } else { ARMReg RB = gpr.R(offsetReg); if (a) { RA = gpr.R(a); ADD(rB, RB, RA); } else { MOV(rB, RB); } } } } if (update) { LDR(rA, R9, PPCSTATE_OFF(Exceptions)); CMP(rA, EXCEPTION_DSI); SetCC(CC_NEQ); MOV(RA, rB); SetCC(); } if (Core::g_CoreStartupParameter.bFastmem) { Operand2 mask(2, 1); // ~(Memory::MEMVIEW32_MASK) BIC(rB, rB, mask); // 1 MOVI2R(rA, (u32)Memory::base, false); // 2-3 ADD(rB, rB, rA); // 4 NEONXEmitter nemit(this); if (single) { VCVT(S0, v0, 0); nemit.VREV32(I_8, D0, D0); VSTR(S0, rB, 0); } else { nemit.VREV64(I_8, D0, v0); VSTR(D0, rB, 0); } } else { PUSH(4, R0, R1, R2, R3); if (single) { MOVI2R(rA, (u32)&Memory::Write_U32); VCVT(S0, v0, 0); VMOV(R0, S0); MOV(R1, rB); BL(rA); } else { MOVI2R(rA, (u32)&Memory::Write_F64); #if !defined(__ARM_PCS_VFP) // SoftFP returns in R0 and R1 VMOV(R0, v0); MOV(R2, rB); #else VMOV(D0, v0); MOV(R0, rB); #endif BL(rA); } POP(4, R0, R1, R2, R3); } gpr.Unlock(rA, rB); }
void prim_regfind_array(PRIM_PROTOTYPE) { struct flgchkdat check; dbref ref, who; const char *name; stk_array *nw; muf_re* re; char* text = NULL; int flags; int matchcnt = 0; const char* errstr = NULL; CHECKOP(4); oper4 = POP(); /* int:pcreflags */ oper3 = POP(); /* str:objflags */ oper2 = POP(); /* str:namepattern */ oper1 = POP(); /* ref:owner */ if (mlev < LMAGE) abort_interp("MAGE prim."); if (oper4->type != PROG_INTEGER) abort_interp("Non-integer argument (4)"); if (oper3->type != PROG_STRING) abort_interp("Expected string argument. (3)"); if (oper2->type != PROG_STRING) abort_interp("Expected string argument. (2)"); if (oper1->type != PROG_OBJECT) abort_interp("Expected dbref argument. (1)"); if (oper1->data.objref < NOTHING || oper1->data.objref >= db_top) abort_interp("Bad object. (1)"); flags = PCRE_NO_AUTO_CAPTURE; if (oper4->data.number & MUF_RE_ICASE) flags |= PCRE_CASELESS; if (oper4->data.number & MUF_RE_EXTENDED) flags |= PCRE_EXTENDED; re = regmatch_re_get(oper2->data.string, flags, &errstr); if (errstr) abort_interp(errstr) /* We're scanning a chunk of the DB, so studying should pay off. * A null return is fine, it just means we can't optimize further. */ if (re && !re->extra) { re->extra = pcre_study(re->re, 0, &errstr); if (errstr) abort_interp(errstr); } who = oper1->data.objref; name = DoNullInd(oper2->data.string); init_checkflags(PSafe, DoNullInd(oper3->data.string), &check); nw = new_array_packed(0); /* The "result = array_appendref" stuff was copied from find_array. I'm * making sure these alterations work as-is before attempting to remove it. * -brevantes */ for (ref = (dbref) 0; ref < db_top; ref++) { if (((who == NOTHING) ? 1 : (OWNER(ref) == who)) && checkflags(ref, check) && NAME(ref)) { if (!*name) result = array_appendref(&nw, ref); else text = (char *)NAME(ref); if ((matchcnt = regmatch_exec(re, text)) < 0) { if (matchcnt != PCRE_ERROR_NOMATCH) abort_interp(muf_re_error(matchcnt)); } else { result = array_appendref(&nw, ref); } } } CLEAR(oper1); CLEAR(oper2); CLEAR(oper3); CLEAR(oper4); PushArrayRaw(nw); }
void JitArm::lfXX(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(bJITLoadStoreFloatingOff); ARMReg rA = gpr.GetReg(); ARMReg rB = gpr.GetReg(); ARMReg RA; u32 a = inst.RA, b = inst.RB; s32 offset = inst.SIMM_16; bool single = false; bool update = false; bool zeroA = false; s32 offsetReg = -1; switch (inst.OPCD) { case 31: switch (inst.SUBOP10) { case 567: // lfsux single = true; update = true; offsetReg = b; break; case 535: // lfsx single = true; zeroA = true; offsetReg = b; break; case 631: // lfdux update = true; offsetReg = b; break; case 599: // lfdx zeroA = true; offsetReg = b; break; } break; case 49: // lfsu update = true; single = true; break; case 48: // lfs single = true; zeroA = true; break; case 51: // lfdu update = true; break; case 50: // lfd zeroA = true; break; } ARMReg v0 = fpr.R0(inst.FD), v1; if (single) v1 = fpr.R1(inst.FD); if (update) { RA = gpr.R(a); // Update path /always/ uses RA if (offsetReg == -1) // uses SIMM_16 { MOVI2R(rB, offset); ADD(rB, rB, RA); } else { ADD(rB, gpr.R(offsetReg), RA); } } else { if (zeroA) { if (offsetReg == -1) { if (a) { RA = gpr.R(a); MOVI2R(rB, offset); ADD(rB, rB, RA); } else { MOVI2R(rB, (u32)offset); } } else { ARMReg RB = gpr.R(offsetReg); if (a) { RA = gpr.R(a); ADD(rB, RB, RA); } else { MOV(rB, RB); } } } } LDR(rA, R9, PPCSTATE_OFF(Exceptions)); CMP(rA, EXCEPTION_DSI); FixupBranch DoNotLoad = B_CC(CC_EQ); if (update) MOV(RA, rB); if (Core::g_CoreStartupParameter.bFastmem) { Operand2 mask(2, 1); // ~(Memory::MEMVIEW32_MASK) BIC(rB, rB, mask); // 1 MOVI2R(rA, (u32)Memory::base, false); // 2-3 ADD(rB, rB, rA); // 4 NEONXEmitter nemit(this); if (single) { VLDR(S0, rB, 0); nemit.VREV32(I_8, D0, D0); // Byte swap to result VCVT(v0, S0, 0); VCVT(v1, S0, 0); } else { VLDR(v0, rB, 0); nemit.VREV64(I_8, v0, v0); // Byte swap to result } } else { PUSH(4, R0, R1, R2, R3); MOV(R0, rB); if (single) { MOVI2R(rA, (u32)&Memory::Read_U32); BL(rA); VMOV(S0, R0); VCVT(v0, S0, 0); VCVT(v1, S0, 0); } else { MOVI2R(rA, (u32)&Memory::Read_F64); BL(rA); #if !defined(__ARM_PCS_VFP) // SoftFP returns in R0 and R1 VMOV(v0, R0); #else VMOV(v0, D0); #endif } POP(4, R0, R1, R2, R3); } gpr.Unlock(rA, rB); SetJumpTarget(DoNotLoad); }
yaml_document_start_event_initialize(yaml_event_t *event, yaml_version_directive_t *version_directive, yaml_tag_directive_t *tag_directives_start, yaml_tag_directive_t *tag_directives_end, int implicit) { struct { yaml_error_type_t error; } context; yaml_mark_t mark = { 0, 0, 0 }; yaml_version_directive_t *version_directive_copy = NULL; struct { yaml_tag_directive_t *start; yaml_tag_directive_t *end; yaml_tag_directive_t *top; } tag_directives_copy = { NULL, NULL, NULL }; yaml_tag_directive_t value = { NULL, NULL }; assert(event); /* Non-NULL event object is expected. */ assert((tag_directives_start && tag_directives_end) || (tag_directives_start == tag_directives_end)); /* Valid tag directives are expected. */ if (version_directive) { version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)); if (!version_directive_copy) goto error; version_directive_copy->major = version_directive->major; version_directive_copy->minor = version_directive->minor; } if (tag_directives_start != tag_directives_end) { yaml_tag_directive_t *tag_directive; if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE)) goto error; for (tag_directive = tag_directives_start; tag_directive != tag_directives_end; tag_directive ++) { assert(tag_directive->handle); assert(tag_directive->prefix); if (!yaml_check_utf8(tag_directive->handle, strlen((char *)tag_directive->handle))) goto error; if (!yaml_check_utf8(tag_directive->prefix, strlen((char *)tag_directive->prefix))) goto error; value.handle = yaml_strdup(tag_directive->handle); value.prefix = yaml_strdup(tag_directive->prefix); if (!value.handle || !value.prefix) goto error; if (!PUSH(&context, tag_directives_copy, value)) goto error; value.handle = NULL; value.prefix = NULL; } } DOCUMENT_START_EVENT_INIT(*event, version_directive_copy, tag_directives_copy.start, tag_directives_copy.top, implicit, mark, mark); return 1; error: yaml_free(version_directive_copy); while (!STACK_EMPTY(context, tag_directives_copy)) { yaml_tag_directive_t value = POP(context, tag_directives_copy); yaml_free(value.handle); yaml_free(value.prefix); } STACK_DEL(context, tag_directives_copy); yaml_free(value.handle); yaml_free(value.prefix); return 0; }
INLINE void retsk(void) { POP(); skip = 1; }