static int run_vm(ClipMachine * mp, ClipBlock * bp) { char *func = bp->func; char *modbeg = func - GETLONG(func); char *pp = modbeg + GETLONG(F_OFFS(func, 1, 0, 0)); char code; long len = GETLONG(F_OFFS(func, 2, 0, 0)); char *beg = pp, *end = pp + len; long staticsOffs = GETLONG(modbeg); ClipFile *file = bp->file; ClipVar *statics = file->statics + staticsOffs; int nlocals = GETSHORT(F_OFFS(func, 3, 0, 1)); int nreflocals = GETSHORT(F_OFFS(func, 3, 1, 1)); int ret = 0; int i; #if 0 ClipVar *locals /* = alloca(sizeof(ClipVar) * nlocals) */ ; #endif int maxdeep = GETSHORT(F_OFFS(func, 3, 2, 1)); ClipVar *stack = alloca(sizeof(ClipVar) * maxdeep); char *filename = F_OFFS(modbeg, 6, 6, 0); int nprivates = GETSHORT(F_OFFS(func, 3, 3, 1)); /*int nparams = GETSHORT( F_OFFS(func, 3, 4, 1)); */ /*long *privates = (long *) F_OFFS(func, 3, 5, 1); */ /*long *localDefHashs = (long *) F_OFFS(func, 3 + nprivates, 5, 1); */ int numlocals = nlocals + nreflocals; /*ClipVarDef *ldp, *localDefs = alloca(sizeof(ClipVarDef) * (numlocals+1)); */ /*short *localDefNums = (short *) F_OFFS(func, 3 + nprivates + numlocals, 5, 1); */ char *procname = F_OFFS(func, 3 + nprivates + numlocals, 5 + numlocals, 1 + 1); char *localnames = procname + *(unsigned char *) F_OFFS(func, 3 + nprivates + numlocals, 5 + numlocals, 1) + 1; /*ClipVar *params = alloca( nparams*sizeof(ClipVar)); */ ClipFrame frame = {stack, stack, filename, 0, 0, 0, 0 /*localDefs */ , file->staticDefs, 0, file->hash_names, procname, maxdeep, 0}; unsigned char c, c1; short s, s1; long l, l1; ClipVar *vp; ClipBlock bl; char *trap_pp = 0; int debuglevel = _clip_debuglevel; ClipVarFrame *localvars = 0, *reflocals = 0; int local_locals = 0; if (!nlocals && !nreflocals) { reflocals = frame.localvars = mp->fp->localvars; if (reflocals && reflocals->refcount) reflocals->refcount++; } else if (nreflocals) { localvars = calloc(1, sizeof(ClipVarFrame) + numlocals * sizeof(ClipVar)); localvars->vars = (ClipVar *) (localvars + 1); localvars->refcount = 1; reflocals = frame.localvars = localvars; localvars->size = numlocals; localvars->names = localnames; } else { #if 1 localvars = calloc(1, sizeof(ClipVarFrame) + numlocals * sizeof(ClipVar)); localvars->vars = (ClipVar *) (localvars + 1); localvars->size = numlocals; localvars->refcount = 1; localvars->names = localnames; reflocals = frame.localvars = localvars; #else locals = alloca(sizeof(ClipVar) * numlocals); memset(locals, 0, numlocals * sizeof(ClipVar)); localvars = alloca(sizeof(ClipVarFrame)); localvars->vars = locals; localvars->size = numlocals; localvars->refcount = 0; localvars->names = localnames; reflocals = frame.localvars = localvars; local_locals = 1; #endif } frame.up = mp->fp; mp->fp = &frame; #if 0 localDefs[0].name = numlocals; for (i = 0, ldp = localDefs + 1; i < numlocals; i++, ldp++, localDefHashs++, localDefNums++) { /*int no = *localDefNums; */ long hash = *localDefHashs; ldp->name = hash; /* if (no < 0) ldp->vp = reflocals - no; else */ /*ldp->vp = locals + no; */ ldp->vp = 0; } #endif if (_clip_profiler) _clip_start_profiler(mp); _clip_logg(4, "PCODE call: proc '%s' file '%s' line %d", frame.procname ? frame.procname : "unknown", frame.filename, frame.line); cont: while (pp >= beg && pp < end) { if (debuglevel) _clip_debug(mp); switch ((code = *pp++)) { case CLIP_NOP: break; case CLIP_POP: _clip_pop(mp); break; case CLIP_LINE: frame.line = GET_SHORT(pp); if (debuglevel) _clip_line(mp); break; case CLIP_PUSH_NUM: { int len, dec; double d; s = GET_SHORT(pp); frame.sp->t.memo = 0; frame.sp->t.type = NUMERIC_t; frame.sp->t.flags = F_NONE; get_num(modbeg, s, &d, &len, &dec); frame.sp->t.len = len; frame.sp->t.dec = dec; frame.sp->n.d = d; frame.sp->t.memo = 0; ++frame.sp; } break; case CLIP_PUSH_STR: #if 0 s = GET_SHORT(pp); frame.sp->t.type = CHARACTER_t; frame.sp->t.flags = F_MSTAT; frame.sp->t.memo = 0; get_str(modbeg, s, &(frame.sp->s.str.buf), &(frame.sp->s.str.len)); /* if ( !(mp->flags1 & NOEXPAND_MACRO_FLAG) ) { */ if (strchr(frame.sp->s.str.buf, '&')) _clip_expand_var(mp, frame.sp); /*}*/ ++frame.sp; break; #endif case CLIP_PUSH_STRDUP: s = GET_SHORT(pp); frame.sp->t.type = CHARACTER_t; frame.sp->t.flags = F_NONE; frame.sp->t.memo = 0; { char *str = ""; int len = 0; get_str(modbeg, s, &str, &len); frame.sp->s.str.buf = _clip_memdup(str, len); frame.sp->s.str.len = len; } /* if ( !(mp->flags1 & NOEXPAND_MACRO_FLAG) ) { */ if (strchr(frame.sp->s.str.buf, '&')) _clip_expand_var(mp, frame.sp); /*}*/ ++frame.sp; break; case CLIP_PUSH_NIL: frame.sp->t.type = UNDEF_t; frame.sp->t.flags = F_NONE; ++frame.sp; break; case CLIP_PUSH_TRUE: frame.sp->t.type = LOGICAL_t; frame.sp->t.flags = F_NONE; frame.sp->l.val = 1; ++frame.sp; break; case CLIP_PUSH_FALSE: frame.sp->t.type = LOGICAL_t; frame.sp->t.flags = F_NONE; frame.sp->l.val = 0; ++frame.sp; break; case CLIP_MEMVAR_PUBLIC: l = GET_LONG(pp); _clip_memvar_public(mp, l); break; case CLIP_MEMVAR_SPACE: l = GET_LONG(pp); l1 = GET_LONG(pp); _clip_memvar_space(mp, _clip_space(mp, l), l1, 1); break; case CLIP_MEMVAR_PRIVATE: l = GET_LONG(pp); _clip_memvar_private(mp, l); break; case CLIP_MEMVAR_PUBLIC_POP: l = _clip_pop_hash(mp); _clip_memvar_public(mp, l); break; case CLIP_MEMVAR_SPACE_POP: l = GET_LONG(pp); l1 = _clip_pop_hash(mp); _clip_memvar_space(mp, _clip_space(mp, l), l1, 1); break; case CLIP_MEMVAR_PRIVATE_POP: l = _clip_pop_hash(mp); /*_clip_memvar_private(mp, l);*/ _clip_add_private(mp, l); break; case CLIP_MEMVAR_PARAM: l = GET_LONG(pp); c = GET_BYTE(pp); _clip_memvar_param(mp, l, c); break; case CLIP_PUSH_PARAM: c = GET_BYTE(pp); s = GET_SHORT(pp); _clip_param(mp, c, s); break; case CLIP_PUSH_LOCAL: s = GET_SHORT(pp); if ((ret = _clip_push_local(mp, s))) goto _trap; break; case CLIP_PUSH_REF_LOCAL: s = GET_SHORT(pp); #if 0 frame.sp->p.vp = _clip_ref_local(mp, s); #else { ClipVar *vp1 = _clip_ref_local(mp, s); frame.sp->p.vp = vp1; } #endif break; case CLIP_PUSH_STATIC: s = GET_SHORT(pp); get_static(mp, file, statics, modbeg, s, &vp); if ((ret = _clip_push_static(mp, vp))) goto _trap; break; case CLIP_PUSH_REF_STATIC: s = GET_SHORT(pp); get_static(mp, file, statics, modbeg, s, &vp); frame.sp->p.vp = vp; break; case CLIP_PUSH_MEMVAR: l = GET_LONG(pp); if ((ret = _clip_memvar(mp, l))) goto _trap; break; case CLIP_PUSH_FMEMVAR: l = GET_LONG(pp); if ((ret = _clip_fmemvar(mp, l))) goto _trap; break; case CLIP_PUSH_MEMVARF: l = GET_LONG(pp); if ((ret = _clip_memvarf(mp, l))) goto _trap; break; case CLIP_REF_FMEMVAR: l = GET_LONG(pp); if ((ret = _clip_ref_fmemvar(mp, l))) goto _trap; break; case CLIP_PUSH_REF_MEMVAR: l = GET_LONG(pp); #if 0 frame.sp->p.vp = _clip_ref_memvar(mp, l); #else { ClipVar *vp1 = _clip_ref_memvar(mp, l); frame.sp->p.vp = vp1; } #endif break; case CLIP_PUSH_REF_MEMVAR_NOADD: l = GET_LONG(pp); { ClipVar *vp1 = _clip_ref_memvar_noadd(mp, l); frame.sp->p.vp = vp1; } break; case CLIP_PUSH_PUBLIC: l = GET_LONG(pp); if ((ret = _clip_public(mp, l))) goto _trap; break; case CLIP_PUSH_REF_PUBLIC: l = GET_LONG(pp); #if 0 frame.sp->p.vp = _clip_ref_public(mp, l); #else { ClipVar *vp1 = _clip_ref_public(mp, l); frame.sp->p.vp = vp1; } #endif break; case CLIP_REFMACRO: if ((ret = _clip_refmacro(mp))) goto _trap; break; case CLIP_MAKE_REF: c = GET_BYTE(pp); vp = frame.sp->p.vp; if ((ret = _clip_ref(mp, vp, c))) goto _trap; break; case CLIP_UNREF_ARR: _clip_unref_arr(mp); break; case CLIP_FIELD: l = GET_LONG(pp); l1 = GET_LONG(pp); if ((ret = _clip_field(mp, l, l1))) goto _trap; break; case CLIP_FIELD_POP: l = GET_LONG(pp); l1 = _clip_pop_hash(mp); if ((ret = _clip_field(mp, l, l1))) goto _trap; break; case CLIP_FIELD_POP_NAME: _clip_pop_fieldhash(mp, &l1, &l); if ((ret = _clip_field(mp, l, l1))) goto _trap; break; case CLIP_PUSH_AREA: l = GET_LONG(pp); if ((ret = _clip_push_area(mp, l))) goto _trap; break; case CLIP_PUSH_AREA_POP: l = _clip_pop_hash(mp); if ((ret = _clip_push_area(mp, l))) goto _trap; break; case CLIP_POP_AREA: if ((ret = _clip_pop_area(mp))) goto _trap; break; case CLIP_FUNC: c = GET_BYTE(pp); l = GET_LONG(pp); if ((ret = _clip_func_hash(mp, l, c, 0, reflocals))) goto _trap; break; case CLIP_FUNCR: c = GET_BYTE(pp); l = GET_LONG(pp); if ((ret = _clip_func_hash(mp, l, c, 1, reflocals))) goto _trap; break; case CLIP_PROC: c = GET_BYTE(pp); l = GET_LONG(pp); if ((ret = _clip_proc_hash(mp, l, c, 0, reflocals))) goto _trap; break; case CLIP_PROCR: c = GET_BYTE(pp); l = GET_LONG(pp); if ((ret = _clip_proc_hash(mp, l, c, 1, reflocals))) goto _trap; break; case CLIP_SFUNC: c = GET_BYTE(pp); s = GET_SHORT(pp); bl.file = file; get_func(modbeg, s, &bl.func); if ((ret = _clip_code_func(mp, &bl, c, 0, reflocals))) goto _trap; break; case CLIP_SFUNCR: c = GET_BYTE(pp); s = GET_SHORT(pp); bl.file = file; get_func(modbeg, s, &bl.func); if ((ret = _clip_code_func(mp, &bl, c, 1, reflocals))) goto _trap; break; case CLIP_SPROC: c = GET_BYTE(pp); s = GET_SHORT(pp); bl.file = file; get_func(modbeg, s, &bl.func); if ((ret = _clip_code_proc(mp, &bl, c, 0, reflocals))) goto _trap; break; case CLIP_SPROCR: c = GET_BYTE(pp); s = GET_SHORT(pp); bl.file = file; get_func(modbeg, s, &bl.func); if ((ret = _clip_code_proc(mp, &bl, c, 1, reflocals))) goto _trap; break; case CLIP_ASSIGN: vp = frame.sp->p.vp; if ((ret = _clip_assign(mp, vp))) goto _trap; break; case CLIP_REF_DESTROY: vp = frame.sp->p.vp; /*if (vp->t.flags != F_MREF)*/ _clip_destroy(mp, vp); /*_clip_destroy(mp, vp);*/ break; case CLIP_MACROASSIGN: c = GET_BYTE(pp); c1 = GET_BYTE(pp); if ((ret = _clip_macroassign(mp, c, c1 & 1, c1 & 2))) goto _trap; break; case CLIP_REFASSIGN: c = GET_BYTE(pp); vp = frame.sp->p.vp; if ((ret = _clip_refassign(mp, vp, c))) goto _trap; break; case CLIP_UNREF: vp = frame.sp->p.vp; _clip_destroy(mp, vp); break; case CLIP_IASSIGN: vp = frame.sp->p.vp; if ((ret = _clip_iassign(mp, vp))) goto _trap; break; case CLIP_OPASSIGN: c = GET_BYTE(pp); vp = frame.sp->p.vp; if ((ret = _clip_opassign(mp, vp, c))) goto _trap; break; case CLIP_OPIASSIGN: c = GET_BYTE(pp); vp = frame.sp->p.vp; if ((ret = _clip_opiassign(mp, vp, c))) goto _trap; break; case CLIP_ASSIGN_FIELD: l = GET_LONG(pp); l1 = GET_LONG(pp); if ((ret = _clip_assign_field(mp, l, l1))) goto _trap; break; case CLIP_IASSIGN_FIELD: l = GET_LONG(pp); l1 = GET_LONG(pp); if ((ret = _clip_iassign_field(mp, l, l1))) goto _trap; break; case CLIP_ASSIGN_FIELD_POP: l = GET_LONG(pp); l1 = _clip_pop_hash(mp); if ((ret = _clip_assign_field(mp, l, l1))) goto _trap; break; case CLIP_IASSIGN_FIELD_POP: l = GET_LONG(pp); l1 = _clip_pop_hash(mp); if ((ret = _clip_iassign_field(mp, l, l1))) goto _trap; break; case CLIP_ASSIGN_PFIELD: l = _clip_pop_hash(mp); l1 = GET_LONG(pp); if ((ret = _clip_assign_field(mp, l, l1))) goto _trap; break; case CLIP_IASSIGN_PFIELD: l = _clip_pop_hash(mp); l1 = GET_LONG(pp); if ((ret = _clip_iassign_field(mp, l, l1))) goto _trap; break; case CLIP_ASSIGN_PFIELD_POP: l = _clip_pop_hash(mp); l1 = _clip_pop_hash(mp); if ((ret = _clip_assign_field(mp, l, l1))) goto _trap; break; case CLIP_IASSIGN_PFIELD_POP: l = _clip_pop_hash(mp); l1 = _clip_pop_hash(mp); if ((ret = _clip_iassign_field(mp, l, l1))) goto _trap; break; case CLIP_FM_ASSIGN: l = GET_LONG(pp); if ((ret = _clip_fm_assign(mp, l))) goto _trap; break; case CLIP_FM_IASSIGN: l = GET_LONG(pp); if ((ret = _clip_fm_iassign(mp, l))) goto _trap; break; case CLIP_ARRAY: l = GET_LONG(pp); _clip_sarray(mp, l); break; case CLIP_DIMARRAY: l = GET_LONG(pp); _clip_dimarray(mp, l); break; case CLIP_NEWARRAY: l = GET_LONG(pp); _clip_vnewarray(mp, l, (long *) pp); pp += l * sizeof(long); break; case CLIP_GET: l = GET_LONG(pp); if ((ret = _clip_get(mp, l))) goto _trap; break; case CLIP_SET: l = GET_LONG(pp); if ((ret = _clip_set(mp, l))) goto _trap; break; case CLIP_RETURN_POP: _clip_return(mp); case CLIP_RETURN: goto _return; case CLIP_STORE: c1 = GET_BYTE(pp); c = GET_BYTE(pp); if ((ret = _clip_store(mp, c, c1))) goto _trap; break; case CLIP_ISTORE: c1 = GET_BYTE(pp); c = GET_BYTE(pp); if ((ret = _clip_istore(mp, c, c1))) goto _trap; break; case CLIP_OPSTORE: c = GET_BYTE(pp); c1 = GET_BYTE(pp); if ((ret = _clip_opstore(mp, c1, c))) goto _trap; break; case CLIP_OPISTORE: c = GET_BYTE(pp); c1 = GET_BYTE(pp); if ((ret = _clip_opistore(mp, c1, c))) goto _trap; break; case CLIP_FETCH: c = GET_BYTE(pp); if ((ret = _clip_fetch(mp, c))) goto _trap; break; case CLIP_FETCHREF: c = GET_BYTE(pp); #if 0 frame.sp->p.vp = _clip_fetchref(mp, c); #else { ClipVar *vp1 = _clip_fetchref(mp, c); /*printf("%p\n", vp1);*/ frame.sp->p.vp = vp1; } #endif if (!frame.sp->p.vp) goto _trap; break; case CLIP_IFETCH: c = GET_BYTE(pp); if ((ret = _clip_ifetch(mp, c))) goto _trap; break; case CLIP_CALL: c = GET_BYTE(pp); l = GET_LONG(pp); if ((ret = _clip_call(mp, c, l))) goto _trap; break; case CLIP_PUSH_CODE: s = GET_SHORT(pp); c = GET_BYTE(pp); c1 = GET_BYTE(pp); vp = NEW(ClipVar); vp->t.type = PCODE_t; vp->t.flags = F_NONE; vp->t.count = 1; vp->c.u.block = NEW(ClipBlock); get_func(modbeg, s, &(vp->c.u.block->func)); vp->c.u.block->file = file; if (c) { int nlocals = c; ClipVarFrame *localvars = calloc(1, sizeof(ClipVarFrame) + nlocals * sizeof(ClipVar)); localvars->vars = (ClipVar *) (localvars + 1); memcpy(localvars->vars, mp->fp->sp - nlocals, nlocals * sizeof(ClipVar)); localvars->refcount = 1; localvars->size = nlocals; vp->c.uplocals = localvars; mp->fp->sp -= nlocals; } else if (!c1 && reflocals && reflocals->refcount) { reflocals->refcount++; vp->c.uplocals = reflocals; } else vp->c.uplocals = 0; file->refCount++; CLEAR_CLIPVAR(frame.sp); frame.sp->t.type = PCODE_t; frame.sp->t.flags = F_MPTR; frame.sp->p.vp = vp; frame.sp++; CLIP_CHECK_STACK; break; case CLIP_MACRO: if ((ret = _clip_macro(mp))) goto _trap; break; case CLIP_PCOUNT: _clip_pcount(mp); break; case CLIP_PSHIFT: _clip_pshift(mp); break; case CLIP_PARN: if ((ret = _clip_parn(mp))) goto _trap; break; case CLIP_FUNC_NAME: c = GET_BYTE(pp); if ((ret = _clip_func_name(mp, c))) goto _trap; break; case CLIP_INCR: vp = frame.sp->p.vp; if ((ret = _clip_incr(mp, vp, 1, 0))) goto _trap; break; case CLIP_INCR_POST: vp = frame.sp->p.vp; if ((ret = _clip_incr(mp, vp, 1, 1))) goto _trap; break; case CLIP_DECR: vp = frame.sp->p.vp; if ((ret = _clip_incr(mp, vp, 0, 0))) goto _trap; break; case CLIP_DECR_POST: vp = frame.sp->p.vp; if ((ret = _clip_incr(mp, vp, 0, 1))) goto _trap; break; case CLIP_OP: c = GET_BYTE(pp); if ((ret = _clip_op(mp, c))) goto _trap; break; case CLIP_NOT: if ((ret = _clip_not(mp))) goto _trap; break; case CLIP_COND: s = GET_SHORT(pp); if ((ret = _clip_cond(mp, &i))) goto _trap; if (!i) pp += s; break; case CLIP_TCOND: s = GET_SHORT(pp); if ((ret = _clip_tcond(mp, &i))) goto _trap; if (!i) pp += s; break; case CLIP_ITCOND: s = GET_SHORT(pp); if ((ret = _clip_tcond(mp, &i))) goto _trap; if (i) pp += s; break; case CLIP_GOTO: s = GET_SHORT(pp); pp += s; break; case CLIP_FORSTEP: s = GET_SHORT(pp); if ((ret = _clip_forstep(mp, &i))) goto _trap; if (!i) pp += s; break; case CLIP_MAP_FIRST: c = GET_BYTE(pp); s = GET_SHORT(pp); if ((ret = _clip_map_first(mp, c, &i))) goto _trap; if (!i) pp += s; break; case CLIP_MAP_NEXT: c = GET_BYTE(pp); s = GET_SHORT(pp); if ((ret = _clip_map_next(mp, c, &i))) goto _trap; if (!i) pp += s; break; case CLIP_MINUS: if ((ret = _clip_minus(mp))) goto _trap; break; case CLIP_RESETTRAP: trap_pp = 0; break; case CLIP_SETTRAP: s = GET_SHORT(pp); trap_pp = pp + s; break; case CLIP_RECOVER: while (frame.sp > frame.stack) _clip_destroy(mp, --frame.sp); ret = 0; break; case CLIP_USING: if (mp->trapVar) { vp = frame.sp->p.vp; *frame.sp = *mp->trapVar; ++frame.sp; free(mp->trapVar); mp->trapVar = 0; if ((ret = _clip_assign(mp, vp))) goto _trap; } break; case CLIP_BREAK: #if 0 /*_clip_trap_str(mp, filename, frame.line, "BREAK");*/ #else vp = NEW(ClipVar); _clip_trap_var(mp, filename, frame.line, vp); #endif ret = -1; goto _trap; case CLIP_BREAK_EXPR: vp = NEW(ClipVar); --frame.sp; *vp = *frame.sp; _clip_trap_var(mp, filename, frame.line, vp); ret = -1; goto _trap; case CLIP_SWAP: c = GET_BYTE(pp); _clip_swap(mp, c); break; case CLIP_PUSH_HASH: l = GET_LONG(pp); frame.sp->t.memo = 0; frame.sp->t.type = NUMERIC_t; frame.sp->t.flags = F_NONE; frame.sp->t.len = 10; frame.sp->t.dec = 0; frame.sp->n.d = l; frame.sp++; CLIP_CHECK_STACK; break; case CLIP_CALC_HASH: _clip_calc_hash(mp); break; case CLIP_CALC_HASH2: _clip_calc_hash2(mp, 1); break; case CLIP_PUSH_LOCALE: _clip_push_locale(mp); break; case CLIP_RDDFIELD: s = GET_SHORT(pp); s1 = GET_SHORT(pp); _clip_rddfield(mp, s, s1); break; case CLIP_CATSTR: s = GET_SHORT(pp); _clip_catstr(mp, s); break; case CLIP_QUOT: _clip_quot(mp); break; case CLIP_SWITCH: s = GET_SHORT(pp); /* label num */ l = _clip_pop_shash(mp); /* hash */ { short other = GET_SHORT(pp); long *lp = (long *) pp; short *jmps = (short *) (pp + s * sizeof(long)); int n = search_long(lp, s, l); if (n < 0) pp += other; else pp += GETSHORT(jmps+n); } break; default: _clip_trap_printf(mp, filename, frame.line, "invalid bytecode %d", code); _clip_call_errblock(mp, 1); ret = 1; goto _trap; } } goto _return; _trap: if (trap_pp /*&& ret > 0 */ ) { pp = trap_pp; goto cont; } _clip_trap(mp, filename, frame.line); /*ret = 1; */ _return: if (_clip_profiler) _clip_stop_profiler(mp); if (local_locals) _clip_destroy_locals(mp); _clip_resume(mp, nlocals, nreflocals); #if 0 _clip_vresume(mp, nlocals, locals); #endif #if 0 _clip_vresume(mp, nparams, params); #endif #if 0 if (nreflocals) _clip_vresume(mp, nreflocals, reflocals); #endif /*_clip_vremove_privates(mp, nprivates, privates);*/ dealloca(stack); return ret; }
int dse_ksrch(block_id srch, block_id_ptr_t pp, int4 *off, char *targ_key, int targ_len) { cache_rec_ptr_t dummy_cr; int rsize, tmp_cmpc; int4 cmp, dummy_int; ssize_t size; sm_uc_ptr_t blk_id, bp, b_top, key_top, rp, r_top; unsigned short cc, dummy_short; if(!(bp = t_qread(srch, &dummy_int, &dummy_cr))) rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_DSEBLKRDFAIL); if (((blk_hdr_ptr_t) bp)->bsiz > cs_addrs->hdr->blk_size) b_top = bp + cs_addrs->hdr->blk_size; else if (((blk_hdr_ptr_t) bp)->bsiz < SIZEOF(blk_hdr)) b_top = bp + SIZEOF(blk_hdr); else b_top = bp + ((blk_hdr_ptr_t) bp)->bsiz; CLEAR_DSE_COMPRESS_KEY; *off = 0; for (rp = bp + SIZEOF(blk_hdr); rp < b_top; rp = r_top) { *off = (int4)(rp - bp); GET_SHORT(dummy_short, &((rec_hdr_ptr_t)rp)->rsiz); rsize = dummy_short; if (rsize < SIZEOF(rec_hdr)) r_top = rp + SIZEOF(rec_hdr); else r_top = rp + rsize; if (r_top > b_top) r_top = b_top; if (r_top - rp < (((blk_hdr_ptr_t)bp)->levl ? SIZEOF(block_id) : MIN_DATA_SIZE) + SIZEOF(rec_hdr)) { *pp = 0; break; } for (key_top = rp + SIZEOF(rec_hdr); key_top < r_top ; ) if (!*key_top++ && !*key_top++) break; if (((blk_hdr_ptr_t)bp)->levl && key_top > (blk_id = r_top - SIZEOF(block_id))) key_top = blk_id; if (EVAL_CMPC((rec_hdr_ptr_t)rp) > patch_comp_count) cc = patch_comp_count; else cc = EVAL_CMPC((rec_hdr_ptr_t)rp); size = (ssize_t)(key_top - rp - SIZEOF(rec_hdr)); if (size > MAX_KEY_SZ - cc) size = MAX_KEY_SZ - cc; if (size < 0) size = 0; memcpy(&patch_comp_key[cc], rp + SIZEOF(rec_hdr), size); patch_comp_count = (int)(cc + size); GET_LONGP(pp, key_top); cmp = memvcmp(targ_key, targ_len, &patch_comp_key[0], patch_comp_count); if (0 > cmp) break; if (!cmp) { if (0 != ((blk_hdr_ptr_t)bp)->levl) break; if (patch_find_root_search) { for (key_top = rp + SIZEOF(rec_hdr); key_top < r_top; ) if (!*key_top++ && !*key_top++) break; GET_LONG(ksrch_root, key_top); } return TRUE; } } patch_path_count++; if (((blk_hdr_ptr_t) bp)->levl && *pp > 0 && *pp < cs_addrs->ti->total_blks && (*pp % cs_addrs->hdr->bplmap) && dse_ksrch(*pp, pp + 1, off + 1, targ_key, targ_len)) return TRUE; return FALSE; }
void dse_m_rest ( block_id blk, /* block number */ unsigned char *bml_list, /* start of local list of local bit maps */ int4 bml_size, /* size of each entry in *bml_list */ sm_vuint_ptr_t blks_ptr, /* total free blocks */ bool in_dir_tree) { sm_uc_ptr_t bp, b_top, rp, r_top, bml_ptr, np, ptr; unsigned char util_buff[MAX_UTIL_LEN]; block_id next; int util_len; int4 dummy_int; cache_rec_ptr_t dummy_cr; int4 bml_index; short level, rsize; int4 bplmap; error_def(ERR_DSEBLKRDFAIL); if(!(bp = t_qread (blk, &dummy_int, &dummy_cr))) rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL); if (((blk_hdr_ptr_t) bp)->bsiz > cs_addrs->hdr->blk_size) b_top = bp + cs_addrs->hdr->blk_size; else if (((blk_hdr_ptr_t) bp)->bsiz < SIZEOF(blk_hdr)) b_top = bp + SIZEOF(blk_hdr); else b_top = bp + ((blk_hdr_ptr_t) bp)->bsiz; level = ((blk_hdr_ptr_t)bp)->levl; bplmap = cs_addrs->hdr->bplmap; for (rp = bp + SIZEOF(blk_hdr); rp < b_top ;rp = r_top) { if (in_dir_tree || level > 1) /* reread block because it may have been flushed from read */ { if (!(np = t_qread(blk,&dummy_int,&dummy_cr))) /* cache due to LRU buffer scheme and reads in recursive */ rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL); /* calls to dse_m_rest. */ if (np != bp) { b_top = np + (b_top - bp); rp = np + (rp - bp); r_top = np + (r_top - bp); bp = np; } } GET_SHORT(rsize,&((rec_hdr_ptr_t)rp)->rsiz); r_top = rp + rsize; if (r_top > b_top) r_top = b_top; if (r_top - rp < (SIZEOF(rec_hdr) + SIZEOF(block_id))) break; if (in_dir_tree && level == 0) { for (ptr = rp + SIZEOF(rec_hdr); ; ) { if (*ptr++ == 0 && *ptr++ == 0) break; } GET_LONG(next,ptr); } else GET_LONG(next,r_top - SIZEOF(block_id)); if (next < 0 || next >= cs_addrs->ti->total_blks || (next / bplmap * bplmap == next)) { memcpy(util_buff,"Invalid pointer in block ",25); util_len = 25; util_len += i2hex_nofill(blk, &util_buff[util_len], 8); memcpy(&util_buff[util_len], " record offset ",15); util_len += 15; util_len += i2hex_nofill((int)(rp - bp), &util_buff[util_len], 4); util_buff[util_len] = 0; util_out_print((char*)util_buff,TRUE); continue; } bml_index = next / bplmap; bml_ptr = bml_list + bml_index * bml_size; if (bml_busy(next - next / bplmap * bplmap, bml_ptr + SIZEOF(blk_hdr))) { *blks_ptr = *blks_ptr - 1; if (((blk_hdr_ptr_t) bp)->levl > 1) { dse_m_rest (next, bml_list, bml_size, blks_ptr, in_dir_tree); } else if (in_dir_tree) { assert(((blk_hdr_ptr_t) bp)->levl == 0 || ((blk_hdr_ptr_t) bp)->levl == 1); dse_m_rest (next, bml_list, bml_size, blks_ptr, ((blk_hdr_ptr_t)bp)->levl); } } } return; }
void iorm_use(io_desc *iod, mval *pp) { unsigned char c; int4 width, length, blocksize; int4 status; d_rm_struct *rm_ptr; struct RAB *r; struct FAB *f; int p_offset; boolean_t shared_seen = FALSE; error_def(ERR_DEVPARMNEG); error_def(ERR_RMWIDTHPOS); error_def(ERR_RMWIDTHTOOBIG); error_def(ERR_RMNOBIGRECORD); error_def(ERR_RMBIGSHARE); error_def(ERR_MTBLKTOOBIG); error_def(ERR_MTBLKTOOSM); p_offset = 0; rm_ptr = (d_rm_struct *)iod->dev_sp; r = &rm_ptr->r; f = &rm_ptr->f; assert(r->rab$l_fab == f); while (*(pp->str.addr + p_offset) != iop_eol) { assert(*(pp->str.addr + p_offset) < n_iops); switch ((c = *(pp->str.addr + p_offset++))) { case iop_allocation: if (iod->state != dev_open) f->fab$l_alq = *(int4*)(pp->str.addr + p_offset); break; case iop_append: if (iod->state != dev_open) r->rab$l_rop |= RAB$M_EOF; break; case iop_blocksize: if (iod->state != dev_open) { GET_LONG(blocksize, pp->str.addr + p_offset); if (MAX_RMS_ANSI_BLOCK < blocksize) rts_error(VARLSTCNT(1) ERR_MTBLKTOOBIG); else if (MIN_RMS_ANSI_BLOCK > blocksize) rts_error(VARLSTCNT(3) ERR_MTBLKTOOSM, 1, MIN_RMS_ANSI_BLOCK); else f->fab$w_bls = (unsigned short)blocksize; } break; case iop_contiguous: if (iod->state != dev_open) { f->fab$l_fop &= ~FAB$M_CBT; f->fab$l_fop |= FAB$M_CTG; } break; case iop_delete: f->fab$l_fop |= FAB$M_DLT; break; case iop_extension: GET_USHORT(f->fab$w_deq, pp->str.addr + p_offset); break; case iop_exception: iod->error_handler.len = *(pp->str.addr + p_offset); iod->error_handler.addr = pp->str.addr + p_offset + 1; s2pool(&iod->error_handler); break; case iop_fixed: if (iod->state != dev_open) rm_ptr->f.fab$b_rfm = rm_ptr->b_rfm = FAB$C_FIX; break; case iop_length: GET_LONG(length, pp->str.addr + p_offset); if (length < 0) rts_error(VARLSTCNT(1) ERR_DEVPARMNEG); iod->length = length; break; case iop_newversion: if (iod->state != dev_open) { f->fab$l_fop |= FAB$M_MXV; f->fab$l_fop &= ~(FAB$M_CIF | FAB$M_SUP); } break; case iop_nosequential: break; case iop_s_protection: rm_ptr->promask &= ~(0x0F << XAB$V_SYS); rm_ptr->promask |= ((~(unsigned char)*(pp->str.addr + p_offset) & 0x0000000F) << XAB$V_SYS); break; case iop_w_protection: rm_ptr->promask &= ~(0x0F << XAB$V_WLD); rm_ptr->promask |= ((~(unsigned char)*(pp->str.addr + p_offset) & 0x0000000F) << XAB$V_WLD); break; case iop_g_protection: rm_ptr->promask &= ~(0x0F << XAB$V_GRP); rm_ptr->promask |= ((~(unsigned char)*(pp->str.addr + p_offset) & 0x0000000F) << XAB$V_GRP); break; case iop_o_protection: rm_ptr->promask &= ~(0x0F << XAB$V_OWN); rm_ptr->promask |= ((~(unsigned char)*(pp->str.addr + p_offset) & 0x0000000F) << XAB$V_OWN); break; case iop_readonly: if (iod->state != dev_open) f->fab$b_fac = FAB$M_GET; break; case iop_noreadonly: if (iod->state != dev_open) f->fab$b_fac = FAB$M_GET | FAB$M_PUT | FAB$M_TRN; break; case iop_recordsize: if (iod->state != dev_open) { GET_LONG(width, pp->str.addr + p_offset); if (width <= 0) rts_error(VARLSTCNT(1) ERR_RMWIDTHPOS); iod->width = width; if (MAX_RMS_RECORDSIZE >= width) r->rab$w_usz = f->fab$w_mrs = (unsigned short)width; else if (MAX_STRLEN < width) rts_error(VARLSTCNT(1) ERR_RMWIDTHTOOBIG); else if (!rm_ptr->largerecord) rts_error(VARLSTCNT(1) ERR_RMNOBIGRECORD); rm_ptr->l_usz = rm_ptr->l_mrs = width; } break; case iop_shared: if (iod->state != dev_open) shared_seen = TRUE; break; case iop_spool: f->fab$l_fop |= FAB$M_SPL; break; case iop_submit: f->fab$l_fop |= FAB$M_SCF; break; case iop_rfa: break; case iop_space: if (iod->state == dev_open && f->fab$l_dev & DEV$M_SQD) { GET_LONG(r->rab$l_bkt, pp->str.addr + p_offset); if ((status = sys$space(r, 0, 0)) != RMS$_NORMAL) rts_error(VARLSTCNT(1) status); r->rab$l_bkt = 0; } break; case iop_uic: { unsigned char *ch, ct, *end; uic_struct uic; struct XABPRO *xabpro; ch = pp->str.addr + p_offset; ct = *ch++; end = ch + ct; uic.grp = uic.mem = 0; xabpro = malloc(SIZEOF(struct XABPRO)); *xabpro = cc$rms_xabpro; /* g,m are octal - no matter currently since iorm_open overwrites fab xab */ while (*ch != ',' && ch < end) uic.grp = (10 * uic.grp) + (*ch++ - '0'); if (*ch == ',') { while (++ch < end) uic.mem = (10 * uic.mem) + (*ch - '0'); } xabpro->xab$l_uic = *((int4 *)&uic); f->fab$l_xab = xabpro; break; } case iop_width: if (iod->state == dev_open) { GET_LONG(width, pp->str.addr + p_offset); if (width <= 0) rts_error(VARLSTCNT(1) ERR_RMWIDTHPOS); else if (width <= rm_ptr->l_mrs) { iorm_flush(iod); rm_ptr->l_usz = iod->width = width; if (!rm_ptr->largerecord) r->rab$w_usz = (short)width; iod->wrap = TRUE; } } break; case iop_wrap: iod->wrap = TRUE; break; case iop_nowrap: iod->wrap = FALSE; break; case iop_convert: r->rab$l_rop |= RAB$M_CVT; break; case iop_rewind: if (iod->state == dev_open && rm_ptr->f.fab$l_dev & DEV$M_FOD) { if (iod->dollar.zeof && rm_ptr->outbuf_pos > rm_ptr->outbuf) iorm_wteol(1, iod); sys$rewind(r); iod->dollar.zeof = FALSE; iod->dollar.y = 0; iod->dollar.x = 0; rm_ptr->outbuf_pos = rm_ptr->outbuf; rm_ptr->r.rab$l_ctx = FAB$M_GET; } break; case iop_truncate: r->rab$l_rop |= RAB$M_TPT; break; case iop_notruncate: r->rab$l_rop &= ~RAB$M_TPT; break; case iop_bigrecord: if (iod->state != dev_open) rm_ptr->largerecord = TRUE; break; case iop_nobigrecord: if (iod->state != dev_open) { if (MAX_RMS_RECORDSIZE < rm_ptr->l_mrs) rts_error(ERR_RMNOBIGRECORD); rm_ptr->largerecord = FALSE; } break; case iop_rfm: break; default: break; } p_offset += ((IOP_VAR_SIZE == io_params_size[c]) ? (unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[c]); } if (shared_seen) { f->fab$b_shr = FAB$M_SHRGET; if (rm_ptr->largerecord) { if (f->fab$b_fac & FAB$M_PUT) { rts_error(VARLSTCNT(1) ERR_RMBIGSHARE); } } else if ((f->fab$b_fac & FAB$M_PUT) == FALSE) f->fab$b_shr |= FAB$M_SHRPUT; } }/* eor */