Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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 */