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; }
/*--------------------------------------------------------------------------*/ 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; }
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; }
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(); }
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]; }
/* 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; }
/* 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; }
/*--------------------------------------------------------------------------*/ 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; }
/* 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; }
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(); }
/*--------------------------------------------------------------------------*/ 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; }
/*--------------------------------------------------------------------------*/ 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)}; } }
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; }
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; }
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); } }
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); } }
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; }