Exemple #1
0
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;
}
Exemple #2
0
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);
}
Exemple #3
0
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;
}
Exemple #4
0
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);
}
Exemple #5
0
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);
}
Exemple #6
0
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;
            }
        }
    }
Exemple #8
0
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;
}
Exemple #9
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
}
Exemple #10
0
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");
}
Exemple #11
0
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);
}
Exemple #14
0
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;
	  }
      }
  }
}
Exemple #15
0
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;
}
Exemple #16
0
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();
}
}
Exemple #17
0
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;
            }
        }
    }
Exemple #18
0
/* 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
}
Exemple #19
0
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;
}
Exemple #20
0
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;
}
Exemple #21
0
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);
}
Exemple #22
0
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;
}
Exemple #23
0
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);
}
Exemple #24
0
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;
}
Exemple #25
0
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);
}
Exemple #27
0
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);
}
Exemple #29
0
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;
}
Exemple #30
0
INLINE void retsk(void) { POP(); skip = 1; }