Exemple #1
0
static void coerce_arg(rtype type, rtype ftype, int l, string code,
		       string *buf, int *i, int *lbuf,
		       int int_allowed, frame name)
{
    frame f = make_frame(type, NULL, l, code, "");

    if ((type == T_INTNUM || type == T_INTLNG) && !int_allowed)
	f = coerce_frame(f, T_NUMBER);

    f = coerce_frame(f, ftype);
    if (f->decls)
	name->decls = nconc(name->decls, copy_list(f->decls, 0));

    NORET(f->code);
    *buf = copy_into_buf(*buf, f->code, i, lbuf, strlen(f->code));

    mcfree(f->code);
    mcfree(f);
}
Exemple #2
0
int comp_fini(bool status, mstr *obj, opctype retcode, oprtype *retopr, int src_len)
{

	triple *ref;
	error_def(ERR_INDEXTRACHARS);

	if (status  &&  source_column != src_len + 2  &&  source_buffer[source_column] != '\0')
	{
		status = FALSE;
		stx_error(ERR_INDEXTRACHARS);
	}
	if (status)
	{
		cg_phase = CGP_RESOLVE;
		assert(for_stack_ptr == for_stack);
		if (*for_stack_ptr)
			tnxtarg(*for_stack_ptr);
		ref = newtriple(retcode);
		if (retopr)
			ref->operand[0] = *retopr;
		start_fetches(OC_NOOP);
		resolve_ref(0);	/* cannot fail because there are no MLAB_REF's in indirect code */
		alloc_reg();
		stp_gcol(0);
		assert(indr_stringpool.base == stringpool.base);
		indr_stringpool = stringpool;
		stringpool = rts_stringpool;
		compile_time = FALSE;
 		ind_code(obj);
		indr_stringpool.free = indr_stringpool.base;
	}
	else
	{
		assert(indr_stringpool.base == stringpool.base);
		indr_stringpool = stringpool;
		stringpool = rts_stringpool;
		indr_stringpool.free = indr_stringpool.base;
		compile_time = FALSE;
		cg_phase = CGP_NOSTATE;
	}
	transform = TRUE;
	mcfree();
	return status;

}
Exemple #3
0
void op_zcompile(mval *v, boolean_t mExtReqd)
{
	unsigned		status;
	command_qualifier	save_qlf;
	unsigned short		len;
	char			source_file_string[FILE_NAME_SIZE + 1],
				obj_file[FILE_NAME_SIZE + 1],
				list_file[FILE_NAME_SIZE + 1],
				ceprep_file[FILE_NAME_SIZE + 1];
#	ifdef UNIX
	CLI_ENTRY		*save_cmd_ary;
#	endif
	size_t			mcallocated, alloc;
	mcalloc_hdr		*lastmca, *nextmca;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	MV_FORCE_STR(v);
	if (!v->str.len)
		return;
	save_qlf = glb_cmd_qlf;
	glb_cmd_qlf.object_file.str.addr = obj_file;
	glb_cmd_qlf.object_file.str.len = FILE_NAME_SIZE;
	glb_cmd_qlf.list_file.str.addr = list_file;
	glb_cmd_qlf.list_file.str.len = FILE_NAME_SIZE;
	glb_cmd_qlf.ceprep_file.str.addr = ceprep_file;
	glb_cmd_qlf.ceprep_file.str.len = FILE_NAME_SIZE;
	zl_cmd_qlf(&v->str, &glb_cmd_qlf);
	cmd_qlf = glb_cmd_qlf;
	assert(run_time);
	assert(rts_stringpool.base == stringpool.base);
	rts_stringpool = stringpool;
	if (!indr_stringpool.base)
	{
		stp_init (STP_INITSIZE);
		indr_stringpool = stringpool;
	} else
		stringpool = indr_stringpool;
	run_time = FALSE;
	TREF(compile_time) = TRUE;
	TREF(transform) = FALSE;
	TREF(dollar_zcstatus) = SS_NORMAL;
	len = FILE_NAME_SIZE;
#	ifdef UNIX
	/* The caller of this function could be GT.M, DSE, MUPIP, GTCM GNP server, GTCM OMI server etc. Most of them have their
	 * own command parsing tables and some dont even have one. Nevertheless, we need to parse the string as if it was a
	 * MUMPS compilation command. So we switch temporarily to the MUMPS parsing table "mumps_cmd_ary". Note that the only
	 * rts_errors possible between save and restore of the cmd_ary are in compile_source_file and those are internally
	 * handled by source_ch which will transfer control back to us (right after the the call to compile_source_file below)
	 * and hence proper restoring of cmd_ary is guaranteed even in case of errors.
	 */
	save_cmd_ary = cmd_ary;
	cmd_ary = mumps_cmd_ary;
#	endif
	mcfree();	/* If last compile errored out, may have left things uninitialized for us */
	/* Find out how much space we have in mcalloc blocks */
	for (mcallocated = 0, nextmca = mcavailptr; nextmca; nextmca = nextmca->link)
		mcallocated += nextmca->size;
	if (0 == mcallocated)
		mcallocated = MC_DSBLKSIZE - MCALLOC_HDR_SZ;	/* Min size is one default block size */
	for (status = cli_get_str("INFILE",source_file_string, &len);
		status;
		status = cli_get_str("INFILE",source_file_string, &len))
	{
		compile_source_file(len, source_file_string, mExtReqd);
		len = FILE_NAME_SIZE;
	}
	/* Determine if need to remove any added added mc blocks. Min value of mcallocated will ensure
	 * we leave at least one block alone.
	 */
	for (alloc = 0, nextmca = mcavailptr;
	     nextmca && (alloc < mcallocated);
	     alloc += nextmca->size, lastmca = nextmca, nextmca = nextmca->link);
	if (nextmca)
	{	/* Start freeing at the nextmca node since these are added blocks */
		lastmca->link = NULL;	/* Sever link to further blocks here */
		/* Release any remaining blocks if any */
		for (lastmca = nextmca; lastmca; lastmca = nextmca)
		{
			nextmca = lastmca->link;
			free(lastmca);
		}
	}
#	ifdef UNIX
	cmd_ary = save_cmd_ary;	/* restore cmd_ary */
#	endif
	assert((FALSE == run_time) && (TRUE == TREF(compile_time)));
	run_time = TRUE;
	TREF(compile_time) = FALSE;
	TREF(transform) = TRUE;
	indr_stringpool = stringpool;
	stringpool = rts_stringpool;
	indr_stringpool.free = indr_stringpool.base;
	glb_cmd_qlf = save_qlf;
}
Exemple #4
0
static frame make_regular_call_frame(frame name, frame args, string header,
				     int int_allowed, int kappafn)
{
    char fname[ATOBUF_SIZE + 4];
    string varg, next, n = NULL;
    int i = 0;
    string arg = strchr(header, ' ') + 1;
    string rest = NULL;
    string kappac = header[1] == STA ? "" : kappafn ? KPC : appfn_prefix;
    string buf;
    int lbuf = (args ? args->cl : 0) + 128;
    int nnullp = strcmp(name->code, "Null?");
    list delvars = NULL;
    int bren = -1;

    sprintf(fname, "%s%s", kappac, name->code);

    if (!call_level && nnullp)
	error(1, "Call level error while parsing call to '%s' in %s",
	      name->code, block_name);

    if (!nnullp) --trilog;
    --call_level;

    if (parsing_rule_if && args && slotref_parsed & (1 << call_level))
    {
	if (strcmp(name->code, "KnownValue?") && nnullp)
	    warn("Suspicious call to '%s' in premise of rule %s",
		 name->code, block_name);
	slotref_parsed &= ~(1 << call_level);
    }

    if (!arg[0])
	return merge_frames(header[0], header[0], name, NULL, name->cl + 6,
			    RET, fname, "()", "");

    buf = (string) mcalloc(lbuf);

    varg = args ? argtok(args->code, &rest) : NULL;

    if (header[0] == T_STRING)
    {
	MAKE_BUFFER(bname, SLOBUF);

	sprintf(buf, "%s%s", bname, arg[1] ? ", " : "");
	i = strlen(bname) + (arg[1] ? 2 : 0);
    }

    for (arg += (header[0] == T_STRING); arg[0]; varg = next) {
	char arg0 = arg[0] & ~PTRF;

	if (arg0 == T_HANDLE && arg[1] != VAGC)
	{
	    next = varg;
	    strcpy(buf + i, "hInstance, ");
	    i += 11;
	    ++arg;
	    continue;
	}

	if (varg)
	{
	    next = argtok(rest, &rest);
	    n = (next ? next : varg + strlen(varg) + 1);
	}
	else
	    next = NULL;

	if (varg && varg[0] != arg0) /* not the normal case.               */
	{
	    if (varg[0] == T_UNKNOWN || varg[0] == T_UNDEF)
	    {
		if (varg[1] == UNOC) /* case of an unfinished function call. */
		{
		    varg[2] = arg0;
		    buf = copy_into_buf(buf, varg + 1, &i, &lbuf,
					n - varg - 2);
		}
		else
		{
		    list m = member(varg, block_decls, 0, 0, 1, 1);
		    int vl = strlen(varg);

		    if (m) /* case of a variable of unknown type.            */
		    {
			if (car(m)[0] == T_UNKNOWN || car(m)[0] == T_UNDEF)
			{
			    list a = member(varg, args->decls, 0, 0, 1, 1);
			    list b = member(varg, block_args, 0, 0, 1, 1);
			    list d = a ? NULL
				       : member(varg, delvars, 0, 0, 1, 1);

			    if (arg0 == T_STRING && !b)
			    {
				buf[i++] = '"';
				buf = copy_into_buf(buf, varg + 1, &i, &lbuf,
						    n - varg - 2);
				buf[i++] = '"';
				if (a && !d)
				{
				    delvars = cons(car(a), delvars);
				    args->decls = delete(varg,
							 args->decls, 1, 1);
				}
			    }
			    else
			    {
				if (!b) /* declaring as atom or object.      */
				{ 
				    string tmp;
				    rtype dt =
					arg0 == T_OBJECT ? T_OBJECT : T_ATOM;
				    tmp = create_adda_call(dt, varg, vl);
				    tmp[0] = dt;
				    if (a && car(m) == car(a))
				    {
					mcfree(car(m));
					car(m) = car(a) = tmp;
				    }
				    else
				    {
					car(m) = tmp;
					if (!a && d)
					    args->decls =
						cons(car(d), args->decls);
				    }
				}
				else
				{
				    if (a)
					car(a)[0] = arg0;
				    else if (d)
				    {
					car(d)[0] = arg0;
					args->decls = cons(car(d),
							   args->decls);
				    }

				    car(m)[0] = arg0;
				}

				if (car(m)[0] == arg0)
				    goto normal;
				else
				    goto coerce;
			    }
			}
			else coerce:
			    coerce_arg(car(m)[0], arg0, n - varg, varg + 1,
				       &buf, &i, &lbuf, int_allowed, name);
		    }
		    else    /* case of a finished function */
		    {
			string fn = strchr(varg + 1, '(');
			int fl = fn - varg - 1 - appfn_pl;

			m = member(varg, headers, 0, fl, appfn_pl + 1, 2);
			coerce_arg(car(m)[0], arg0, n - varg, varg + 1,
				   &buf, &i, &lbuf, int_allowed, name);
#ifdef OLD
			else if (user_headers.count)
			{
			    char fname[48];
			    string *pr;

			    strncpy(fname, varg + appfn_pl + 1, fl);
			    fname[fl] = '\0';
			    pr = bsearch(&fname, user_headers.table,
					 user_headers.count,
					 sizeof(string), (sortfn) hcomp);

			    coerce_arg(*pr[0], arg0, n - varg, varg + 1,
				       &buf, &i, &lbuf, int_allowed, name);
			}			    
#endif
		    }
		}
	    }
	    else
	    {
		int bd = arg0 == T_ATOM && varg[0] == T_OBJECT;

		if (bren == -1 && bd)
		    bren = !strcmp(name->code, "RenameInstance") ||
			   !strcmp(name->code, "RenameClass");

		if (bren == 1 && bd)
		{
		    char nv1[32], nv2[32];

                    novar(nv1, varg + 1);
		    novar(nv2, name->code);
		    warn("%s was compiled as an object in call to %s, line %d.",
			 nv1, nv2, yylineno);
		}
		    
		coerce_arg(varg[0], arg0, n - varg, varg + 1, &buf, &i,
			   &lbuf, int_allowed, name);
	    }
	}
int comp_fini(int status, mstr *obj, opctype retcode, oprtype *retopr, oprtype *dst, mstr_len_t src_len)
{
	triple *ref;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	if (status)
	{
		while (TK_SPACE == TREF(window_token))	/* Eat up trailing white space */
			advancewindow();
		if (TK_ERROR == TREF(window_token))
		{
			status = EXPR_FAIL;
			stx_error(ERR_INDRCOMPFAIL);
		} else if ((TK_EOL != TREF(window_token)) || (source_column < src_len))
		{
			status = EXPR_FAIL;
			stx_error(ERR_INDEXTRACHARS);
		} else
		{
			cg_phase = CGP_RESOLVE;
			assert(TREF(for_stack_ptr) == TADR(for_stack));
			if (*TREF(for_stack_ptr))
				tnxtarg(*TREF(for_stack_ptr));
			ref = newtriple(retcode);
			if (retopr)
				ref->operand[0] = *retopr;
			if (OC_IRETMVAL == retcode)
				ref->operand[1] = *dst;
			start_fetches(OC_NOOP);
			resolve_ref(0);	/* cannot fail because there are no MLAB_REF's in indirect code */
			alloc_reg();
			INVOKE_STP_GCOL(0);
			/* The above invocation of stp_gcol with a parameter of 0 is a critical part of compilation
			 * (both routine compilations and indirect dynamic compilations). This collapses the indirect
			 * (compilation) stringpool so that only the literals are left. This stringpool is then written
			 * out to the compiled object as the literal pool for that compilation. Temporary stringpool
			 * use for conversions or whatever are eliminated. Note the path is different in stp_gcol for
			 * the indirect stringpool which is only used during compilations.
			 */
			assert(indr_stringpool.base == stringpool.base);
			indr_stringpool = stringpool;
			stringpool = rts_stringpool;
			TREF(compile_time) = FALSE;
			ind_code(obj);
			indr_stringpool.free = indr_stringpool.base;
		}
	} else
	{	/* If this assert fails, it means a syntax problem could have been caught earlier. Consider placing a more useful
		 * and specific error message at that location.
		 */
		assert(FALSE);
		stx_error(ERR_INDRCOMPFAIL);
	}
	if (EXPR_FAIL == status)
	{
		assert(indr_stringpool.base == stringpool.base);
		indr_stringpool = stringpool;
		stringpool = rts_stringpool;
		indr_stringpool.free = indr_stringpool.base;
		TREF(compile_time) = FALSE;
		cg_phase = CGP_NOSTATE;
	}
	TREF(transform) = TRUE;
	COMPILE_HASHTAB_CLEANUP;
	mcfree();
	return status;
}
Exemple #6
0
static frame make_trsl_frame(frame f1, frame f2, rtype type, 
			     void (*merge_fn)(string, string,
					      string, va_list), ...)

{
    frame knv = NULL;
    string c = coerce_from_atom[type - T_NUMBER];
    char cv1[12], cv2[12];
    int f1s = f1->type == T_SLOT;
    int f2s = f2->type == T_SLOT;
    string check = " " QSM " idTrue : idFalse) : idNull";
    string trcb;
    char buf[512];
    va_list ap;

    va_start(ap, merge_fn);

    NORET(f1->code);
    NORET(f2->code);

    if (!det_type(type) || type == T_OBJECT)
	type = T_ATOM;

    if (f1s)
	knv = prepare_knv_frame(f1, knv, cv1, c);
    else if (trcb = strchr(f1->code, TRLC))
	knv = prepare_trsl_frame(f1, knv, trcb);
    else if (type == T_ATOM || type == T_BOOL)
    {
	f1 = prepare_frame(f1, type);

	if (member(f1->code, block_args, 0, 0, 0, 1) ||
	    !member(f1->code, block_decls, 0, 0, 0, 1))
	{
	    knv = make_lknv_frame(f1, ++vcount, 1, type);
	    f1->cl = 8;
	    f1->code = (string) recalloc(f1->code, f1->cl);
	    sprintf(f1->code, "_v%d", vcount);
	}
    }

    if (f2s)
	knv = prepare_knv_frame(f2, knv, cv2, c);
    else if (trcb = strchr(f2->code, TRLC))
	knv = prepare_trsl_frame(f2, knv, trcb);
    else if (type == T_ATOM || type == T_BOOL)
    {
	f2 = prepare_frame(f2, type);

	if (member(f2->code, block_args, 0, 0, 0, 1) ||
	    !member(f2->code, block_decls, 0, 0, 0, 1))
	{
	    frame knv1 = make_lknv_frame(f2, ++vcount, 1, type);

	    knv = knv ? merge_frames(T_CBOOL, T_UNKNOWN, knv, knv1,
				     knv->cl + knv1->cl + 7,
				     knv->code, " "AMP AMP" " NST TABS,
				     knv1->code, "") :
	                knv1;
	    f2->cl = 8;
	    f2->code = (string) recalloc(f2->code, f2->cl);
	    sprintf(f2->code, "_v%d", vcount);
	}
    }

    if (knv)
	f1->decls = merge_decl_lists(T_UNKNOWN, f1->decls, knv->decls);
    
    (*merge_fn)(buf, f1s ? cv1 : NORET(f1->code),
		f2s ? cv2 : NORET(f2->code), ap);

    if (knv)
    {
	f1 = merge_frames(T_BOOL, type, f1, f2,
			  knv->cl + strlen(buf) + strlen(check) + 12,
			  RET, knv->code, " " QSM NST TABS " (", TRL, buf, TRL,
			  check, "");
	mcfree(knv->code);
	mcfree(knv);
    }	
    else
	f1 = merge_frames(T_BOOL, type, f1, f2, strlen(buf) + 4,
			  RET, TRL, buf, TRL, "");

    va_end(ap);

    f1->block = -1;

    return f1;
}