Beispiel #1
0
frame make_undef_call_frame(frame name, frame args)
{
    string und_name = allocate_var(name->cl + 1);
    
    strcpy(und_name, NORET(name->code));
    undef_calls = cons(und_name, undef_calls);

    name->decls = delete(und_name, name->decls, 0, 1);
    block_decls = delete(und_name, block_decls, 0, 1);

    if (args)
    {
	args = merge_frames(T_UNDEF, T_UNDEF, args, NULL, args->cl,
			    args->code, "");
	name = merge_frames(T_UNDEF, T_UNKNOWN, name, args,
			    name->cl + args->cl + 6,
			    RET, UNO, " ", name->code, ARG,
			    args->code, UNC, "");
    }
    else
	name = merge_frames(T_UNDEF, T_UNKNOWN, name, NULL, name->cl + 4,
			    RET, UNO, " ", name->code, UNC, "");
    
    name->undefs++;
    call_level--;

    return name;
}    
Beispiel #2
0
static frame make_lknv_frame(frame f, int n, int copy, rtype type)
{
    char v[8];
    string dv;

    if (copy)
    {
	frame cf = make_frame(f->type, NULL, f->cl, f->code, "");

	f = cf;
    }

    if (f->type == T_SLOT)
	return make_knv_frame(f, n);

    sprintf(v, "_v%c%d", LVAC, n);
    dv = make_decl(type, v);
    dv[0] = type;

    if (f->block)
    {
	int b = f->block;

	f = deblock_frame(f, 1);
	if (b != -1)
	    f = prepare_frame(f, type);
    }
    else if (f->type != type)
	f = coerce_frame(f, type);
    
    f->decls = cons(dv, f->decls);

    return merge_frames(T_CBOOL, T_UNKNOWN, f, NULL, f->cl + 18,
			"_lkn(" AMP, v, ", ", NORET(f->code), ")", "");
}
Beispiel #3
0
static frame make_knv_frame(frame f, int n)
{
    frame fc = make_frame(f->type, copy_list(f->decls, 0), 6, "_knv(" AMP, "");
    char v[8], buf[512];
    int i, l;
    string dv, st, next;

    sprintf(v, "_v%c%d", LVAC, n);
    dv = make_decl(T_ATOM, v);

    for (i = 0, st = f->code; ; st = next + 1) {
	next = strchr(st, NSTC);
	l = next ? next - st : strlen(st);

	strncpy(buf + i, st, l);
	i += l;
	strcpy(buf + i, ", ");
	i += 2;

	if (!next) break;
    }
    strcpy(buf + i, "NULL)");
    i += 5;

    fc->decls = cons(dv, fc->decls);
    
    return merge_frames(T_CBOOL, T_UNKNOWN, fc, NULL, fc->cl + i + 9,
		        fc->code, v, ", ", buf, "");
}
Beispiel #4
0
static frame make_log_frame(frame f1, frame f2, string op)
{
    f1 = prepare_frame(f1, T_CBOOL);
    f2 = prepare_frame(f2, T_CBOOL);

    return merge_frames(T_CBOOL, T_UNKNOWN, f1, f2, f1->cl + f2->cl + 5, RET,
			NORET(f1->code), op, NORET(f2->code), "");
}
Beispiel #5
0
frame make_cmp_frame(frame f1, frame f2, string op, rtype type, int l,
		     int trsl, int abs)
{
    rtype num = num_type(type) ? type : common_num_type(f1->type, f2->type);

    if (trsl && (!det_type(f1->type) || !det_type(f2->type) ||
		 f1->block == -1 || f2->block == -1))
    {
	if (det_type(f1->type))
	    f1 = prepare_frame(f1, num);
	if (det_type(f2->type))
	    f2 = prepare_frame(f2, num);

	return make_trsl_frame(f1, f2, num,
			       num == T_NUMBER ? 
   			           (abs ? merge_fainfix_strings :
				          merge_finfix_strings) :
			           merge_infix_strings,
			       op);
    }

    f1 = prepare_frame(f1, num);
    f2 = prepare_frame(f2, num);
    f1->code = NORET(f1->code);
    f2->code = NORET(f2->code);
    
    if (num == T_NUMBER)
    {
	int n = isnum(f2->code) << 1;
	string mop = n ? " - " : " - (";
	string cp = n ? "" : ")";

	if (abs)
	    f1 = merge_frames(num, num, f1, f2, f1->cl + f2->cl + 12 + n,
			      "fabs(", f1->code, mop, f2->code, ")", cp, "");
	else
	    f1 = merge_frames(num, num, f1, f2, f1->cl + f2->cl + 5 + n,
			      f1->code, mop, f2->code, cp, "");

	f2 = make_frame(num, NULL, l_epsilon + 1, epsilon, "");
    }

    return merge_frames(type == T_UNKNOWN ? num : type, num, f1, f2,
			f1->cl + f2->cl + l, RET, 
			f1->code, op, f2->code, "");
}
Beispiel #6
0
int
Task_Entry::reframe (ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries,
                     Task_Entry &owner,
                     ACE_Ordered_MultiSet <Dispatch_Entry_Link> &set,
                     u_long &set_period, u_long new_period)
{
  int result = 0;

  // if the set period is zero, treat it as uninitialized,
  // and simply value the set period with the new period
  if (set_period)
    {
      // make sure the new period is greater than the current
      // set period, and that they are harmonically related
      if (new_period <= set_period)
        // return an error if they're not harmonically related,
        // do nothing if set's frame is a multiple of the new frame
        return (set_period % new_period) ? -1 : 0;
      else if (new_period % set_period)
        return -1;

      // make a shallow copy of the set in a new ordered multiset
      // using the Dispatch_Entry_Link smart pointers
      ACE_Ordered_MultiSet <Dispatch_Entry_Link> new_set;
      ACE_Ordered_MultiSet_Iterator <Dispatch_Entry_Link> new_iter (new_set);
      ACE_Ordered_MultiSet_Iterator <Dispatch_Entry_Link> set_iter (set);

      for (set_iter.first (); set_iter.done () == 0; set_iter.advance ())
        {
          Dispatch_Entry_Link *link;

          if (set_iter.next (link) == 0)
            return -1;
          else if (new_set.insert (*link, new_iter) < 0)
            return -1;
        }

      // Do a deep copy merge back into the set using the new period
      // and starting after the 0th sub-frame: this puts all
      // dispatches after the 0th sub-frame of the new period into the
      // set, and leaves existing dispatches in the 0th sub-frame of
      // the new period in the set as well.
      result = merge_frames (dispatch_entries,
                             owner,
                             set,
                             new_set,
                             new_period,
                             set_period,
                             1,
                             1);
    }

  // update the set's period to be the new frame
  set_period = new_period;

  return result;
}
Beispiel #7
0
frame make_eq_frame(frame f1, frame f2, string op, string fop, string aop, 
                    rtype type, int l, int trsl)
{
    if (type == T_ATOM || type == T_BOOL ||
	(det_type(f1->type) && !num_type(f1->type) &&
	 f2->type == T_UNKNOWN && !member(f2->code, block_args, 0, 0, 1, 1) ||
	 det_type(f2->type) && !num_type(f2->type) &&
	 f1->type == T_UNKNOWN && !member(f1->code, block_args, 0, 0, 1, 1) ||
	 !det_type(f1->type) && !det_type(f2->type)))
    {
        int opeq = !strcmp(op, aop);
	
	if (type != T_BOOL && type != T_ATOM ||
	    type == T_BOOL && (!det_type(f1->type) || !det_type(f2->type)))
	    type = T_ATOM;

        if (trsl)
            return make_trsl_frame(f1, f2, type, 
                                   opeq ? merge_infix_strings :
                                          merge_flge_strings, aop);

	f1 = prepare_frame(f1, type);
	f2 = prepare_frame(f2, type);
	f1->code = NORET(f1->code);
	f2->code = NORET(f2->code);

	if (opeq)
	    return merge_frames(T_CBOOL, type, f1, f2, f1->cl + f2->cl + l,
				RET, f1->code, op, f2->code, "");

	return merge_frames(T_CBOOL, type, f1, f2,
			    f1->cl + f2->cl + l + l_epsilon + 5,
			    RET, aop, "(", f1->code, ", ", f2->code, ", ",
			    epsilon, ")", "");
    }
    else
    {
        rtype num = common_num_type(f1->type, f2->type);

        return make_cmp_frame(f1, f2, num == T_NUMBER ? fop : op, T_CBOOL, 
                              l, trsl, 1);
    }
}
Beispiel #8
0
frame make_not_frame(frame f, int trsl)
{
    if (trsl)
    {
	f = make_lknv_frame(f, 0, 0, T_BOOL);

	f = merge_frames(T_BOOL, T_UNKNOWN, f, NULL, f->cl + 50,
			 RET, f->code, " " QSM NST TABS, "_v0 != idFalse ", 
			 QSM " idFalse : idTrue : idNull", "");
	f->block = -1;

	return f;
    }

    f = prepare_frame(f, T_CBOOL);

    return merge_frames(T_CBOOL, T_UNKNOWN, f, NULL, f->cl + 4, RET,
			"!(", NORET(f->code), ")", "");
}
Beispiel #9
0
static frame prepare_trsl_frame(frame f, frame knv, string trcb)
{
    string trq;
    string trce = strchr(trcb + 1, TRLC);
    int l = trcb - f->code;

    trcb[0] = trce[0] = '\0';

    trq = strrchr(f->code, QSMC);
    trq[-1] = '\0';

    knv = knv ? merge_frames(T_UNKNOWN, T_UNKNOWN, knv, NULL,
			     knv->cl + l + 8, 
			     knv->code, " " AMP AMP " " NST TABS,
			     f->code, "") :
		make_frame(T_UNKNOWN, NULL, l + 1, f->code, "");

    f = merge_frames(T_UNKNOWN, T_UNKNOWN, f, NULL, trce - trcb, trcb + 1, "");

    return knv;
}
Beispiel #10
0
frame make_xor_frame(frame f1, frame f2, int trsl)
{
    if (trsl && (!det_type(f1->type) || !det_type(f2->type) ||
		 f1->block == -1 || f2->block == -1))
	return make_trsl_frame(f1, f2, T_BOOL, merge_fns_strings, "KpcXor");
    else
    {
	f1 = prepare_frame(f1, T_BOOL);
	f2 = prepare_frame(f2, T_BOOL);

	return merge_frames(T_BOOL, T_UNKNOWN, f1, f2, f1->cl + f2->cl + 12,
			    RET, "KpcXor(", NORET(f1->code), ", ",
			    NORET(f2->code), ")", "");
    }
}
Beispiel #11
0
frame make_arith_frame(frame f1, frame f2, string op, rtype type, int l,
		       int trsl)
{
    rtype num = num_type(type) ? type : common_num_type(f1->type, f2->type);

    if (trsl && (!det_type(f1->type) || !det_type(f2->type) ||
		 f1->block == -1 || f2->block == -1))
	return make_trsl_frame(f1, f2, num, merge_infix_strings, op);

    f1 = prepare_frame(f1, num);
    f2 = prepare_frame(f2, num);
    
    return merge_frames(type == T_UNKNOWN ? num : type, num, f1, f2,
			f1->cl + f2->cl + l, RET, 
			NORET(f1->code), op, NORET(f2->code), "");
}
Beispiel #12
0
static frame prepare_knv_frame(frame f, frame knv, string buf, string c)
{
    frame knv1 = make_knv_frame(f, ++vcount);

    if (c)
	sprintf(buf, "%s(_v%d)", c, vcount);
    else
	sprintf(buf, "_v%d", vcount);


    return knv = knv ? merge_frames(T_CBOOL, T_UNKNOWN, knv, knv1,
				    knv->cl + knv1->cl + 7,
				    knv->code, " "AMP AMP" " NST TABS,
				    knv1->code, "") :
		 knv1;
}
Beispiel #13
0
frame make_abouteq_frame(frame f1, frame f2, int trsl)
{
    if (trsl && (!det_type(f1->type) || !det_type(f2->type) ||
		 f1->block == -1 || f2->block == -1))
	return make_trsl_frame(f1, f2, T_NUMBER, merge_fns_strings,
			       "KpcAboutEq");
    else
    {
	f1 = prepare_frame(f1, T_NUMBER);
	f2 = prepare_frame(f2, T_NUMBER);

	return merge_frames(T_CBOOL, T_UNKNOWN, f1, f2,
			    f1->cl + f2->cl + 16,
			    RET, "KpcAboutEq(", NORET(f1->code), ", ",
			    NORET(f2->code), ")", "");
    }    
}
Beispiel #14
0
frame make_strcmp_frame(frame f1, frame f2, int trsl)
{
    if (trsl && (!det_type(f1->type) || !det_type(f2->type) ||
		 f1->block == -1 || f2->block == -1))
	return make_trsl_frame(f1, f2, T_ATOM, merge_fns_strings,
			       "_acm(");
    else
    {
	f1 = prepare_frame(f1, T_ATOM);
	f2 = prepare_frame(f2, T_ATOM);

	return merge_frames(T_CBOOL, T_UNKNOWN, f1, f2,
			    f1->cl + f2->cl + 16,
			    RET, "_acm(", NORET(f1->code), ", ",
			    NORET(f2->code), ")", "");
    }    
}
Beispiel #15
0
History & History::add (const Vector<float> & present)
{
  ASSERT_SIZE(present, m_size);

  // advance all frames
  for (Frame * f = m_frames; f; f = f->next) {
    f->time += 1;
  }

  // merge redundant frames of same rank
  for (Frame * f = m_frames; f and f->next; f = f->next) {
    Frame * g = f->next;

    if (g->rank != f->rank) {
      ASSERTW(g->rank == f->rank + 1,
          "found gap in history frames; try using higher density");
      continue;
    }

    while (g->next and (g->next->rank == g->rank)) {
      f = g;
      g = g->next;
    }

    const float resolution = 0.25f;
    if (log_time(g->time) - log_time(f->time) < resolution) {
      merge_frames(f);
    }
  }

  // pop obsolete frames
  for (Frame * f = m_frames; f and f->next; f = f->next) {
    const float padding = 1;
    if (log_time(f->next->time) >= m_length + padding) {
      crop_to_frame(f);
    }
  }

  // add new frame
  add_frame(present);

  return * this;
}
Beispiel #16
0
frame make_fcmp_frame(frame f1, frame f2, string op, string fop, rtype type,
		      int l, int trsl)
{
    rtype num = num_type(type) ? type : common_num_type(f1->type, f2->type);

    if (num != T_NUMBER)
	return make_cmp_frame(f1, f2, op, type, l, trsl, 0);

    if (trsl && (!det_type(f1->type) || !det_type(f2->type) ||
		 f1->block == -1 || f2->block == -1))
	return make_trsl_frame(f1, f2, num, merge_flge_strings, fop);

    f1 = prepare_frame(f1, num);
    f2 = prepare_frame(f2, num);
    
    return merge_frames(type, num, f1, f2, f1->cl + f2->cl + l_epsilon + 12,
			RET, fop, "(", NORET(f1->code), ", ",
			NORET(f2->code), ", ", epsilon, ")", "");
}
Beispiel #17
0
int
Task_Entry::disjunctive_merge (Dependency_Type dt,
                               ACE_Unbounded_Set <Dispatch_Entry *> &dispatch_entries,
                               ACE_CString &unresolved_locals,
                               ACE_CString &unresolved_remotes)
{
  char string_buffer[BUFSIZ];

  // Iterate over the set of dependencies, merging dispatches of the
  // callers over the enclosing frame size.
  for (ACE_Unbounded_Set_Iterator <Task_Entry_Link *> iter (callers_);
       ! iter.done ();
       iter.advance ())
    {
      Task_Entry_Link **link;

      if (iter.next (link) == 0
          || link == 0
          || *link == 0)
        return -1;

      // The link matches the dependency type given
      if ((*link)->dependency_type () == dt)
        {
          // Check for and warn about unresolved remote dependencies
          // in the ONE_WAY call graph.
          if ((*link)->dependency_type () == RtecBase::ONE_WAY_CALL
              && (*link)->caller ().has_unresolved_remote_dependencies ()
              && ! this->has_unresolved_remote_dependencies ())
            {
              // Propagate the unresolved remote dependency flag, and
              // issue a debug scheduler warning.
              this->has_unresolved_remote_dependencies (1);
              ORBSVCS_DEBUG ((LM_DEBUG,
                          "Warning: an operation identified by "
                          "\"%s\" has unresolved remote dependencies.\n",
                          (const char*) this->rt_info ()->entry_point));

              // Record entry point in list of unresolved remote
              // dependencies
              ACE_OS::sprintf (string_buffer,
                               "// %s\n",
                               (const char*) this->rt_info ()->entry_point);
              unresolved_remotes +=
                ACE_CString (string_buffer);

            }

          // Check for and warn about unresolved local dependencies in
          // the ONE_WAY call graph.
          if ((*link)->dependency_type () == RtecBase::ONE_WAY_CALL
              && (*link)->caller ().has_unresolved_local_dependencies ()
              && ! this->has_unresolved_local_dependencies ())
            {
              // Propagate the unresolved local dependency flag, and
              // issue a debug scheduler warning.
              this->has_unresolved_local_dependencies (1);
              ORBSVCS_DEBUG ((LM_DEBUG,
                          "Warning: an operation identified by "
                          "\"%s\" has unresolved local dependencies.\n",
                          (const char*) this->rt_info ()->entry_point));

              // Record entry point in list of unresolved local
              // dependencies
              ACE_OS::sprintf (string_buffer,
                               "// %s\n",
                               (const char*) this->rt_info ()->entry_point);
              unresolved_locals +=
                ACE_CString (string_buffer);
            }

          // Merge the caller's dispatches into the current set.
          if (merge_frames (dispatch_entries,
                            *this,
                            dispatches_,
                            (*link)->caller ().dispatches_, effective_period_,
                            (*link)->caller ().effective_period_,
                            (*link)->number_of_calls ()) < 0)
            return -1;
        }
    }

  return 0;
}
Beispiel #18
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);
	    }
	}
Beispiel #19
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;
}