Beispiel #1
0
BEGIN_C_DECLS

/****************************************************************************/
/*                                                         DRIVERS FOR ODEs */

/*--------------------------------------------------------------------------*/
/*                                                                  forodec */
/* forodec(tag, n, tau, dold, dnew, X[n][d+1])                              */
fint forodec_(fint* ftag,    /* tape identifier */
              fint* fn,       /* space dimension */
              fdouble* ftau,  /* scaling defaults to 1.0 */
              fint* fdol,     /* previous degree defaults to zero */
              fint* fdeg,     /* New degree of consistency        */
              fdouble* fy)    /* Taylor series                    */
{
    int rc= -1;
    short tag= (short) *ftag;
    int n=*fn, dol=*fdol, deg=*fdeg;
    int i;
    double tau=*ftau;
    double** Y = myalloc2(n,deg+1);
    for(i=0;i<n;i++)
        *Y[i] = fy[i];
    rc= forodec(tag,n,tau,dol,deg,Y);
    pack2(n,deg+1,Y,fy);
    free((char*)*Y);
    free((char*)Y);
    return rc;
}
Beispiel #2
0
/*--------------------------------------------------------------------------*/
fint fov_forward_(fint* ftag,
                  fint* fm,
                  fint* fn,
                  fint* fp,
                  fdouble* fbase,
                  fdouble* fx,
                  fdouble* fvalue,
                  fdouble* fy) {
    int rc= -1;
    int tag=*ftag, m=*fm, n=*fn, p=*fp;
    double* base = myalloc1(n);
    double* value = myalloc1(m);
    double** X = myalloc2(n,p);
    double** Y = myalloc2(m,p);
    spread1(n,fbase,base);
    spread2(n,p,fx,X);
    rc= fov_forward(tag,m,n,p,base,X,value,Y);
    pack2(m,p,Y,fy);
    pack1(m,value,fvalue);
    free((char*)*X);
    free((char*)X);
    free((char*)*Y);
    free((char*)Y);
    free((char*)base);
    free((char*)value);
    return rc;
}
Beispiel #3
0
BEGIN_C_DECLS

/*--------------------------------------------------------------------------*/
fint hos_forward_(fint* ftag,
                  fint* fm,
                  fint* fn,
                  fint* fd,
                  fint* fk,
                  fdouble* fbase,
                  fdouble* fx,
                  fdouble* fvalue,
                  fdouble* fy) {
    int rc= -1;
    int tag=*ftag, m=*fm, n=*fn, d=*fd, k=*fk;
    double* base = myalloc1(n);
    double* value = myalloc1(m);
    double** X = myalloc2(n,d);
    double** Y = myalloc2(m,d);
    spread1(n,fbase,base);
    spread2(n,d,fx,X);
    rc= hos_forward(tag,m,n,d,k,base,X,value,Y);
    pack2(m,d,Y,fy);
    pack1(m,value,fvalue);
    free((char*)*X);
    free((char*)X);
    free((char*)*Y);
    free((char*)Y);
    free((char*)base);
    free((char*)value);
    return rc;
}
Beispiel #4
0
gui::ImageSpace::ImageSpace() {
	set_border_width(BORDER_WIDTH);
	originalImage_.set_label("Original Image");
	currentImage_.set_label("Current Image");
	pack1(originalImage_, false, false);
	pack2(currentImage_, false, false);
	show_all_children();
}
Beispiel #5
0
JPaned::JPaned(){
    drawing = new Gtk::DrawingArea();
    playerlist = new PlayerList();
    drawing->override_background_color(
        Gdk::RGBA("BLACK"), Gtk::STATE_FLAG_NORMAL);
    pack1(*drawing, Gtk::EXPAND);
    pack2(*playerlist, Gtk::FILL);
    show_all();
    drawing->add_events(Gdk::POINTER_MOTION_MASK);
    drawing->signal_motion_notify_event().connect(
        sigc::mem_fun(*this, &JPaned::motion));}
void deconv2(void *g, int row_g, int col_g, void *f, int row_f, int col_f, void *out) {
	double *g2 = unpack2(g, row_g, col_g, col_g);
	double *f2 = unpack2(f, row_f, col_f, col_g);

	double ff[(row_g - row_f + 1) * col_g];
	deconv(g2, row_g * col_g, f2, row_f * col_g, ff, col_g);
	pack2(ff, row_g - row_f + 1, col_g, col_g - col_f + 1, out);

	free(g2);
	free(f2);
}
/**
 * Truncate the bit width.
 *
 * TODO: Handle saturation consistently.
 */
LLVMValueRef
lp_build_pack(struct gallivm_state *gallivm,
              struct lp_type src_type,
              struct lp_type dst_type,
              boolean clamped,
              const LLVMValueRef *src, unsigned num_srcs)
{
   LLVMValueRef (*pack2)(struct gallivm_state *gallivm,
                         struct lp_type src_type,
                         struct lp_type dst_type,
                         LLVMValueRef lo,
                         LLVMValueRef hi);
   LLVMValueRef tmp[LP_MAX_VECTOR_LENGTH];
   unsigned i;

   /* Register width must remain constant */
   assert(src_type.width * src_type.length == dst_type.width * dst_type.length);

   /* We must not loose or gain channels. Only precision */
   assert(src_type.length * num_srcs == dst_type.length);

   if(clamped)
      pack2 = &lp_build_pack2;
   else
      pack2 = &lp_build_packs2;

   for(i = 0; i < num_srcs; ++i)
      tmp[i] = src[i];

   while(src_type.width > dst_type.width) {
      struct lp_type tmp_type = src_type;

      tmp_type.width /= 2;
      tmp_type.length *= 2;

      /* Take in consideration the sign changes only in the last step */
      if(tmp_type.width == dst_type.width)
         tmp_type.sign = dst_type.sign;

      num_srcs /= 2;

      for(i = 0; i < num_srcs; ++i)
         tmp[i] = pack2(gallivm, src_type, tmp_type,
                        tmp[2*i + 0], tmp[2*i + 1]);

      src_type = tmp_type;
   }

   assert(num_srcs == 1);

   return tmp[0];
}
Beispiel #8
0
/* Establish data connection and return the socket descriptor */
int
ftp_pasv(int fd)
{
	struct sockaddr_in	sa;
	char			buf[MAX_LINE], *s, *e;
	uint			addr[4], port[2];
	int			ret, sock;

	if (writeline(fd, "PASV\r\n") == -1)
		return -1;

	if (ftp_readline(fd, buf, sizeof buf) != P_OK)
		return -1;

	if ((s = strchr(buf, '(')) == NULL || (e = strchr(s, ')')) == NULL) {
		warnx("Malformed PASV reply");
		return -1;
	}

	s++;
	*e = '\0';
	ret = sscanf(s, "%u,%u,%u,%u,%u,%u",
	    &addr[0], &addr[1], &addr[2], &addr[3],
	    &port[0], &port[1]);

	if (ret != 6) {
		warnx("Passive mode address scan failure");
		return -1;
	}

	memset(&sa, 0, sizeof sa);
	sa.sin_family = AF_INET;
	sa.sin_len = sizeof(sa);
	sa.sin_addr.s_addr = htonl(pack4(addr, 0));
	sa.sin_port = htons(pack2(port, 0));

	if ((sock = socket(sa.sin_family, SOCK_STREAM, 0)) == -1)
		err(1, "ftp_pasv: socket");

	if (connect(sock, (struct sockaddr *)&sa, sa.sin_len) == -1) {
		if (errno == EINTR) {
			if (close(sock) == -1 && errno != EINTR)
				err(1, "ftp_pasv: close");
			return -1;
		}
		err(1, "ftp_pasv: connect");
	}

	return sock;
}
Beispiel #9
0
/* jacobian(tag, m, n, x[n], J[m][n])                                       */
fint jacobian_(fint* ftag,
               fint* fdepen,
               fint* findep,
               fdouble *fargument,
               fdouble *fjac) {
    int rc= -1;
    int tag=*ftag, depen=*fdepen, indep=*findep;
    double** Jac = myalloc2(depen,indep);
    double* argument = myalloc1(indep);
    spread1(indep,fargument,argument);
    rc= jacobian(tag,depen,indep,argument,Jac);
    pack2(depen,indep,Jac,fjac);
    free((char*)*Jac);
    free((char*)Jac);
    free((char*)argument);
    return rc;
}
Beispiel #10
0
/*--------------------------------------------------------------------------*/
fint hos_reverse_(fint* ftag,
                  fint* fm,
                  fint* fn,
                  fint* fd,
                  fdouble* fu,
                  fdouble* fz) {
    int rc=-1;
    int tag=*ftag, m=*fm, n=*fn, d=*fd;
    double** Z = myalloc2(n,d+1);
    double* u = myalloc1(m);
    spread1(m,fu,u);
    rc=hos_reverse(tag,m,n,d,u,Z);
    pack2(n,d+1,Z,fz);
    free((char*)*Z);
    free((char*)Z);
    free((char*)u);
    return rc;
}
Beispiel #11
0
/* hessian(tag, n, x[n], lower triangle of H[n][n])                         */
fint hessian_(fint* ftag,
              fint* fn,
              fdouble* fx,
              fdouble* fh) /* length of h should be n*n but the
                            upper half of this matrix remains unchanged */
{
    int rc= -1;
    int tag=*ftag, n=*fn;
    double** H = myalloc2(n,n);
    double* x = myalloc1(n);
    spread1(n,fx,x);
    rc= hessian(tag,n,x,H);
    pack2(n,n,H,fh);
    free((char*)*H);
    free((char*)H);
    free((char*)x);
    return rc;
}
Beispiel #12
0
void PackUnix::pack(OutputFile *fo)
{
    Filter ft(ph.level);
    ft.addvalue = 0;
    b_len = 0;
    progid = 0;

    // set options
    blocksize = opt->o_unix.blocksize;
    if (blocksize <= 0)
        blocksize = BLOCKSIZE;
    if ((off_t)blocksize > file_size)
        blocksize = file_size;

    // init compression buffers
    ibuf.alloc(blocksize);
    obuf.allocForCompression(blocksize);

    fi->seek(0, SEEK_SET);
    pack1(fo, ft);  // generate Elf header, etc.

    p_info hbuf;
    set_te32(&hbuf.p_progid, progid);
    set_te32(&hbuf.p_filesize, file_size);
    set_te32(&hbuf.p_blocksize, blocksize);
    fo->write(&hbuf, sizeof(hbuf));

    // append the compressed body
    if (pack2(fo, ft)) {
        // write block end marker (uncompressed size 0)
        b_info hdr; memset(&hdr, 0, sizeof(hdr));
        set_le32(&hdr.sz_cpr, UPX_MAGIC_LE32);
        fo->write(&hdr, sizeof(hdr));
    }

    pack3(fo, ft);  // append loader

    pack4(fo, ft);  // append PackHeader and overlay_offset; update Elf header

    // finally check the compression ratio
    if (!checkFinalCompressionRatio(fo))
        throwNotCompressible();
}
Beispiel #13
0
/*--------------------------------------------------------------------------*/
fint fov_reverse_(fint* ftag,
                  fint* fm,
                  fint* fn,
                  fint* fq,
                  fdouble* fu,
                  fdouble* fz) {
    int rc=-1;
    int tag=*ftag, m=*fm, n=*fn, q=*fq;
    double** U = myalloc2(q,m);
    double** Z = myalloc2(q,n);
    spread2(q,m,fu,U);
    rc=fov_reverse(tag,m,n,q,U,Z);
    pack2(q,n,Z,fz);
    free((char*)*Z);
    free((char*)Z);
    free((char*)*U);
    free((char*)U);
    return rc;
}
Beispiel #14
0
/*--------------------------------------------------------------------------*/
fint hos_ti_reverse_(
    fint* ftag,
    fint* fm,
    fint* fn,
    fint* fd,
    fdouble* fu,
    fdouble* fz) {
    int rc=-1;
    int tag=*ftag, m=*fm, n=*fn, d=*fd;
    double** Z = myalloc2(n,d+1);
    double** U = myalloc2(m,d+1);
    spread2(m,d+1,fu,U);
    rc=hos_ti_reverse(tag,m,n,d,U,Z);
    pack2(n,d+1,Z,fz);
    free((char*)*Z);
    free((char*)Z);
    free((char*)*U);
    free((char*)U);
    return rc;
}
void copyTV(Vout& v, Vloc src, Vloc dst, Type destType) {
  auto src_arity = src.numAllocated();
  auto dst_arity = dst.numAllocated();

  if (dst_arity == 2) {
    always_assert(src_arity == 2);
    v << copy2{src.reg(0), src.reg(1), dst.reg(0), dst.reg(1)};
    return;
  }
  always_assert(dst_arity == 1);

  if (src_arity == 2 && dst.isFullSIMD()) {
    pack2(v, src.reg(0), src.reg(1), dst.reg(0));
    return;
  }
  always_assert(src_arity >= 1);

  if (src_arity == 2 && destType <= TBool) {
    v << movtqb{src.reg(0), dst.reg(0)};
  } else {
    v << copy{src.reg(0), dst.reg(0)};
  }
}
Beispiel #16
0
static int cli_send_columns(int statement, int cmd)
{
    statement_desc* s = statements.get(statement);
    column_binding* cb;
    if (s == NULL) { 
	return cli_bad_descriptor;
    }
    long msg_size = sizeof(cli_request);
    if (cmd == cli_cmd_update) { 
	if (!s->prepared) { 
	    return cli_not_fetched;
	}
	if (s->oid == 0) { 
	    return cli_not_found;
	}
	if (!s->for_update) { 
	    return cli_not_update_mode;
	}
    } else { 
	if (!s->prepared) { 
	    cmd = cli_cmd_prepare_and_insert;
	    msg_size += 1 + s->stmt_len + s->n_columns + s->columns_len;
	}
    }
    for (cb = s->columns; cb != NULL; cb = cb->next) { 
	if (cb->get_fnc != NULL) { 
	    cb->arr_ptr = cb->get_fnc(cb->var_type, cb->var_ptr, &cb->arr_len);
	    int len = cb->arr_len;
	    if (cb->var_type >= cli_array_of_oid) { 
		len *= sizeof_type[cb->var_type - cli_array_of_oid];
	    }
	    msg_size += 4 + len;
	} else { 
	    if (cb->var_type == cli_asciiz) { 
		msg_size += 4 + strlen((char*)cb->var_ptr) + 1;
	    } else if (cb->var_type == cli_pasciiz) { 
		msg_size += 4 + strlen(*(char**)cb->var_ptr) + 1;
	    } else if (cb->var_type >= cli_array_of_oid) { 
		msg_size += 4 + 
		    *cb->var_len * sizeof_type[cb->var_type-cli_array_of_oid];
	    } else { 
		msg_size += sizeof_type[cb->var_type];
	    }
	}
    }
    dbSmallBuffer buf(msg_size);
    char* p = buf;
    cli_request* req = (cli_request*)p;
    req->length  = msg_size;
    req->cmd     = cmd;
    req->stmt_id = statement;
    req->pack();
    p += sizeof(cli_request);
    if (cmd == cli_cmd_prepare_and_insert) { 
	char* cmd = s->stmt;
	while ((*p++ = *cmd++) != '\0');
	*p++ = s->n_columns;
	for (cb = s->columns; cb != NULL; cb = cb->next) { 
	    char* src = cb->name;
	    *p++ = cb->var_type;
	    while ((*p++ = *src++) != '\0');
	}	
    }
    for (cb = s->columns; cb != NULL; cb = cb->next) { 
	int n;
	char* src;
	if (cb->get_fnc != NULL) { 
	    src = (char*)cb->arr_ptr;
	    n = cb->arr_len;
	} else { 
	    src = (char*)cb->var_ptr;
	    if (cb->var_type >= cli_array_of_oid) { 
		n = *cb->var_len;	
	    }
	}
	if (cb->var_type >= cli_array_of_oid) { 
	    p = pack4(p, n);
	    switch (sizeof_type[cb->var_type-cli_array_of_oid]) { 
	      case 2:
		while (--n >= 0) { 
		    p = pack2(p, src);
		    src += 2;
		}
		break;
	      case 4:
		while (--n >= 0) { 
		    p = pack4(p, src);
		    src += 4;
		}
		break;
	      case 8:
		while (--n >= 0) { 
		    p = pack8(p, src);
		    src += 8;
		}
		break;
	      default:
		memcpy(p, src, n);
		p += n;
	    }
	} else if (cb->var_type == cli_asciiz) { 		
	    p = pack4(p, strlen(src)+1);
	    while ((*p++ = *src++) != 0);
	} else if (cb->var_type == cli_pasciiz) { 
	    src = *(char**)src;
	    p = pack4(p, strlen(src)+1);
	    while ((*p++ = *src++) != 0);
	} else { 
	    switch (sizeof_type[cb->var_type]) { 
	      case 2:
		p = pack2(p, src);
		break;
	      case 4:
		p = pack4(p, src);
		break;
	      case 8:
		p = pack8(p, src);
		break;
	      default:
		*p++ = *src;
	    }
	}
    }
    assert(p - buf == msg_size);
    if (!s->session->sock->write(buf, msg_size)) { 
	return cli_network_error;
    }
    return cli_ok;
}
Beispiel #17
0
int cli_fetch(int statement, int for_update)
{
    parameter_binding* pb;
    column_binding*    cb;
    statement_desc* stmt = statements.get(statement);
    char *p, *s;

    if (stmt == NULL) { 
	return cli_bad_descriptor;
    }
    stmt->for_update = for_update;
    int msg_size = sizeof(cli_request) + 1;
    for (pb = stmt->params; pb != NULL; pb = pb->next) { 
	if (pb->var_ptr == NULL) { 
	    return cli_unbound_parameter;
	}
	if (pb->var_type == cli_asciiz) { 
	    msg_size += strlen((char*)pb->var_ptr) + 1;
	} else if (pb->var_type == cli_pasciiz) { 
	    msg_size += strlen(*(char**)pb->var_ptr) + 1;
	} else { 
	    msg_size += sizeof_type[pb->var_type];
	}
    }
    stmt->oid = 0;
    if (!stmt->prepared) { 
	msg_size += 4 + stmt->stmt_len + stmt->n_params;
	msg_size += stmt->columns_len + stmt->n_columns;
    }
    dbSmallBuffer buf(msg_size);
    p = buf;
    cli_request* req = (cli_request*)p;
    req->length  = msg_size;
    req->cmd     = stmt->prepared 
	? cli_cmd_execute : cli_cmd_prepare_and_execute;
    req->stmt_id = statement;
    req->pack();
    p += sizeof(cli_request);

    if (!stmt->prepared) { 
	*p++ = stmt->n_params;
	*p++ = stmt->n_columns;
	p = pack2(p, stmt->stmt_len + stmt->n_params);
	pb = stmt->params;
	char* end = p + stmt->stmt_len + stmt->n_params;
	char* src = stmt->stmt;
	while (p < end) { 
	    while ((*p++ = *src++) != '\0');
	    if (pb != NULL) { 
		*p++ = pb->var_type == cli_pasciiz ? cli_asciiz : pb->var_type;
		pb = pb->next;
	    }
	}
	for (cb = stmt->columns; cb != NULL; cb = cb->next) { 
	    *p++ = cb->var_type;
	    s = cb->name;
	    while ((*p++ = *s++) != '\0');
	}
    }	
    *p++ = for_update;
    for (pb = stmt->params; pb != NULL; pb = pb->next) { 
	switch (pb->var_type) { 
	  case cli_asciiz:
	    s = (char*)pb->var_ptr;
	    while ((*p++ = *s++) != '\0');
	    continue;
	  case cli_pasciiz:
	    s = *(char**)pb->var_ptr;
	    while ((*p++ = *s++) != '\0');
	    continue;
	  default:
	    switch (sizeof_type[pb->var_type]) { 
	      case 1:
		*p++ = *(char*)pb->var_ptr;
		continue;
	      case 2:
		p = pack2(p, *(int2*)pb->var_ptr);
		continue;
	      case 4:
		p = pack4(p, *(int4*)pb->var_ptr);
		continue;
	      case 8:
		p = pack8(p, *(int8*)pb->var_ptr);
		continue;
	    }
	}
    }
    assert(msg_size == p - buf);
    if (!stmt->session->sock->write(buf, msg_size)) { 
	return cli_network_error;
    }
    int4 response;
    if (!stmt->session->sock->read(&response, sizeof response)) { 
	return cli_network_error;
    }
    unpack4(response);
    if (response >= 0) { 
	stmt->prepared = true;
    }
    return response;
}
Beispiel #18
0
void lower_vcall(Vunit& unit, Inst& inst, Vlabel b, size_t i) {
  auto& blocks = unit.blocks;
  auto const& vinstr = blocks[b].code[i];

  auto const is_vcall = vinstr.op == Vinstr::vcall;
  auto const vcall = vinstr.vcall_;
  auto const vinvoke = vinstr.vinvoke_;

  // We lower vinvoke in two phases, and `inst' is overwritten after the first
  // phase.  We need to save any of its parameters that we care about in the
  // second phase ahead of time.
  auto const& vargs = unit.vcallArgs[inst.args];
  auto const dests = unit.tuples[inst.d];
  auto const destType = inst.destType;

  auto const scratch = unit.makeScratchBlock();
  SCOPE_EXIT { unit.freeScratchBlock(scratch); };
  Vout v(unit, scratch, vinstr.origin);

  int32_t const adjust = (vargs.stkArgs.size() & 0x1) ? sizeof(uintptr_t) : 0;
  if (adjust) v << lea{rsp()[-adjust], rsp()};

  // Push stack arguments, in reverse order.
  for (int i = vargs.stkArgs.size() - 1; i >= 0; --i) {
    v << push{vargs.stkArgs[i]};
  }

  // Get the arguments in the proper registers.
  RegSet argRegs;
  bool needsCopy = false;
  auto doArgs = [&] (const VregList& srcs, PhysReg (*r)(size_t)) {
    VregList argDests;
    for (size_t i = 0, n = srcs.size(); i < n; ++i) {
      auto const reg = r(i);
      argDests.push_back(reg);
      argRegs |= reg;
    }
    if (argDests.size()) {
      v << copyargs{v.makeTuple(srcs),
                    v.makeTuple(std::move(argDests))};
    }
  };
  switch (arch()) {
    case Arch::X64:
    case Arch::PPC64:
      doArgs(vargs.args, rarg);
      break;
    case Arch::ARM:
      if (vargs.indirect) {
        if (vargs.args.size() > 0) {
          // First arg is a pointer to storage for the return value.
          v << copy{vargs.args[0], rret_indirect()};
          VregList rem(vargs.args.begin() + 1, vargs.args.end());
          doArgs(rem, rarg);
          needsCopy = true;
        }
      } else {
        doArgs(vargs.args, rarg);
      }
  }
  doArgs(vargs.simdArgs, rarg_simd);

  // Emit the appropriate call instruction sequence.
  emitCall(v, inst.call, argRegs);

  // Handle fixup and unwind information.
  if (inst.fixup.isValid()) {
    v << syncpoint{inst.fixup};
  }

  if (!is_vcall) {
    auto& targets = vinvoke.targets;
    v << unwind{{targets[0], targets[1]}};

    // Insert an lea fixup for any stack args at the beginning of the catch
    // block.
    if (auto rspOffset = ((vargs.stkArgs.size() + 1) & ~1) *
                         sizeof(uintptr_t)) {
      auto& taken = unit.blocks[targets[1]].code;
      assertx(taken.front().op == Vinstr::landingpad ||
              taken.front().op == Vinstr::jmp);

      Vinstr vi { lea{rsp()[rspOffset], rsp()} };
      vi.origin = taken.front().origin;

      if (taken.front().op == Vinstr::jmp) {
        taken.insert(taken.begin(), vi);
      } else {
        taken.insert(taken.begin() + 1, vi);
      }
    }

    // Write out the code so far to the end of b.  Remaining code will be
    // emitted to the next block.
    vector_splice(blocks[b].code, i, 1, blocks[scratch].code);
  } else if (vcall.nothrow) {
    v << nothrow{};
  }

  // Copy back the indirect result pointer into the return register.
  if (needsCopy) {
    v << copy{rret_indirect(), rret(0)};
  }

  // For vinvoke, `inst' is no longer valid after this point.

  // Copy the call result to the destination register(s).
  switch (destType) {
    case DestType::TV:
      static_assert(offsetof(TypedValue, m_data) == 0, "");
      static_assert(offsetof(TypedValue, m_type) == 8, "");

      if (dests.size() == 2) {
        v << copy2{rret(0), rret(1), dests[0], dests[1]};
      } else {
        // We have cases where we statically know the type but need the value
        // from native call.  Even if the type does not really need a register
        // (e.g., InitNull), a Vreg is still allocated in assignRegs(), so the
        // following assertion holds.
        assertx(dests.size() == 1);
        v << copy{rret(0), dests[0]};
      }
      break;

    case DestType::SIMD:
      static_assert(offsetof(TypedValue, m_data) == 0, "");
      static_assert(offsetof(TypedValue, m_type) == 8, "");
      assertx(dests.size() == 1);

      pack2(v, rret(0), rret(1), dests[0]);
      break;

    case DestType::SSA:
    case DestType::Byte:
      assertx(dests.size() == 1);
      assertx(dests[0].isValid());

      // Copy the single-register result to dests[0].
      v << copy{rret(0), dests[0]};
      break;

    case DestType::Dbl:
      // Copy the single-register result to dests[0].
      assertx(dests.size() == 1);
      assertx(dests[0].isValid());
      v << copy{rret_simd(0), dests[0]};
      break;

    case DestType::None:
      assertx(dests.empty());
      break;
  }

  if (vargs.stkArgs.size() > 0) {
    auto const delta = safe_cast<int32_t>(
      vargs.stkArgs.size() * sizeof(uintptr_t) + adjust
    );
    v << lea{rsp()[delta], rsp()};
  }

  // Insert new instructions to the appropriate block.
  if (is_vcall) {
    vector_splice(blocks[b].code, i, 1, blocks[scratch].code);
  } else {
    vector_splice(blocks[vinvoke.targets[0]].code, 0, 0,
                  blocks[scratch].code);
  }
}
Beispiel #19
0
void lower_vcall(Vunit& unit, Inst& inst, Vlabel b, size_t i) {
  auto& blocks = unit.blocks;
  auto const& vinstr = blocks[b].code[i];

  auto const is_vcall = vinstr.op == Vinstr::vcall;
  auto const vcall = vinstr.vcall_;
  auto const vinvoke = vinstr.vinvoke_;

  // We lower vinvoke in two phases, and `inst' is overwritten after the first
  // phase.  We need to save any of its parameters that we care about in the
  // second phase ahead of time.
  auto const& vargs = unit.vcallArgs[inst.args];
  auto const dests = unit.tuples[inst.d];
  auto const destType = inst.destType;

  auto const scratch = unit.makeScratchBlock();
  SCOPE_EXIT { unit.freeScratchBlock(scratch); };
  Vout v(unit, scratch, vinstr.irctx());

  // Push stack arguments, in reverse order. Push in pairs without padding
  // except for the last argument (pushed first) which should be padded if
  // there are an odd number of arguments.
  auto numArgs = vargs.stkArgs.size();
  int32_t const adjust = (numArgs & 0x1) ? sizeof(uintptr_t) : 0;
  if (adjust) {
    // Using InvalidReg below fails SSA checks and simplify pass, so just
    // push the arg twice. It's on the same cacheline and will actually
    // perform faster than an explicit lea.
    v << pushp{vargs.stkArgs[numArgs - 1], vargs.stkArgs[numArgs - 1]};
    --numArgs;
  }
  for (auto i2 = numArgs; i2 >= 2; i2 -= 2) {
    v << pushp{vargs.stkArgs[i2 - 1], vargs.stkArgs[i2 - 2]};
  }

  // Get the arguments in the proper registers.
  RegSet argRegs;
  auto doArgs = [&] (const VregList& srcs, PhysReg (*r)(size_t)) {
    VregList argDests;
    for (size_t i2 = 0, n = srcs.size(); i2 < n; ++i2) {
      auto const reg = r(i2);
      argDests.push_back(reg);
      argRegs |= reg;
    }
    if (argDests.size()) {
      v << copyargs{v.makeTuple(srcs),
                    v.makeTuple(std::move(argDests))};
    }
  };
  doArgs(vargs.indRetArgs, rarg_ind_ret);
  doArgs(vargs.args, rarg);
  doArgs(vargs.simdArgs, rarg_simd);

  // Emit the appropriate call instruction sequence.
  emitCall(v, inst.call, argRegs);

  // Handle fixup and unwind information.
  if (inst.fixup.isValid()) {
    v << syncpoint{inst.fixup};
  }

  if (!is_vcall) {
    auto& targets = vinvoke.targets;
    v << unwind{{targets[0], targets[1]}};

    // Insert an lea fixup for any stack args at the beginning of the catch
    // block.
    if (auto rspOffset = ((vargs.stkArgs.size() + 1) & ~1) *
                         sizeof(uintptr_t)) {
      auto& taken = unit.blocks[targets[1]].code;
      assertx(taken.front().op == Vinstr::landingpad ||
              taken.front().op == Vinstr::jmp);

      Vinstr vi { lea{rsp()[rspOffset], rsp()}, taken.front().irctx() };

      if (taken.front().op == Vinstr::jmp) {
        taken.insert(taken.begin(), vi);
      } else {
        taken.insert(taken.begin() + 1, vi);
      }
    }

    // Write out the code so far to the end of b.  Remaining code will be
    // emitted to the next block.
    vector_splice(blocks[b].code, i, 1, blocks[scratch].code);
  } else if (vcall.nothrow) {
    v << nothrow{};
  }
  // For vinvoke, `inst' is no longer valid after this point.

  // Copy the call result to the destination register(s).
  switch (destType) {
    case DestType::TV:
      static_assert(offsetof(TypedValue, m_data) == 0, "");
      static_assert(offsetof(TypedValue, m_type) == 8, "");

      if (dests.size() == 2) {
        switch (arch()) {
          case Arch::X64: // fall through
          case Arch::PPC64:
            v << copy2{rret(0), rret(1), dests[0], dests[1]};
            break;
          case Arch::ARM:
            // For ARM64 we need to clear the bits 8..31 from the type value.
            // That allows us to use the resulting register values in
            // type comparisons without the need for truncation there.
            // We must not touch bits 63..32 as they contain the AUX data.
            v << copy{rret(0), dests[0]};
            v << andq{v.cns(0xffffffff000000ff),
                      rret(1), dests[1], v.makeReg()};
            break;
        }
      } else {
        // We have cases where we statically know the type but need the value
        // from native call.  Even if the type does not really need a register
        // (e.g., InitNull), a Vreg is still allocated in assignRegs(), so the
        // following assertion holds.
        assertx(dests.size() == 1);
        v << copy{rret(0), dests[0]};
      }
      break;

    case DestType::SIMD:
      static_assert(offsetof(TypedValue, m_data) == 0, "");
      static_assert(offsetof(TypedValue, m_type) == 8, "");
      assertx(dests.size() == 1);

      pack2(v, rret(0), rret(1), dests[0]);
      break;

    case DestType::SSA:
    case DestType::Byte:
      assertx(dests.size() == 1);
      assertx(dests[0].isValid());

      // Copy the single-register result to dests[0].
      v << copy{rret(0), dests[0]};
      break;

    case DestType::SSAPair:
      assertx(dests.size() == 2);
      assertx(dests[0].isValid());
      assertx(dests[1].isValid());

      // Copy the result pair to dests.
      v << copy2{rret(0), rret(1), dests[0], dests[1]};
      break;

    case DestType::Dbl:
      // Copy the single-register result to dests[0].
      assertx(dests.size() == 1);
      assertx(dests[0].isValid());
      v << copy{rret_simd(0), dests[0]};
      break;

    case DestType::Indirect:
      // Already asserted above
      break;

    case DestType::None:
      assertx(dests.empty());
      break;
  }

  if (vargs.stkArgs.size() > 0) {
    auto const delta = safe_cast<int32_t>(
      vargs.stkArgs.size() * sizeof(uintptr_t) + adjust
    );
    v << lea{rsp()[delta], rsp()};
  }

  // Insert new instructions to the appropriate block.
  if (is_vcall) {
    vector_splice(blocks[b].code, i, 1, blocks[scratch].code);
  } else {
    vector_splice(blocks[vinvoke.targets[0]].code, 0, 0,
                  blocks[scratch].code);
  }
}
Beispiel #20
0
static int cli_send_columns_fdb(int statement, int cmd)
{
    statement_desc* s = statements.get(statement);
    column_binding* cb;
    if (s == NULL) { 
        return cli_bad_descriptor;
    }
    long msg_size = sizeof(cli_request);
    if (cmd == cli_cmd_update) { 
        if (!s->prepared) { 
            return cli_not_fetched;
        }
        if (s->oid == 0) { 
            return cli_not_found;
        }
        if (s->updated) {
            return cli_already_updated;
        } 
        if (!s->for_update) { 
            return cli_not_update_mode;
        }
    } else { 
        if (!s->prepared) { 
            cmd = cli_cmd_prepare_and_insert;
            msg_size += 1 + s->stmt_len + s->n_columns + s->columns_len;
        }
    }
    s->autoincrement = false;
    for (cb = s->columns; cb != NULL; cb = cb->next) { 
        if (cb->get_fnc != NULL) { 
            cb->arr_ptr = cb->get_fnc(cb->var_type, cb->var_ptr, &cb->arr_len, 
                                      cb->name, statement, cb->user_data);
            int len = cb->arr_len;
            msg_size += 4;
            if (cb->var_type == cli_array_of_string) {
                char** p = (char**)cb->arr_ptr;
                while (--len >= 0) { 
                    msg_size += strlen(*p++) + 1;
                }
            } else if (cb->var_type == cli_array_of_wstring) {
                wchar_t** p = (wchar_t**)cb->arr_ptr;
                while (--len >= 0) { 
                    msg_size += (wcslen(*p++) + 1)*sizeof(wchar_t);
                }
            } else if (cb->var_type == cli_wstring || cb->var_type == cli_pwstring) {
                msg_size += len * sizeof(wchar_t);
            } else if (cb->var_type >= cli_array_of_oid) {
                msg_size += len * sizeof_type[cb->var_type - cli_array_of_oid];
            } else { 
                msg_size += len;
            }
        } else { 
            switch (cb->var_type) { 
              case cli_autoincrement:
                s->autoincrement = true;
                break;
              case cli_asciiz:
                msg_size += 4 + (strlen((char*)cb->var_ptr) + 1);
                break;
              case cli_pasciiz:
                msg_size += 4 + (strlen(*(char**)cb->var_ptr) + 1);
                break;
              case cli_wstring:
                msg_size += 4 + (wcslen((wchar_t*)cb->var_ptr) + 1)*sizeof(wchar_t);
                break;
              case cli_pwstring:
                msg_size += 4 + (wcslen(*(wchar_t**)cb->var_ptr) + 1)*sizeof(wchar_t);
                break;
              case cli_array_of_string:
              { 
                char** p = (char**)cb->var_ptr;
                int len;
                msg_size += 4;
                for (len = *cb->var_len; --len >= 0;) { 
                    msg_size += (strlen(*p++) + 1);
                }
                break;
              }
              case cli_array_of_wstring:
              { 
                wchar_t** p = (wchar_t**)cb->var_ptr;
                int len;
                msg_size += 4;
                for (len = *cb->var_len; --len >= 0;) { 
                    msg_size += (wcslen(*p++) + 1)*sizeof(wchar_t);
                }
                break;
              }
              default:
                if (cb->var_type >= cli_array_of_oid && cb->var_type < cli_array_of_string) {
                    msg_size += 4 + *cb->var_len * sizeof_type[cb->var_type-cli_array_of_oid];
                } else { 
                    msg_size += sizeof_type[cb->var_type];
                }
            }
        }
    }
    dbSmallBuffer buf(msg_size);
    char* p = buf;
    cli_request* req = (cli_request*)p;
    req->length  = msg_size;
    req->cmd     = cmd;
    req->stmt_id = statement;
    req->pack();
    p += sizeof(cli_request);
    if (cmd == cli_cmd_prepare_and_insert) { 
        char* cmd = s->stmt;
        while ((*p++ = *cmd++) != '\0');
        *p++ = s->n_columns;
        for (cb = s->columns; cb != NULL; cb = cb->next) { 
            char* src = cb->name;
            *p++ = cb->var_type;
            while ((*p++ = *src++) != '\0');
        }       
    }
    for (cb = s->columns; cb != NULL; cb = cb->next) { 
        int n = 0;
        char* src;
        if (cb->get_fnc != NULL) { 
            src = (char*)cb->arr_ptr;
            n = cb->arr_len;
        } else { 
            src = (char*)cb->var_ptr;
            if (cb->var_type >= cli_array_of_oid && (cb->var_type <= cli_array_of_string || cb->var_type == cli_array_of_wstring)) { 
                n = *cb->var_len;       
            }
        }
        if (cb->var_type >= cli_array_of_oid && (cb->var_type <= cli_array_of_string || cb->var_type == cli_array_of_wstring)) { 
            p = pack4(p, n);
            if (cb->var_type == cli_array_of_string) {
                while (--n >= 0) {
                    strcpy(p, *(char**)src);
                    p += strlen(p) + 1;
                    src += sizeof(char*);
                }
            } else if (cb->var_type == cli_array_of_wstring) {
                while (--n >= 0) {
                    wcscpy((wchar_t*)p, *(wchar_t**)src);
                    p += (wcslen((wchar_t*)p) + 1)*sizeof(wchar_t);
                    src += sizeof(wchar_t*);
                }
            } else {
                switch (sizeof_type[cb->var_type-cli_array_of_oid]) { 
                  case 2:
                    while (--n >= 0) { 
                        p = pack2(p, src);
                        src += 2;
                    }
                    break;
                  case 4:
                    while (--n >= 0) { 
                        p = pack4(p, src);
                        src += 4;
                    }
                    break;
                  case 8:
                    while (--n >= 0) { 
                        p = pack8(p, src);
                        src += 8;
                    }
                    break;
                  default:
                    memcpy(p, src, n);
                    p += n;
                }
            }
        } else if (cb->var_type == cli_asciiz) {                
            p = pack4(p, strlen(src)+1);
            while ((*p++ = *src++) != 0);
        } else if (cb->var_type == cli_pasciiz) { 
            src = *(char**)src;
            p = pack4(p, strlen(src)+1);
            while ((*p++ = *src++) != 0);
        } else if (cb->var_type == cli_wstring) {                
            wchar_t* body = (wchar_t*)src;
            p = pack4(p, wcslen(body)+1);
            wchar_t* dst = (wchar_t*)p;
            while ((*dst++ = *body++) != 0);
            p = (char*)dst;
        } else if (cb->var_type == cli_pwstring) {                
            wchar_t* body = *(wchar_t**)src;
            p = pack4(p, wcslen(body)+1);
            wchar_t* dst = (wchar_t*)p;
            while ((*dst++ = *body++) != 0);
            p = (char*)dst;
        } else if (cb->var_type == cli_rectangle) {
            p = pack_rectangle(p, (cli_rectangle_t*)src);
        } else if (cb->var_type != cli_autoincrement) { 
            switch (sizeof_type[cb->var_type]) { 
              case 2:
                p = pack2(p, src);
                break;
              case 4:
                p = pack4(p, src);
                break;
              case 8:
                p = pack8(p, src);
                break;
              default:
                *p++ = *src;
            }
        }
    }
    assert(p - buf.base() == msg_size);
    if (!s->session->sock->write(buf, msg_size)) { 
        return cli_network_error;
    }
    return cli_ok;
}