Exemple #1
0
int examine_inside_scaling_none(void)
{
    int i;
    double inside;

    inside_failure = 0.0;

    for (i = 0; i < num_roots; i++) {
        inside = expl_graph[roots[i]->id]->inside;
        if (i == failure_root_index) {
            inside_failure = inside;
            if (!(1.0 - inside_failure > 0.0)) {
                emit_error("Probability of failure being unity");
                RET_ERR(err_invalid_numeric_value);
            }
        }
        else {
            if (!(inside > 0.0)) {
                emit_error("Probability of an observed goal being zero");
                RET_ERR(err_invalid_numeric_value);
            }
        }
    }

    return BP_TRUE;
}
Exemple #2
0
int examine_inside_scaling_log_exp(void)
{
    int i;
    double inside;

    /* [23 Aug 2007, by yuizumi]
     * By the code below, inside_failure can take only a non-zero value
     * when `failure' is observed.  We can therefore safely use zero as
     * an indicator of failure being not observed.  Zero is chosen just
     * for convenience in implementation of the parallel version.
     */
    inside_failure = 0.0;

    for (i = 0; i < num_roots; i++) {
        inside = expl_graph[roots[i]->id]->inside;
        if (i == failure_root_index) {
            inside_failure = inside; /* log-scale */
            if (!(inside_failure < 0.0)) {
                emit_error("Probability of failure being unity");
                RET_ERR(err_invalid_numeric_value);
            }
        }
        else {
            if (!isfinite(inside)) {
                emit_error("Probability of an observed goal being zero");
                RET_ERR(err_invalid_numeric_value);
            }
        }
    }

    return BP_TRUE;
}
Exemple #3
0
/* We check if all smoothing constants are positive (MAP),
 * or all smoothing constants are zero.  If some are positive,
 * but the others are zero, die immediately.  We also check
 * if there exist parameters fixed at zero in MAP estimation.
 */
int check_smooth(int *smooth)
{
    /*
      q = +4 : found non-zero smoothing constants
          +2 : found zero-valued smoothing constants
          +1 : found parameters fixed to zero
    */
    int i, q = 0;
    SW_INS_PTR sw_ins_ptr;

    for (i = 0; i < occ_switch_tab_size; i++) {
        sw_ins_ptr = occ_switches[i];
        while (sw_ins_ptr != NULL) {
            if (sw_ins_ptr->smooth_prolog < 0) {
                emit_error("negative delta values in MAP estimation");
                RET_ERR(err_invalid_numeric_value);
            }

            q |= (sw_ins_ptr->smooth_prolog < TINY_PROB) ? 2 : 4;
            q |= (sw_ins_ptr->fixed && sw_ins_ptr->inside < TINY_PROB) ? 1 : 0;

            sw_ins_ptr = sw_ins_ptr->next;
        }
    }

    switch (q) {
    case 0: /* p.counts = (none), w/o  0-valued params */
    case 1: /* p.counts = (none), with 0-valued params */
        emit_internal_error("unexpected case in check_smooth()");
        RET_ERR(ierr_unmatched_branches);
        break;
    case 2: /* p.counts = 0 only, w/o  0-valued params */
    case 3: /* p.counts = 0 only, with 0-valued params */
        *smooth = 0;
        break;
    case 4: /* p.counts = + only, w/o  0-valued params */
        *smooth = 1;
        break;
    case 5: /* p.counts = + only, with 0-valued params */
        emit_error("parameters fixed to zero in MAP estimation");
        RET_ERR(err_invalid_numeric_value);
        break;
    case 6: /* p.counts = (both), w/o  0-valued params */
    case 7: /* p.counts = (both), with 0-valued params */
        emit_error("mixture of zero and non-zero pseudo counts");
        RET_ERR(err_invalid_numeric_value);
    }

    transfer_hyperparams_prolog();

    return BP_TRUE;
}
int update_params(void)
{
    int i;
    SW_INS_PTR ptr;
    double sum;

    for (i = 0; i < occ_switch_tab_size; i++) {
        ptr = occ_switches[i];
        sum = 0.0;
        while (ptr != NULL) {
            sum += ptr->total_expect;
            ptr = ptr->next;
        }
        if (sum != 0.0) {
            ptr = occ_switches[i];
            if (ptr->fixed > 0) continue;
            while (ptr != NULL) {
                if (ptr->fixed == 0) ptr->inside = ptr->total_expect / sum;
                if (log_scale && ptr->inside < TINY_PROB) {
                    emit_error("Parameter being zero (-inf in log scale) -- %s",
                               prism_sw_ins_string(ptr->id));
                    RET_ERR(err_underflow);
                }
                ptr = ptr->next;
            }
        }
    }

    return BP_TRUE;
}
Exemple #5
0
/// Performs the call to Python
bool PythonScript::executeString()
{
    emit started(MSG_STARTED);
    bool success(false);
    GlobalInterpreterLock gil;

    PyObject * compiledCode = compileToByteCode(false);
    PyObject *result(NULL);
    if(compiledCode)
    {
        result = executeCompiledCode(compiledCode);
    }
    // If an error has occurred we need to construct the error message
    // before any other python code is run
    QString msg;
    if(!result)
    {
        emit_error();
    }
    else
    {
        emit finished(MSG_FINISHED);
        success = true;
    }
    if(isInteractive())
    {
        generateAutoCompleteList();
    }

    Py_XDECREF(compiledCode);
    Py_XDECREF(result);

    return success;
}
/// Performs the call to Python
bool PythonScript::executeString() {
  emit started(MSG_STARTED);
  bool success(false);
  ScopedPythonGIL lock;

  PyObject *compiledCode = compileToByteCode(false);
  PyObject *result(nullptr);
  if (compiledCode) {
    result = executeCompiledCode(compiledCode);
  }
  // If an error has occurred we need to construct the error message
  // before any other python code is run
  if (!result) {
    emit_error();
    // If a script was aborted we both raise a KeyboardInterrupt and
    // call Algorithm::cancel to make sure we capture it. The doubling
    // can leave an interrupt in the pipeline so we clear it was we've
    // got the error info out
    m_interp->raiseAsyncException(m_threadID, nullptr);
  } else {
    emit finished(MSG_FINISHED);
    success = true;
    if (isInteractive()) {
      generateAutoCompleteList();
    }
  }

  Py_XDECREF(compiledCode);
  Py_XDECREF(result);

  return success;
}
bool PythonScript::compile(bool for_eval)
{
  if(Context->isA("Table")) {
    PyDict_SetItemString(localDict,"__builtins__",PyDict_GetItemString(env()->globalDict(),"__builtins__"));
    PyObject *ret = PyRun_String("def col(c,*arg):\n\ttry: return self.cell(c,arg[0])\n\texcept(IndexError): return self.cell(c,i)\n",Py_file_input,localDict,localDict);
    if (ret)
      Py_DECREF(ret);
    else
      PyErr_Print();
  } else if(Context->isA("Matrix")) {
    PyDict_SetItemString(localDict,"__builtins__",PyDict_GetItemString(env()->globalDict(),"__builtins__"));
    PyObject *ret = PyRun_String("def cell(*arg):\n\ttry: return self.cell(arg[0],arg[1])\n\texcept(IndexError): return self.cell(i,j)\n",Py_file_input,localDict,localDict);
    if (ret)
      Py_DECREF(ret);
    else
      PyErr_Print();
  }
  bool success=false;
  Py_XDECREF(PyCode);
  PyCode = Py_CompileString(Code.ascii(),Name,Py_eval_input);
  if (PyCode) { // code is a single expression
    success = true;
  } else if (for_eval) { // code contains statements
    PyErr_Clear();
    PyObject *key, *value;
    int i=0;
    QString signature = "";
    while(PyDict_Next(localDict, &i, &key, &value))
      signature.append(PyString_AsString(key)).append(",");
    signature.truncate(signature.length()-1);
    QString fdef = "def __doit__("+signature+"):\n";
    fdef.append(Code);
    fdef.replace('\n',"\n\t");
    PyCode = Py_CompileString(fdef,Name,Py_file_input);
    if (PyCode)
    {
      PyObject *tmp = PyDict_New();
      Py_XDECREF(PyEval_EvalCode((PyCodeObject*)PyCode, env()->globalDict(), tmp));
      Py_DECREF(PyCode);
      PyCode = PyDict_GetItemString(tmp,"__doit__");
      Py_XINCREF(PyCode);
      Py_DECREF(tmp);
    }
    success = PyCode != NULL;
  } else {
    PyErr_Clear();
    PyCode = Py_CompileString(Code.ascii(),Name,Py_file_input);
    success = PyCode != NULL;
  }
  if (!success)
  {
    compiled = compileErr;
    emit_error(env()->errorMsg(), 0);
  } else
    compiled = isCompiled;
  return success;
}
Exemple #8
0
static void error_unless(Value *cond, const std::string &msg, jl_codectx_t *ctx)
{
    BasicBlock *failBB = BasicBlock::Create(getGlobalContext(),"fail",ctx->f);
    BasicBlock *passBB = BasicBlock::Create(getGlobalContext(),"pass");
    builder.CreateCondBr(cond, passBB, failBB);
    builder.SetInsertPoint(failBB);
    emit_error(msg, ctx);
    builder.CreateBr(passBB);
    ctx->f->getBasicBlockList().push_back(passBB);
    builder.SetInsertPoint(passBB);
}
Exemple #9
0
static Value *emit_cglobal(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
{
    JL_NARGS(cglobal, 1, 2);
    jl_value_t *rt=NULL;
    Value *res;
    JL_GC_PUSH1(&rt);

    if (nargs == 2) {
        rt = jl_interpret_toplevel_expr_in(ctx->module, args[2],
                                           &jl_tupleref(ctx->sp,0),
                                           jl_tuple_len(ctx->sp)/2);
        JL_TYPECHK(cglobal, type, rt);
        rt = (jl_value_t*)jl_apply_type((jl_value_t*)jl_pointer_type, jl_tuple1(rt));
    }
    else {
        rt = (jl_value_t*)jl_voidpointer_type;
    }
    Type *lrt = julia_type_to_llvm(rt);
    if (lrt == NULL) lrt = T_pint8;

    native_sym_arg_t sym = interpret_symbol_arg(args[1], ctx, "cglobal");

    if (sym.jl_ptr != NULL) {
        res = builder.CreateIntToPtr(sym.jl_ptr, lrt);
    }
    else if (sym.fptr != NULL) {
        res = literal_pointer_val(sym.fptr, lrt);
    }
    else {
        void *symaddr;
        if (sym.f_lib != NULL)
            symaddr = add_library_sym(sym.f_name, sym.f_lib);
        else
            symaddr = sys::DynamicLibrary::SearchForAddressOfSymbol(sym.f_name);
        if (symaddr == NULL) {
            std::stringstream msg;
            msg << "cglobal: could not find symbol ";
            msg << sym.f_name;
            if (sym.f_lib != NULL) {
                msg << " in library ";
                msg << sym.f_lib;
            }
            emit_error(msg.str(), ctx);
            res = literal_pointer_val(NULL, lrt);
        }
        else {
            res = jl_Module->getOrInsertGlobal(sym.f_name,
                                               lrt->getContainedType(0));
        }
    }

    JL_GC_POP();
    return mark_julia_type(res, rt);
}
QVariant MuParserScript::eval() {
  if (compiled != Script::isCompiled && !compile()) return QVariant();
  try {
    // see documentation of s_currentInstance for explanation
    s_currentInstance = this;
    return m_parser.Eval();
  } catch (EmptySourceError *e) {
    // formula tried to access a table cell marked as invalid
    return "";
  } catch (mu::ParserError &e) {
    emit_error(QString::fromLocal8Bit(e.GetMsg().c_str()), 0);
    return QVariant();
  }
}
/**
 * \brief Pre-process #Code and hand it to #m_parser.
 *
 * This implements some functionality not directly supported by muParser, like overloaded functions
 * and multi-line expressions. See class documentation of MuParserScript for details.
 */
bool MuParserScript::compile(bool asFunction) {
	Q_UNUSED(asFunction); // only needed for Python

	QString intermediate = Code.trimmed(); // pre-processed version of #Code

	// remove comments
	bool inString = false;
	int commentStart = -1;
	for (int i=0; i<intermediate.size(); i++)
		switch (intermediate.at(i).toAscii()) {
			case '"':
				if (commentStart < 0) inString = !inString;
				break;
			case '#':
				if (!inString) commentStart = i;
				break;
			case '\n':
				if (commentStart >= 0) {
					intermediate.remove(commentStart, i-commentStart);
					i = commentStart;
					commentStart = -1;
				}
				break;
		}
	if (commentStart >= 0)
		intermediate.remove(commentStart, intermediate.size()-commentStart);

	// simplify statement separators
	intermediate.replace(QRegExp("([;\\n]\\s*)+"),"; ");

	// recursively translate legacy functions col(), tablecol() and cell()
	if (Context && Context->inherits("Table"))
		if (!translateLegacyFunctions(intermediate))
			return false;

	try {
		m_parser.SetExpr(qPrintable(intermediate));
	} catch (mu::ParserError &e) {
		emit_error(QString::fromLocal8Bit(e.GetMsg().c_str()), 0);
		return false;
	}

	compiled = isCompiled;
	return true;
}
/**
 * \brief Set a (local, double-valued) variable.
 *
 * Other kinds of variables are not supported (integers are converted to
 * doubles).
 *
 * \sa m_variables
 */
bool MuParserScript::setDouble(double value, const char *name) {
  QByteArray baName(name);
  QMap<QByteArray, double>::iterator entry = m_variables.find(baName);
  if (entry == m_variables.end()) {
    // variable is not known yet
    entry = m_variables.insert(baName, value);
    try {
      m_parser.DefineVar(name, entry.operator->());
    } catch (mu::ParserError &e) {
      m_variables.erase(entry);
      emit_error(QString::fromLocal8Bit(e.GetMsg().c_str()), 0);
      return false;
    }
  } else
    // variable is known and only needs to be updated
    *entry = value;
  return true;
}
Exemple #13
0
/* compute node->inside (CRF inside) */
int compute_feature_scaling_none(void) {
	int i,k;
	double sum, this_path_inside, this_sws_inside;
	EG_NODE_PTR eg_ptr;
	EG_PATH_PTR path_ptr;

	for (i = 0; i < sorted_egraph_size; i++) {
		eg_ptr = sorted_expl_graph[i];
		sum = 0.0;
		path_ptr = eg_ptr->path_ptr;
		if (path_ptr == NULL) {
			sum = 1.0; /* path_ptr should not be NULL; but it happens */
		} else {
			while (path_ptr != NULL) {
				this_path_inside = 1.0;
				for (k = 0; k < path_ptr->children_len; k++) {
					this_path_inside *= path_ptr->children[k]->inside;
				}
				this_sws_inside = 0.0;
				for (k = 0; k < path_ptr->sws_len; k++) {
					this_sws_inside += (path_ptr->sws[k]->inside * path_ptr->sws[k]->inside_h);
				}
				this_path_inside *= exp(this_sws_inside);
				path_ptr->inside = this_path_inside;  //path_ptr->inside = exp(?)
				sum += this_path_inside;
				path_ptr = path_ptr->next;
			}
		}
		if (!isfinite(sum)) {
			emit_error("overflow CRF-inside");
			RET_ERR(err_overflow);
		}
		eg_ptr->inside = sum;  //eg_ptr->inside = exp(?)
	}

	return BP_TRUE;
}
Exemple #14
0
static int compute_gradient_scaling_log_exp(void) {
	int i,k;
	EG_PATH_PTR path_ptr;
	EG_NODE_PTR eg_ptr,node_ptr;
	SW_INS_PTR sw_ptr;
	double q,r;

	for (i = 0; i < sw_ins_tab_size; i++) {
		switch_instances[i]->total_expect = 0.0;
		switch_instances[i]->has_first_expectation = 0;
		switch_instances[i]->first_expectation = 0.0;
	}

	for (i = 0; i < sorted_egraph_size; i++) {
		sorted_expl_graph[i]->outside = 0.0;
		sorted_expl_graph[i]->has_first_outside = 0;
		sorted_expl_graph[i]->first_outside = 0.0;
	}

	for (i = 0; i < num_roots; i++) {
		if (roots[i]->pid == -1) {
			eg_ptr = expl_graph[roots[i]->id];
			if (i == failure_root_index) {
				eg_ptr->first_outside =
				    log(num_goals / (1.0 - exp(inside_failure)));
			} else {
				eg_ptr->first_outside =
				    log((double)(roots[i]->sgd_count)) - eg_ptr->inside;
			}
			eg_ptr->has_first_outside = 1;
			eg_ptr->outside = 1.0;
		}
	}

	/* sorted_expl_graph[to] must be a root node */
	for (i = sorted_egraph_size - 1; i >= 0; i--) {
		eg_ptr = sorted_expl_graph[i];

		if (eg_ptr->visited == 0) continue;

		/* First accumulate log-scale outside probabilities: */
		if (!eg_ptr->has_first_outside) {
			emit_internal_error("unexpected has_first_outside[%s]",
			                    prism_goal_string(eg_ptr->id));
			RET_INTERNAL_ERR;
		} else if (!(eg_ptr->outside > 0.0)) {
			emit_internal_error("unexpected outside[%s]",
			                    prism_goal_string(eg_ptr->id));
			RET_INTERNAL_ERR;
		} else {
			eg_ptr->outside = eg_ptr->first_outside + log(eg_ptr->outside);
		}

		path_ptr = sorted_expl_graph[i]->path_ptr;
		while (path_ptr != NULL) {
			q = sorted_expl_graph[i]->outside + path_ptr->inside;
			for (k = 0; k < path_ptr->children_len; k++) {
				node_ptr = path_ptr->children[k];
				r = q - node_ptr->inside;
				if (!node_ptr->has_first_outside) {
					node_ptr->first_outside = r;
					node_ptr->outside += 1.0;
					node_ptr->has_first_outside = 1;
				} else if (r - node_ptr->first_outside >= log(HUGE_PROB)) {
					node_ptr->outside *= exp(node_ptr->first_outside - r);
					node_ptr->first_outside = r;
					node_ptr->outside += 1.0;
				} else {
					node_ptr->outside += exp(r - node_ptr->first_outside);
				}
			}
			for (k = 0; k < path_ptr->sws_len; k++) {
				sw_ptr = path_ptr->sws[k];
				if (!sw_ptr->has_first_expectation) {
					sw_ptr->first_expectation = q;
					sw_ptr->total_expect += 1.0;
					sw_ptr->has_first_expectation = 1;
				} else if (q - sw_ptr->first_expectation >= log(HUGE_PROB)) {
					sw_ptr->total_expect *= exp(sw_ptr->first_expectation - q);
					sw_ptr->first_expectation = q;
					sw_ptr->total_expect += 1.0;
				} else {
					sw_ptr->total_expect += exp(q - sw_ptr->first_expectation);
				}
			}
			path_ptr = path_ptr->next;
		}
	}

	/* unscale total_expect */
	for (i = 0; i < sw_ins_tab_size; i++) {
		sw_ptr = switch_instances[i];
		if (!sw_ptr->has_first_expectation) continue;
		if (!(sw_ptr->total_expect > 0.0)) {
			emit_error("unexpected expectation for %s",prism_sw_ins_string(i));
			RET_ERR(err_invalid_numeric_value);
		}
		sw_ptr->total_expect =
		    exp(sw_ptr->first_expectation + log(sw_ptr->total_expect));
	}

	for (i=0; i<occ_switch_tab_size; i++) {
		sw_ptr = occ_switches[i];
		while (sw_ptr!=NULL) {
			sw_ptr->gradient = (sw_ptr->count - sw_ptr->total_expect) * sw_ptr->inside_h;
			if (crf_penalty != 0.0) {
				sw_ptr->gradient -= sw_ptr->inside * crf_penalty;
			}
			sw_ptr = sw_ptr->next;
		}
	}

	return BP_TRUE;
}
Socks5::Socks5(Settings s, Logger *lp, Poller *poller)
    : Emitter(lp), settings(s),
      conn(settings["family"].c_str(), settings["socks5_address"].c_str(),
           settings["socks5_port"].c_str(), lp, poller),
      proxy_address(settings["socks5_address"]),
      proxy_port(settings["socks5_port"]) {

    logger->debug("socks5: connecting to Tor at %s:%s",
                  settings["socks5_address"].c_str(),
                  settings["socks5_port"].c_str());

    // Step #0: Steal "error", "connect", and "flush" handlers

    conn.on_error([this](Error err) { emit_error(err); });
    conn.on_connect([this]() {
        conn.on_flush([]() {
            // Nothing
        });

        // Step #1: send out preferred authentication methods

        logger->debug("socks5: connected to Tor!");

        Buffer out;
        out.write_uint8(5); // Version
        out.write_uint8(1); // Number of methods
        out.write_uint8(0); // "NO_AUTH" meth.
        conn.send(out);

        logger->debug("socks5: >> version=5");
        logger->debug("socks5: >> number of methods=1");
        logger->debug("socks5: >> NO_AUTH (0)");

        // Step #2: receive the allowed authentication methods

        conn.on_data([this](Buffer d) {
            buffer << d;
            auto readbuf = buffer.readn(2);
            if (readbuf == "") {
                return; // Try again after next recv()
            }

            logger->debug("socks5: << version=%d", readbuf[0]);
            logger->debug("socks5: << auth=%d", readbuf[1]);

            if (readbuf[0] != 5 || // Reply version
                readbuf[1] != 0) { // Preferred auth method
                emit_error(BadSocksVersionError());
                return;
            }

            // Step #3: ask Tor to connect to remote host

            Buffer out;
            out.write_uint8(5); // Version
            out.write_uint8(1); // CMD_CONNECT
            out.write_uint8(0); // Reserved
            out.write_uint8(3); // ATYPE_DOMAINNAME

            logger->debug("socks5: >> version=5");
            logger->debug("socks5: >> CMD_CONNECT (0)");
            logger->debug("socks5: >> Reserved (0)");
            logger->debug("socks5: >> ATYPE_DOMAINNAME (3)");

            auto address = settings["address"];

            if (address.length() > 255) {
                emit_error(SocksAddressTooLongError());
                return;
            }
            out.write_uint8(address.length());            // Len
            out.write(address.c_str(), address.length()); // String

            logger->debug("socks5: >> domain len=%d",
                          (uint8_t)address.length());
            logger->debug("socks5: >> domain str=%s", address.c_str());

            auto portnum = std::stoi(settings["port"]);
            if (portnum < 0 || portnum > 65535) {
                emit_error(SocksInvalidPortError());
                return;
            }
            out.write_uint16(portnum); // Port

            logger->debug("socks5: >> port=%d", portnum);

            conn.send(out);

            // Step #4: receive Tor's response

            conn.on_data([this](Buffer d) {

                buffer << d;
                if (buffer.length() < 5) {
                    return; // Try again after next recv()
                }

                auto peekbuf = buffer.peek(5);

                logger->debug("socks5: << version=%d", peekbuf[0]);
                logger->debug("socks5: << reply=%d", peekbuf[1]);
                logger->debug("socks5: << reserved=%d", peekbuf[2]);
                logger->debug("socks5: << atype=%d", peekbuf[3]);

                // TODO: Here we should process peekbuf[1] more
                // carefully to map to the error that occurred
                // and report it correctly to the caller

                if (peekbuf[0] != 5 || // Version
                    peekbuf[1] != 0 || // Reply
                    peekbuf[2] != 0) { // Reserved
                    emit_error(SocksGenericError());
                    return;
                }
                auto atype = peekbuf[3]; // Atype

                size_t total = 4; // Version .. Atype size
                if (atype == 1) {
                    total += 4; // IPv4 addr size
                } else if (atype == 3) {
                    total += 1             // Len size
                             + peekbuf[4]; // String size
                } else if (atype == 4) {
                    total += 16; // IPv6 addr size
                } else {
                    emit_error(SocksGenericError());
                    return;
                }
                total += 2; // Port size
                if (buffer.length() < total) {
                    return; // Try again after next recv()
                }

                buffer.discard(total);

                //
                // Step #5: we are now connected
                // Restore the original hooks
                // Tell upstream we are connected
                // If more data, pass it up
                //

                conn.on_data([this](Buffer d) { emit_data(d); });
                conn.on_flush([this]() { emit_flush(); });

                emit_connect();

                // Note that emit_connect() may have called close()
                if (!isclosed && buffer.length() > 0) {
                    emit_data(buffer);
                }
            });
        });
    });
}
Exemple #16
0
// ccall(pointer, rettype, (argtypes...), args...)
static Value *emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
{
    JL_NARGSV(ccall, 3);
    jl_value_t *ptr=NULL, *rt=NULL, *at=NULL;
    JL_GC_PUSH(&ptr, &rt, &at);
    ptr = jl_interpret_toplevel_expr_in(ctx->module, args[1],
                                        &jl_tupleref(ctx->sp,0),
                                        jl_tuple_len(ctx->sp)/2);
    rt  = jl_interpret_toplevel_expr_in(ctx->module, args[2],
                                        &jl_tupleref(ctx->sp,0),
                                        jl_tuple_len(ctx->sp)/2);
    if (jl_is_tuple(rt)) {
        std::string msg = "in " + ctx->funcName +
            ": ccall: missing return type";
        jl_error(msg.c_str());
    }
    at  = jl_interpret_toplevel_expr_in(ctx->module, args[3],
                                        &jl_tupleref(ctx->sp,0),
                                        jl_tuple_len(ctx->sp)/2);
    void *fptr=NULL;
    char *f_name=NULL, *f_lib=NULL;
    if (jl_is_tuple(ptr) && jl_tuple_len(ptr)==1) {
        ptr = jl_tupleref(ptr,0);
    }
    if (jl_is_symbol(ptr))
        f_name = ((jl_sym_t*)ptr)->name;
    else if (jl_is_byte_string(ptr))
        f_name = jl_string_data(ptr);
    if (f_name != NULL) {
        // just symbol, default to JuliaDLHandle
#ifdef __WIN32__
        fptr = jl_dlsym_e(jl_dl_handle, f_name);
        if (!fptr) {
            fptr = jl_dlsym_e(jl_kernel32_handle, f_name);
            if (!fptr) {
                fptr = jl_dlsym_e(jl_ntdll_handle, f_name);
                if (!fptr) {
                    fptr = jl_dlsym_e(jl_crtdll_handle, f_name);
                    if (!fptr) {
                        fptr = jl_dlsym(jl_winsock_handle, f_name);
                    }
                }
            }
        }
        else {
            // available in process symbol table
            fptr = NULL;
        }
#else
        // will look in process symbol table
#endif
    }
    else if (jl_is_cpointer_type(jl_typeof(ptr))) {
        fptr = *(void**)jl_bits_data(ptr);
    }
    else if (jl_is_tuple(ptr) && jl_tuple_len(ptr)>1) {
        jl_value_t *t0 = jl_tupleref(ptr,0);
        jl_value_t *t1 = jl_tupleref(ptr,1);
        if (jl_is_symbol(t0))
            f_name = ((jl_sym_t*)t0)->name;
        else if (jl_is_byte_string(t0))
            f_name = jl_string_data(t0);
        else
            JL_TYPECHK(ccall, symbol, t0);
        if (jl_is_symbol(t1))
            f_lib = ((jl_sym_t*)t1)->name;
        else if (jl_is_byte_string(t1))
            f_lib = jl_string_data(t1);
        else
            JL_TYPECHK(ccall, symbol, t1);
    }
    else {
        JL_TYPECHK(ccall, pointer, ptr);
    }
    if (f_name == NULL && fptr == NULL) {
        JL_GC_POP();
        emit_error("ccall: null function pointer", ctx);
        return literal_pointer_val(jl_nothing);
    }
    JL_TYPECHK(ccall, type, rt);
    JL_TYPECHK(ccall, tuple, at);
    JL_TYPECHK(ccall, type, at);
    jl_tuple_t *tt = (jl_tuple_t*)at;
    std::vector<Type *> fargt(0);
    std::vector<Type *> fargt_sig(0);
    Type *lrt = julia_type_to_llvm(rt);
    if (lrt == NULL) {
        JL_GC_POP();
        return literal_pointer_val(jl_nothing);
    }
    size_t i;
    bool haspointers = false;
    bool isVa = false;
    for(i=0; i < jl_tuple_len(tt); i++) {
        jl_value_t *tti = jl_tupleref(tt,i);
        if (jl_is_seq_type(tti)) {
            isVa = true;
            tti = jl_tparam0(tti);
        }
        Type *t = julia_type_to_llvm(tti);
        if (t == NULL) {
            JL_GC_POP();
            return literal_pointer_val(jl_nothing);
        }
        fargt.push_back(t);
        if (!isVa)
            fargt_sig.push_back(t);
    }
    // check for calling convention specifier
    CallingConv::ID cc = CallingConv::C;
    jl_value_t *last = args[nargs];
    if (jl_is_expr(last)) {
        jl_sym_t *lhd = ((jl_expr_t*)last)->head;
        if (lhd == jl_symbol("stdcall")) {
            cc = CallingConv::X86_StdCall;
            nargs--;
        }
        else if (lhd == jl_symbol("cdecl")) {
            cc = CallingConv::C;
            nargs--;
        }
        else if (lhd == jl_symbol("fastcall")) {
            cc = CallingConv::X86_FastCall;
            nargs--;
        }
    }
    
    if ((!isVa && jl_tuple_len(tt)  != (nargs-2)/2) ||
        ( isVa && jl_tuple_len(tt)-1 > (nargs-2)/2))
        jl_error("ccall: wrong number of arguments to C function");

    // some special functions
    if (fptr == &jl_array_ptr) {
        Value *ary = emit_expr(args[4], ctx);
        JL_GC_POP();
        return mark_julia_type(builder.CreateBitCast(emit_arrayptr(ary),lrt),
                               rt);
    }

    // see if there are & arguments
    for(i=4; i < nargs+1; i+=2) {
        jl_value_t *argi = args[i];
        if (jl_is_expr(argi) && ((jl_expr_t*)argi)->head == amp_sym) {
            haspointers = true;
            break;
        }
    }

    // make LLVM function object for the target
    Constant *llvmf;
    FunctionType *functype = FunctionType::get(lrt, fargt_sig, isVa);
    
    if (fptr != NULL) {
        Type *funcptype = PointerType::get(functype,0);
        llvmf = ConstantExpr::getIntToPtr( 
            ConstantInt::get(funcptype, (uint64_t)fptr), 
            funcptype);
    }
    else {
        if (f_lib != NULL)
            add_library_sym(f_name, f_lib);
        llvmf = jl_Module->getOrInsertFunction(f_name, functype);
    }

    // save temp argument area stack pointer
    Value *saveloc=NULL;
    Value *stacksave=NULL;
    if (haspointers) {
        // TODO: inline this
        saveloc = builder.CreateCall(save_arg_area_loc_func);
        stacksave =
            builder.CreateCall(Intrinsic::getDeclaration(jl_Module,
                                                         Intrinsic::stacksave));
    }

    // emit arguments
    Value *argvals[(nargs-3)/2];
    int last_depth = ctx->argDepth;
    int nargty = jl_tuple_len(tt);
    for(i=4; i < nargs+1; i+=2) {
        int ai = (i-4)/2;
        jl_value_t *argi = args[i];
        bool addressOf = false;
        if (jl_is_expr(argi) && ((jl_expr_t*)argi)->head == amp_sym) {
            addressOf = true;
            argi = jl_exprarg(argi,0);
        }
        Type *largty;
        jl_value_t *jargty;
        if (isVa && ai >= nargty-1) {
            largty = fargt[nargty-1];
            jargty = jl_tparam0(jl_tupleref(tt,nargty-1));
        }
        else {
            largty = fargt[ai];
            jargty = jl_tupleref(tt,ai);
        }
        Value *arg;
        if (largty == jl_pvalue_llvmt) {
            arg = emit_expr(argi, ctx, true);
        }
        else {
            arg = emit_unboxed(argi, ctx);
            if (jl_is_bits_type(expr_type(argi, ctx))) {
                if (addressOf)
                    arg = emit_unbox(largty->getContainedType(0), largty, arg);
                else
                    arg = emit_unbox(largty, PointerType::get(largty,0), arg);
            }
        }
        /*
#ifdef JL_GC_MARKSWEEP
        // make sure args are rooted
        if (largty->isPointerTy() &&
            (largty == jl_pvalue_llvmt ||
             !jl_is_bits_type(expr_type(args[i], ctx)))) {
            make_gcroot(boxed(arg), ctx);
        }
#endif
        */
        argvals[ai] = julia_to_native(largty, jargty, arg, argi, addressOf,
                                      ai+1, ctx);
    }
    // the actual call
    Value *result = builder.CreateCall(llvmf,
                                       ArrayRef<Value*>(&argvals[0],(nargs-3)/2));
    if (cc != CallingConv::C)
        ((CallInst*)result)->setCallingConv(cc);

    // restore temp argument area stack pointer
    if (haspointers) {
        assert(saveloc != NULL);
        builder.CreateCall(restore_arg_area_loc_func, saveloc);
        assert(stacksave != NULL);
        builder.CreateCall(Intrinsic::getDeclaration(jl_Module,
                                                     Intrinsic::stackrestore),
                           stacksave);
    }
    ctx->argDepth = last_depth;
    if (0) { // Enable this to turn on SSPREQ (-fstack-protector) on the function containing this ccall
        ctx->f->addFnAttr(Attribute::StackProtectReq);
    }

    JL_GC_POP();
    if (lrt == T_void)
        return literal_pointer_val((jl_value_t*)jl_nothing);
    return mark_julia_type(result, rt);
}
Exemple #17
0
// ccall(pointer, rettype, (argtypes...), args...)
static Value *emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
{
    JL_NARGSV(ccall, 3);
    jl_value_t *rt=NULL, *at=NULL;
    JL_GC_PUSH2(&rt, &at);

    native_sym_arg_t symarg = interpret_symbol_arg(args[1], ctx, "ccall");
    Value *jl_ptr=NULL;
    void *fptr = NULL;
    char *f_name = NULL, *f_lib = NULL;
    jl_ptr = symarg.jl_ptr;
    fptr = symarg.fptr;
    f_name = symarg.f_name;
    f_lib = symarg.f_lib;
    if (f_name == NULL && fptr == NULL && jl_ptr == NULL) {
        JL_GC_POP();
        emit_error("ccall: null function pointer", ctx);
        return literal_pointer_val(jl_nothing);
    }

    rt  = jl_interpret_toplevel_expr_in(ctx->module, args[2],
                                        &jl_tupleref(ctx->sp,0),
                                        jl_tuple_len(ctx->sp)/2);
    if (jl_is_tuple(rt)) {
        std::string msg = "in " + ctx->funcName +
            ": ccall: missing return type";
        jl_error(msg.c_str());
    }
    if (rt == (jl_value_t*)jl_pointer_type)
        jl_error("ccall: return type Ptr should have an element type, Ptr{T}");
    at  = jl_interpret_toplevel_expr_in(ctx->module, args[3],
                                        &jl_tupleref(ctx->sp,0),
                                        jl_tuple_len(ctx->sp)/2);

    JL_TYPECHK(ccall, type, rt);
    JL_TYPECHK(ccall, tuple, at);
    JL_TYPECHK(ccall, type, at);
    jl_tuple_t *tt = (jl_tuple_t*)at;
    std::vector<Type *> fargt(0);
    std::vector<Type *> fargt_sig(0);
    Type *lrt = julia_struct_to_llvm(rt);
    if (lrt == NULL) {
        JL_GC_POP();
        emit_error("ccall: return type doesn't correspond to a C type", ctx);
        return literal_pointer_val(jl_nothing);
    }
    size_t i;
    bool isVa = false;
    size_t nargt = jl_tuple_len(tt);
    std::vector<AttributeWithIndex> attrs;

    for(i=0; i < nargt; i++) {
        jl_value_t *tti = jl_tupleref(tt,i);
        if (tti == (jl_value_t*)jl_pointer_type)
            jl_error("ccall: argument type Ptr should have an element type, Ptr{T}");
        if (jl_is_vararg_type(tti)) {
            isVa = true;
            tti = jl_tparam0(tti);
        }
        if (jl_is_bitstype(tti)) {
            // see pull req #978. need to annotate signext/zeroext for
            // small integer arguments.
            jl_datatype_t *bt = (jl_datatype_t*)tti;
            if (bt->size < 4) {
                if (jl_signed_type == NULL) {
                    jl_signed_type = jl_get_global(jl_core_module,jl_symbol("Signed"));
                }
#ifdef LLVM32
                Attributes::AttrVal av;
                if (jl_signed_type && jl_subtype(tti, jl_signed_type, 0))
                    av = Attributes::SExt;
                else
                    av = Attributes::ZExt;
                attrs.push_back(AttributeWithIndex::get(getGlobalContext(), i+1,
                                                        ArrayRef<Attributes::AttrVal>(&av, 1)));
#else
                Attribute::AttrConst av;
                if (jl_signed_type && jl_subtype(tti, jl_signed_type, 0))
                    av = Attribute::SExt;
                else
                    av = Attribute::ZExt;
                attrs.push_back(AttributeWithIndex::get(i+1, av));
#endif
            }
        }
        Type *t = julia_struct_to_llvm(tti);
        if (t == NULL) {
            JL_GC_POP();
            std::stringstream msg;
            msg << "ccall: the type of argument ";
            msg << i+1;
            msg << " doesn't correspond to a C type";
            emit_error(msg.str(), ctx);
            return literal_pointer_val(jl_nothing);
        }
        fargt.push_back(t);
        if (!isVa)
            fargt_sig.push_back(t);
    }
    // check for calling convention specifier
    CallingConv::ID cc = CallingConv::C;
    jl_value_t *last = args[nargs];
    if (jl_is_expr(last)) {
        jl_sym_t *lhd = ((jl_expr_t*)last)->head;
        if (lhd == jl_symbol("stdcall")) {
            cc = CallingConv::X86_StdCall;
            nargs--;
        }
        else if (lhd == jl_symbol("cdecl")) {
            cc = CallingConv::C;
            nargs--;
        }
        else if (lhd == jl_symbol("fastcall")) {
            cc = CallingConv::X86_FastCall;
            nargs--;
        }
        else if (lhd == jl_symbol("thiscall")) {
            cc = CallingConv::X86_ThisCall;
            nargs--;
        }
    }
    
    if ((!isVa && jl_tuple_len(tt)  != (nargs-2)/2) ||
        ( isVa && jl_tuple_len(tt)-1 > (nargs-2)/2))
        jl_error("ccall: wrong number of arguments to C function");

    // some special functions
    if (fptr == &jl_array_ptr) {
        assert(lrt->isPointerTy());
        Value *ary = emit_expr(args[4], ctx);
        JL_GC_POP();
        return mark_julia_type(builder.CreateBitCast(emit_arrayptr(ary),lrt),
                               rt);
    }
    if (fptr == &jl_value_ptr) {
        assert(lrt->isPointerTy());
        jl_value_t *argi = args[4];
        bool addressOf = false;
        if (jl_is_expr(argi) && ((jl_expr_t*)argi)->head == amp_sym) {
            addressOf = true;
            argi = jl_exprarg(argi,0);
        }
        Value *ary = boxed(emit_expr(argi, ctx));
        JL_GC_POP();
        return mark_julia_type(
                builder.CreateBitCast(emit_nthptr_addr(ary, addressOf?1:0),lrt),
                rt);
    }

    // make LLVM function object for the target
    Value *llvmf;
    FunctionType *functype = FunctionType::get(lrt, fargt_sig, isVa);
    
    if (jl_ptr != NULL) {
        null_pointer_check(jl_ptr,ctx);
        Type *funcptype = PointerType::get(functype,0);
        llvmf = builder.CreateIntToPtr(jl_ptr, funcptype);
    }
    else if (fptr != NULL) {
        Type *funcptype = PointerType::get(functype,0);
        llvmf = literal_pointer_val(fptr, funcptype);
    }
    else {
        void *symaddr;
        if (f_lib != NULL)
            symaddr = add_library_sym(f_name, f_lib);
        else
            symaddr = sys::DynamicLibrary::SearchForAddressOfSymbol(f_name);
        if (symaddr == NULL) {
            JL_GC_POP();
            std::stringstream msg;
            msg << "ccall: could not find function ";
            msg << f_name;
            if (f_lib != NULL) {
                msg << " in library ";
                msg << f_lib;
            }
            emit_error(msg.str(), ctx);
            return literal_pointer_val(jl_nothing);
        }
        llvmf = jl_Module->getOrInsertFunction(f_name, functype);
    }

    // save place before arguments, for possible insertion of temp arg
    // area saving code.
    Value *saveloc=NULL;
    Value *stacksave=NULL;
    BasicBlock::InstListType &instList = builder.GetInsertBlock()->getInstList();
    Instruction *savespot;
    if (instList.empty()) {
        savespot = NULL;
    }
    else {
        // hey C++, there's this thing called pointers...
        Instruction &_savespot = builder.GetInsertBlock()->back();
        savespot = &_savespot;
    }

    // emit arguments
    Value *argvals[(nargs-3)/2];
    int last_depth = ctx->argDepth;
    int nargty = jl_tuple_len(tt);
    bool needTempSpace = false;
    for(i=4; i < nargs+1; i+=2) {
        int ai = (i-4)/2;
        jl_value_t *argi = args[i];
        bool addressOf = false;
        if (jl_is_expr(argi) && ((jl_expr_t*)argi)->head == amp_sym) {
            addressOf = true;
            argi = jl_exprarg(argi,0);
        }
        Type *largty;
        jl_value_t *jargty;
        if (isVa && ai >= nargty-1) {
            largty = fargt[nargty-1];
            jargty = jl_tparam0(jl_tupleref(tt,nargty-1));
        }
        else {
            largty = fargt[ai];
            jargty = jl_tupleref(tt,ai);
        }
        Value *arg;
        if (largty == jl_pvalue_llvmt ||
                largty->isStructTy()) {
            arg = emit_expr(argi, ctx, true);
        }
        else {
            arg = emit_unboxed(argi, ctx);
            if (jl_is_bitstype(expr_type(argi, ctx))) {
                if (addressOf)
                    arg = emit_unbox(largty->getContainedType(0), largty, arg);
                else
                    arg = emit_unbox(largty, PointerType::get(largty,0), arg);
            }
        }
        /*
#ifdef JL_GC_MARKSWEEP
        // make sure args are rooted
        if (largty->isPointerTy() &&
            (largty == jl_pvalue_llvmt ||
             !jl_is_bits_type(expr_type(args[i], ctx)))) {
            make_gcroot(boxed(arg), ctx);
        }
#endif
        */
        bool mightNeed=false;
        argvals[ai] = julia_to_native(largty, jargty, arg, argi, addressOf,
                                      ai+1, ctx, &mightNeed);
        needTempSpace |= mightNeed;
    }
    if (needTempSpace) {
        // save temp argument area stack pointer
        // TODO: inline this
        saveloc = CallInst::Create(save_arg_area_loc_func);
        stacksave = CallInst::Create(Intrinsic::getDeclaration(jl_Module,
                                                               Intrinsic::stacksave));
        if (savespot)
            instList.insertAfter(savespot, (Instruction*)saveloc);
        else
            instList.push_front((Instruction*)saveloc);
        instList.insertAfter((Instruction*)saveloc, (Instruction*)stacksave);
    }
    // the actual call
    Value *result = builder.CreateCall(llvmf,
                                       ArrayRef<Value*>(&argvals[0],(nargs-3)/2));
    if (cc != CallingConv::C)
        ((CallInst*)result)->setCallingConv(cc);

#ifdef LLVM32
    ((CallInst*)result)->setAttributes(AttrListPtr::get(getGlobalContext(), ArrayRef<AttributeWithIndex>(attrs)));
#else
    ((CallInst*)result)->setAttributes(AttrListPtr::get(attrs.data(),attrs.size()));
#endif
    if (needTempSpace) {
        // restore temp argument area stack pointer
        assert(saveloc != NULL);
        builder.CreateCall(restore_arg_area_loc_func, saveloc);
        assert(stacksave != NULL);
        builder.CreateCall(Intrinsic::getDeclaration(jl_Module,
                                                     Intrinsic::stackrestore),
                           stacksave);
    }
    ctx->argDepth = last_depth;
    if (0) { // Enable this to turn on SSPREQ (-fstack-protector) on the function containing this ccall
#ifdef LLVM32        
        ctx->f->addFnAttr(Attributes::StackProtectReq);
#else
        ctx->f->addFnAttr(Attribute::StackProtectReq);
#endif
    }

    JL_GC_POP();
    if (lrt == T_void)
        return literal_pointer_val((jl_value_t*)jl_nothing);
    if (lrt->isStructTy()) {
        //fprintf(stderr, "ccall rt: %s -> %s\n", f_name, ((jl_tag_type_t*)rt)->name->name->name);
        assert(jl_is_structtype(rt));
        Value *strct =
            builder.CreateCall(jlallocobj_func,
                               ConstantInt::get(T_size,
                                    sizeof(void*)+((jl_datatype_t*)rt)->size));
        builder.CreateStore(literal_pointer_val((jl_value_t*)rt),
                            emit_nthptr_addr(strct, (size_t)0));
        builder.CreateStore(result,
                            builder.CreateBitCast(
                                emit_nthptr_addr(strct, (size_t)1),
                                PointerType::get(lrt,0)));
        return mark_julia_type(strct, rt);
    }
    return mark_julia_type(result, rt);
}
bool PythonScript::compile(bool for_eval)
{
    // Support for the convenient col() and cell() functions.
    // This can't be done anywhere else, because we need access to the local
    // variables self, i and j.
    if(Context->inherits("Table")) {
        // A bit of a hack, but we need either IndexError or len() from __builtins__.
        PyDict_SetItemString(localDict, "__builtins__",
                             PyDict_GetItemString(env()->globalDict(), "__builtins__"));
        PyObject *ret = PyRun_String(
                            "def col(c,*arg):\n"
                            "\ttry: return self.cell(c,arg[0])\n"
                            "\texcept(IndexError): return self.cell(c,i)\n"
                            "def cell(c,r):\n"
                            "\treturn self.cell(c,r)\n"
                            "def tablecol(t,c):\n"
                            "\treturn self.folder().rootFolder().table(t,True).cell(c,i)\n"
                            "def _meth_table_col_(t,c):\n"
                            "\treturn t.cell(c,i)\n"
                            "self.__class__.col = _meth_table_col_",
                            Py_file_input, localDict, localDict);
        if (ret)
            Py_DECREF(ret);
        else
            PyErr_Print();
    } else if(Context->inherits("Matrix")) {
        // A bit of a hack, but we need either IndexError or len() from __builtins__.
        PyDict_SetItemString(localDict, "__builtins__",
                             PyDict_GetItemString(env()->globalDict(), "__builtins__"));
        PyObject *ret = PyRun_String(
                            "def cell(*arg):\n"
                            "\ttry: return self.cell(arg[0],arg[1])\n"
                            "\texcept(IndexError): return self.cell(i,j)\n",
                            Py_file_input, localDict, localDict);
        if (ret)
            Py_DECREF(ret);
        else
            PyErr_Print();
    }
    bool success=false;
    Py_XDECREF(PyCode);
    // Simplest case: Code is a single expression
    PyCode = Py_CompileString(Code, Name, Py_eval_input);

    if (PyCode)
        success = true;
    else if (for_eval) {
        // Code contains statements (or errors) and we want to get a return
        // value from it.
        // So we wrap the code into a function definition,
        // execute that (as Py_file_input) and store the function object in PyCode.
        // See http://mail.python.org/pipermail/python-list/2001-June/046940.html
        // for why there isn't an easier way to do this in Python.
        PyErr_Clear(); // silently ignore errors
        PyObject *key, *value;
#if PY_VERSION_HEX >= 0x02050000
        Py_ssize_t i=0;
#else
        int i=0;
#endif
        QString signature = "";
        while(PyDict_Next(localDict, &i, &key, &value))
            signature.append(PyString_AsString(key)).append(",");
        signature.truncate(signature.length()-1);
        QString fdef = "def __doit__("+signature+"):\n";
        fdef.append(Code);
        fdef.replace('\n',"\n\t");
        PyCode = Py_CompileString(fdef, Name, Py_file_input);
        if (PyCode) {
            PyObject *tmp = PyDict_New();
            Py_XDECREF(PyEval_EvalCode((PyCodeObject*)PyCode, env()->globalDict(), tmp));
            Py_DECREF(PyCode);
            PyCode = PyDict_GetItemString(tmp,"__doit__");
            Py_XINCREF(PyCode);
            Py_DECREF(tmp);
        }
        success = (PyCode != NULL);
    } else {
        // Code contains statements (or errors), but we do not need to get
        // a return value.
        PyErr_Clear(); // silently ignore errors
        PyCode = Py_CompileString(Code, Name, Py_file_input);
        success = (PyCode != NULL);
    }

    if (!success) {
        compiled = compileErr;
        emit_error(env()->errorMsg(), 0);
    } else
        compiled = isCompiled;
    return success;
}
/**
 * \brief Do in-place translation of overloaded functions.
 *
 * Recursively replaces:
 * - col("name") with column("name")
 * - col(arg) with column("arg") if the current table contains a column named
 * "arg" and
 *   with column_(arg) otherwise
 * - col("name", row) with cell("name", row)
 * - col(arg, row) with cell("arg", row) if the current table contains a column
 * named "arg" and
 *   with cell_(arg, row) otherwise
 * - tablecol("tableName", "columnName") with column("tableName/columnName")
 * - tablecol("tableName", columnIndex) with column__("tableName", columnIndex)
 * - cell(columnIndex, rowIndex) with cell_(columnIndex, rowIndex)
 *
 * Also escapes occurences of / in table/column names, so that legacy formulas
 * work with the path
 * argument of the new column() and cell() functions (see resolveColumnPath()).
 */
bool MuParserScript::translateLegacyFunctions(QString &input) {
  QRegExp legacyFunction("(\\W||^)(col|tablecol|cell)\\s*\\(");

  int functionStart = legacyFunction.indexIn(input, 0);
  while (functionStart != -1) {
    QStringList arguments;
    int functionEnd = functionStart;  // initialization is a failsafe
    QString replacement;

    // parse arguments of function
    QString currentArgument;
    for (int i = functionStart + legacyFunction.matchedLength(),
             parenthesisLevel = 1;
         parenthesisLevel > 0 && i < input.size(); i++) {
      switch (input.at(i).toAscii()) {
        case '"':
          currentArgument += '"';
          for (i++; i < input.size() && input.at(i) != QChar('"'); i++)
            if (input.at(i) == QChar('\\')) {
              currentArgument += '\\';
              currentArgument += input.at(++i);
            } else
              currentArgument += input.at(i);
          currentArgument += '"';
          break;
        case '\\':
          currentArgument += '\\';
          currentArgument += input.at(++i);
          break;
        case '(':
          parenthesisLevel++;
          currentArgument += '(';
          break;
        case ')':
          parenthesisLevel--;
          if (parenthesisLevel > 0)
            currentArgument += ')';
          else
            functionEnd = i;
          break;
        case ',':
          if (parenthesisLevel == 1) {
            arguments << currentArgument;
            currentArgument.clear();
          } else
            currentArgument += ',';
          break;
        default:
          currentArgument += input.at(i);
          break;
      }
    }
    arguments << currentArgument;

    // select replacement function call
    Table *table = qobject_cast<Table *>(Context);
    if (legacyFunction.cap(2) == "col") {
      QString columnArgument;
      bool numericColumn = false;
      if (arguments.at(0).startsWith("\"")) {
        // col("name") -> column("name")
        columnArgument = arguments.at(0);
        // do escaping of path argument
        columnArgument.replace("\\", "\\\\");
        columnArgument.replace("/", "\\/");
      } else if (table &&
                 table->d_future_table->column(arguments.at(0), false)) {
        // hack for ambiguous legacy syntax:
        // col(name) -> column("name"), if name is a column of the current table
        columnArgument = "\"" + arguments.at(0) + "\"";
        // do escaping of path argument
        columnArgument.replace("\\", "\\\\");
        columnArgument.replace("/", "\\/");
      } else {
        // col(expression) -> column_(expression)
        columnArgument = arguments.at(0);
        if (!translateLegacyFunctions(columnArgument)) return false;
        numericColumn = true;
      }
      if (arguments.size() > 1) {
        QString rowArgument = arguments.at(1);
        if (!translateLegacyFunctions(rowArgument)) return false;
        replacement = QString("cell") + (numericColumn ? "_" : "") + "(" +
                      columnArgument + "," + rowArgument + ")";
      } else
        replacement = QString("column") + (numericColumn ? "_" : "") + "(" +
                      columnArgument + ")";
    } else if (legacyFunction.cap(2) == "tablecol") {
      // assert number of arguments == 2
      if (arguments.size() != 2) {
        emit_error(tr("tablecol: wrong number of arguments (need 2, got %1)")
                       .arg(arguments.size()),
                   0);
        compiled = Script::compileErr;
        return false;
      }
      if (arguments.at(1).startsWith("\"")) {
        // tablecol("table", "column") -> column("table/column")
        // do escaping of path argument
        QString tableArgument = arguments.at(0);
        tableArgument.replace("\\", "\\\\");
        tableArgument.replace("/", "\\/");
        QString columnArgument = arguments.at(1);
        columnArgument.replace("\\", "\\\\");
        columnArgument.replace("/", "\\/");
        // remove quotation marks
        tableArgument.remove(tableArgument.size() - 1, 1);
        columnArgument.remove(0, 1);
        replacement =
            QString("column(") + tableArgument + "/" + columnArgument + ")";
      } else {
        // tablecol("table", column) -> column__("table", column)
        QString rowArgument = arguments.at(1);
        if (!translateLegacyFunctions(rowArgument)) return false;
        replacement =
            QString("column__(") + arguments.at(0) + "," + rowArgument + ")";
      }
    } else {  // legacyFunction.cap(2) == "cell"
      // assert number of arguments == 2
      if (arguments.size() != 2) {
        emit_error(tr("cell: wrong number of arguments (need 2, got %1)")
                       .arg(arguments.size()),
                   0);
        compiled = Script::compileErr;
        return false;
      }
      if (arguments.at(0).startsWith("\"")) {
        // keep cell("column",row) -- this is new-style syntax
        QString rowArgument = arguments.at(1);
        if (!translateLegacyFunctions(rowArgument)) return false;
        replacement =
            QString("cell(") + arguments.at(0) + "," + rowArgument + ")";
      } else {
        // cell(column,row) -> cell_(column,row)
        QString columnArgument = arguments.at(0);
        if (!translateLegacyFunctions(columnArgument)) return false;
        QString rowArgument = arguments.at(1);
        if (!translateLegacyFunctions(rowArgument)) return false;
        replacement =
            QString("cell_(") + columnArgument + "," + rowArgument + ")";
      }
    }

    // do replacement
    if (legacyFunction.cap(1).isEmpty())
      // matched with ^, not \W (lookbehind assertion would be darn handy...)
      input.replace(functionStart, functionEnd - functionStart + 1,
                    replacement);
    else
      // need to adjust for the additional matched character
      input.replace(functionStart + 1, functionEnd - functionStart,
                    replacement);
    // search for next match, starting at the end of the replaced text
    functionStart =
        legacyFunction.indexIn(input, functionStart + replacement.length());
  }  // while (functionStart != -1)
  return true;
}
Exemple #20
0
static Value *julia_to_native(Type *ty, jl_value_t *jt, Value *jv,
                              jl_value_t *argex, bool addressOf,
                              int argn, jl_codectx_t *ctx,
                              bool *mightNeedTempSpace, bool *needStackRestore)
{
    Type *vt = jv->getType();
    if (ty == jl_pvalue_llvmt) {
        return boxed(jv,ctx);
    }
    else if (ty == vt && !addressOf) {
        return jv;
    }
    else if (vt != jl_pvalue_llvmt) {
        // argument value is unboxed
        if (addressOf) {
            if (ty->isPointerTy() && ty->getContainedType(0)==vt) {
                // pass the address of an alloca'd thing, not a box
                // since those are immutable.
                *needStackRestore = true;
                Value *slot = builder.CreateAlloca(vt);
                builder.CreateStore(jv, slot);
                return builder.CreateBitCast(slot, ty);
            }
        }
        else if ((vt->isIntegerTy() && ty->isIntegerTy()) ||
                 (vt->isFloatingPointTy() && ty->isFloatingPointTy()) ||
                 (vt->isPointerTy() && ty->isPointerTy())) {
            if (vt->getPrimitiveSizeInBits() ==
                ty->getPrimitiveSizeInBits()) {
                return builder.CreateBitCast(jv, ty);
            }
        }
        // error. box for error handling.
        jv = boxed(jv,ctx);
    }
    else if (jl_is_cpointer_type(jt)) {
        assert(ty->isPointerTy());
        jl_value_t *aty = expr_type(argex, ctx);
        if (jl_is_array_type(aty) &&
            (jl_tparam0(jt) == jl_tparam0(aty) ||
             jl_tparam0(jt) == (jl_value_t*)jl_bottom_type)) {
            // array to pointer
            return builder.CreateBitCast(emit_arrayptr(jv), ty);
        }
        if (aty == (jl_value_t*)jl_ascii_string_type || aty == (jl_value_t*)jl_utf8_string_type) {
            return builder.CreateBitCast(emit_arrayptr(emit_nthptr(jv,1,tbaa_const)), ty);
        }
        if (jl_is_structtype(aty) && jl_is_leaf_type(aty) && !jl_is_array_type(aty)) {
            if (!addressOf) {
                emit_error("ccall: expected & on argument", ctx);
                return literal_pointer_val(jl_nothing);
            }
            return builder.CreateBitCast(emit_nthptr_addr(jv, (size_t)1), ty); // skip type tag field
        }
        *mightNeedTempSpace = true;
        Value *p = builder.CreateCall4(prepare_call(value_to_pointer_func),
                                       literal_pointer_val(jl_tparam0(jt)), jv,
                                       ConstantInt::get(T_int32, argn),
                                       ConstantInt::get(T_int32, (int)addressOf));
        return builder.CreateBitCast(p, ty);
    }
    else if (jl_is_structtype(jt)) {
        if (addressOf)
            jl_error("ccall: unexpected & on argument"); // the only "safe" thing to emit here is the expected struct
        assert (ty->isStructTy() && (Type*)((jl_datatype_t*)jt)->struct_decl == ty);
        jl_value_t *aty = expr_type(argex, ctx);
        if (aty != jt) {
            std::stringstream msg;
            msg << "ccall argument ";
            msg << argn;
            emit_typecheck(jv, jt, msg.str(), ctx);
        }
        //TODO: check instead that prefix matches
        //if (!jl_is_structtype(aty))
        //    emit_typecheck(emit_typeof(jv), (jl_value_t*)jl_struct_kind, "ccall: Struct argument called with something that isn't a struct", ctx);
        // //safe thing would be to also check that jl_typeof(aty)->size > sizeof(ty) here and/or at runtime
        Value *pjv = builder.CreateBitCast(emit_nthptr_addr(jv, (size_t)1), PointerType::get(ty,0));
        return builder.CreateLoad(pjv, false);
    }
    else if (jl_is_tuple(jt)) {
        return emit_unbox(ty,jv,jt);
    }
    // TODO: error for & with non-pointer argument type
    assert(jl_is_bitstype(jt));
    std::stringstream msg;
    msg << "ccall argument ";
    msg << argn;
    emit_typecheck(jv, jt, msg.str(), ctx);
    Value *p = data_pointer(jv);
    return builder.CreateLoad(builder.CreateBitCast(p,
                                                    PointerType::get(ty,0)),
                              false);
}
/**
 * Evaluate the code and return the value
 * @return
 */
QVariant PythonScript::evaluateImpl() {
  ScopedPythonGIL lock;
  PyObject *compiledCode = this->compileToByteCode(true);
  if (!compiledCode) {
    return QVariant("");
  }
  PyObject *pyret;
  beginStdoutRedirect();
  if (PyCallable_Check(compiledCode)) {
    PyObject *empty_tuple = PyTuple_New(0);
    pyret = PyObject_Call(compiledCode, empty_tuple, localDict);
    Py_DECREF(empty_tuple);
  } else {
    pyret = PyEval_EvalCode(CODE_OBJECT(compiledCode), localDict, localDict);
  }
  endStdoutRedirect();
  if (!pyret) {
    if (PyErr_ExceptionMatches(PyExc_ValueError) ||
        PyErr_ExceptionMatches(PyExc_ZeroDivisionError)) {
      PyErr_Clear(); // silently ignore errors
      return QVariant("");
    } else {
      emit_error();
      return QVariant();
    }
  }

  QVariant qret = QVariant();
  /* None */
  if (pyret == Py_None) {
    qret = QVariant("");
  }
  /* numeric types */
  else if (PyFloat_Check(pyret)) {
    qret = QVariant(PyFloat_AS_DOUBLE(pyret));
  } else if (INT_CHECK(pyret)) {
    qret = QVariant((qlonglong)TO_LONG(pyret));
  }
#if !defined(IS_PY3K)
  else if (PyLong_Check(pyret)) {
    qret = QVariant((qlonglong)PyLong_AsLongLong(pyret));
  }
#endif
  else if (PyNumber_Check(pyret)) {
    PyObject *number = PyNumber_Float(pyret);
    if (number) {
      qret = QVariant(PyFloat_AS_DOUBLE(number));
      Py_DECREF(number);
    }
  }
  /* bool */
  else if (PyBool_Check(pyret)) {
    qret = QVariant(pyret == Py_True);
  }
  // could handle advanced types (such as PyList->QValueList) here if needed
  /* fallback: try to convert to (unicode) string */
  if (!qret.isValid()) {
#if defined(IS_PY3K)
    // In 3 everything is unicode
    PyObject *pystring = PyObject_Str(pyret);
    if (pystring) {
      qret = QVariant(QString::fromUtf8(_PyUnicode_AsString(pystring)));
    }
#else
    PyObject *pystring = PyObject_Unicode(pyret);
    if (pystring) {
      PyObject *asUTF8 =
          PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(pystring),
                               (int)PyUnicode_GET_DATA_SIZE(pystring), nullptr);
      Py_DECREF(pystring);
      if (asUTF8) {
        qret = QVariant(QString::fromUtf8(PyString_AS_STRING(asUTF8)));
        Py_DECREF(asUTF8);
      } else if ((pystring = PyObject_Str(pyret))) {
        qret = QVariant(QString(PyString_AS_STRING(pystring)));
        Py_DECREF(pystring);
      }
    }
#endif
  }
  Py_DECREF(pyret);
  if (PyErr_Occurred()) {
    if (PyErr_ExceptionMatches(PyExc_ValueError) ||
        PyErr_ExceptionMatches(PyExc_ZeroDivisionError)) {
      PyErr_Clear(); // silently ignore errors
      return QVariant("");
    } else {
      emit_error();
    }
    return QVariant();
  }
  return qret;
}
Exemple #22
0
int run_em(EM_ENG_PTR em_ptr)
{
    int     r, iterate, old_valid, converged, saved = 0;
    double  likelihood, log_prior;
    double  lambda, old_lambda = 0.0;

    config_em(em_ptr);

    for (r = 0; r < num_restart; r++) {
        SHOW_PROGRESS_HEAD("#em-iters", r);

        initialize_params();
        itemp = daem ? itemp_init : 1.0;
        iterate = 0;

        /* [21 Aug 2007, by yuizumi]
         * while-loop for inversed temperature (DAEM).  Note that this
         * loop is evaluated only once for EM without annealing, since
         * itemp initially set to 1.0 by the code above.
         */
        while (1) {
            if (daem) {
                SHOW_PROGRESS_TEMP(itemp);
            }
            old_valid = 0;

            while (1) {
                if (CTRLC_PRESSED) {
                    SHOW_PROGRESS_INTR();
                    RET_ERR(err_ctrl_c_pressed);
                }

                RET_ON_ERR(em_ptr->compute_inside());
                RET_ON_ERR(em_ptr->examine_inside());

                likelihood = em_ptr->compute_likelihood();
                log_prior  = em_ptr->smooth ? em_ptr->compute_log_prior() : 0.0;
                lambda = likelihood + log_prior;

                if (verb_em) {
                    if (em_ptr->smooth) {
                        prism_printf("Iteration #%d:\tlog_likelihood=%.9f\tlog_prior=%.9f\tlog_post=%.9f\n", iterate, likelihood, log_prior, lambda);
                    }
                    else {
                        prism_printf("Iteration #%d:\tlog_likelihood=%.9f\n", iterate, likelihood);
                    }
                }

                if (debug_level) {
                    prism_printf("After I-step[%d]:\n", iterate);
                    prism_printf("likelihood = %.9f\n", likelihood);
                    print_egraph(debug_level, PRINT_EM);
                }

                if (!isfinite(lambda)) {
                    emit_internal_error("invalid log likelihood or log post: %s (at iteration #%d)",
                                        isnan(lambda) ? "NaN" : "infinity", iterate);
                    RET_ERR(ierr_invalid_likelihood);
                }
                if (old_valid && old_lambda - lambda > prism_epsilon) {
                    emit_error("log likelihood or log post decreased [old: %.9f, new: %.9f] (at iteration #%d)",
                               old_lambda, lambda, iterate);
                    RET_ERR(err_invalid_likelihood);
                }
                if (itemp == 1.0 && likelihood > 0.0) {
                    emit_error("log likelihood greater than zero [value: %.9f] (at iteration #%d)",
                               likelihood, iterate);
                    RET_ERR(err_invalid_likelihood);
                }

                converged = (old_valid && lambda - old_lambda <= prism_epsilon);
                if (converged || REACHED_MAX_ITERATE(iterate)) {
                    break;
                }

                old_lambda = lambda;
                old_valid  = 1;

                RET_ON_ERR(em_ptr->compute_expectation());

                if (debug_level) {
                    prism_printf("After O-step[%d]:\n", iterate);
                    print_egraph(debug_level, PRINT_EM);
                }

                SHOW_PROGRESS(iterate);
                RET_ON_ERR(em_ptr->update_params());
                iterate++;
            }

            /* [21 Aug 2007, by yuizumi]
             * Note that 1.0 can be represented exactly in IEEE 754.
             */
            if (itemp == 1.0) {
                break;
            }
            itemp *= itemp_rate;
            if (itemp >= 1.0) {
                itemp = 1.0;
            }
        }

        SHOW_PROGRESS_TAIL(converged, iterate, lambda);

        if (r == 0 || lambda > em_ptr->lambda) {
            em_ptr->lambda     = lambda;
            em_ptr->likelihood = likelihood;
            em_ptr->iterate    = iterate;

            saved = (r < num_restart - 1);
            if (saved) {
                save_params();
            }
        }
    }

    if (saved) {
        restore_params();
    }

    em_ptr->bic = compute_bic(em_ptr->likelihood);
    em_ptr->cs  = em_ptr->smooth ? compute_cs(em_ptr->likelihood) : 0.0;

    return BP_TRUE;
}
Exemple #23
0
/* main loop */
static int run_grd(CRF_ENG_PTR crf_ptr) {
	int r,iterate,old_valid,converged,conv_time,saved = 0;
	double likelihood,old_likelihood = 0.0;
	double crf_max_iterate = 0.0;
	double tmp_epsilon,alpha0,gf_sd,old_gf_sd = 0.0;

	config_crf(crf_ptr);

	initialize_weights();

	if (crf_learn_mode == 1) {
		initialize_LBFGS();
		printf("L-BFGS mode\n");
	}

	if (crf_learning_rate==1) {
		printf("learning rate:annealing\n");
	} else if (crf_learning_rate==2) {
		printf("learning rate:backtrack\n");
	} else if (crf_learning_rate==3) {
		printf("learning rate:golden section\n");
	}

	if (max_iterate == -1) {
		crf_max_iterate = DEFAULT_MAX_ITERATE;
	} else if (max_iterate >= +1) {
		crf_max_iterate = max_iterate;
	}

	for (r = 0; r < num_restart; r++) {
		SHOW_PROGRESS_HEAD("#crf-iters", r);

		initialize_crf_count();
		initialize_lambdas();
		initialize_visited_flags();

		old_valid = 0;
		iterate = 0;
		tmp_epsilon = crf_epsilon;

		LBFGS_index = 0;
		conv_time = 0;

		while (1) {
			if (CTRLC_PRESSED) {
				SHOW_PROGRESS_INTR();
				RET_ERR(err_ctrl_c_pressed);
			}

			RET_ON_ERR(crf_ptr->compute_feature());

			crf_ptr->compute_crf_probs();

			likelihood = crf_ptr->compute_likelihood();

			if (verb_em) {
				prism_printf("Iteration #%d:\tlog_likelihood=%.9f\n", iterate, likelihood);
			}

			if (debug_level) {
				prism_printf("After I-step[%d]:\n", iterate);
				prism_printf("likelihood = %.9f\n", likelihood);
				print_egraph(debug_level, PRINT_EM);
			}

			if (!isfinite(likelihood)) {
				emit_internal_error("invalid log likelihood: %s (at iteration #%d)",
				                    isnan(likelihood) ? "NaN" : "infinity", iterate);
				RET_ERR(ierr_invalid_likelihood);
			}
			/*        if (old_valid && old_likelihood - likelihood > prism_epsilon) {
					  emit_error("log likelihood decreased [old: %.9f, new: %.9f] (at iteration #%d)",
					  old_likelihood, likelihood, iterate);
					  RET_ERR(err_invalid_likelihood);
					  }*/
			if (likelihood > 0.0) {
				emit_error("log likelihood greater than zero [value: %.9f] (at iteration #%d)",
				           likelihood, iterate);
				RET_ERR(err_invalid_likelihood);
			}

			if (crf_learn_mode == 1 && iterate > 0) restore_old_gradient();

			RET_ON_ERR(crf_ptr->compute_gradient());

			if (crf_learn_mode == 1 && iterate > 0) {
				compute_LBFGS_y_rho();
				compute_hessian(iterate);
			} else if (crf_learn_mode == 1 && iterate == 0) {
				initialize_LBFGS_q();
			}

			converged = (old_valid && fabs(likelihood - old_likelihood) <= prism_epsilon);

			if (converged || REACHED_MAX_ITERATE(iterate)) {
				break;
			}

			old_likelihood = likelihood;
			old_valid = 1;

			if (debug_level) {
				prism_printf("After O-step[%d]:\n", iterate);
				print_egraph(debug_level, PRINT_EM);
			}

			SHOW_PROGRESS(iterate);

			if (crf_learning_rate == 1) { // annealing
				tmp_epsilon = (annealing_weight / (annealing_weight + iterate)) * crf_epsilon;
			} else if (crf_learning_rate == 2) { // line-search(backtrack)
				if (crf_learn_mode == 1) {
					gf_sd = compute_gf_sd_LBFGS();
				} else {
					gf_sd = compute_gf_sd();
				}
				if (iterate==0) {
					alpha0 = 1;
				} else {
					alpha0 = tmp_epsilon * old_gf_sd / gf_sd;
				}
				if (crf_learn_mode == 1) {
					tmp_epsilon = line_search_LBFGS(crf_ptr,alpha0,crf_ls_rho,crf_ls_c1,likelihood,gf_sd);
				} else {
					tmp_epsilon = line_search(crf_ptr,alpha0,crf_ls_rho,crf_ls_c1,likelihood,gf_sd);
				}

				if (tmp_epsilon < EPS) {
					emit_error("invalid alpha in line search(=0.0) (at iteration #%d)",iterate);
					RET_ERR(err_line_search);
				}
				old_gf_sd = gf_sd;
			} else if (crf_learning_rate == 3) { // line-search(golden section)
				if (crf_learn_mode == 1) {
					tmp_epsilon = golden_section_LBFGS(crf_ptr,0,crf_golden_b);
				} else {
					tmp_epsilon = golden_section(crf_ptr,0,crf_golden_b);
				}
			}
			crf_ptr->update_lambdas(tmp_epsilon);

			iterate++;
		}

		SHOW_PROGRESS_TAIL(converged, iterate, likelihood);

		if (r == 0 || likelihood > crf_ptr->likelihood) {
			crf_ptr->likelihood = likelihood;
			crf_ptr->iterate    = iterate;

			saved = (r < num_restart - 1);
			if (saved) {
				save_params();
			}
		}
	}

	if (crf_learn_mode == 1) clean_LBFGS();
	INIT_VISITED_FLAGS;
	return BP_TRUE;
}
Exemple #24
0
static Value *julia_to_native(Type *ty, jl_value_t *jt, Value *jv,
                              jl_value_t *aty, bool addressOf,
                              bool byRef, bool inReg,
                              bool needCopy,
                              int argn, jl_codectx_t *ctx,
                              bool *needStackRestore)
{
    Type *vt = jv->getType();

    // We're passing any
    if (ty == jl_pvalue_llvmt) {
        return boxed(jv,ctx);
    }
    if (ty == vt && !addressOf && !byRef) {
        return jv;
    }
    if (vt != jl_pvalue_llvmt) {
        // argument value is unboxed
        if (addressOf || (byRef && inReg)) {
            if (ty->isPointerTy() && ty->getContainedType(0)==vt) {
                // pass the address of an alloca'd thing, not a box
                // since those are immutable.
                *needStackRestore = true;
                Value *slot = builder.CreateAlloca(vt);
                builder.CreateStore(jv, slot);
                return builder.CreateBitCast(slot, ty);
            }
        }
        else if ((vt->isIntegerTy() && ty->isIntegerTy()) ||
                 (vt->isFloatingPointTy() && ty->isFloatingPointTy()) ||
                 (vt->isPointerTy() && ty->isPointerTy())) {
            if (vt->getPrimitiveSizeInBits() ==
                ty->getPrimitiveSizeInBits()) {
                if (!byRef) {
                    return builder.CreateBitCast(jv, ty);
                }
                else {
                    *needStackRestore = true;
                    Value *mem = builder.CreateAlloca(ty);
                    builder.CreateStore(jv,builder.CreateBitCast(mem,vt->getPointerTo()));
                    return mem;
                }
            }
        }
        else if (vt->isStructTy()) {
            if (!byRef) {
                return jv;
            }
            else {
                *needStackRestore = true;
                Value *mem = builder.CreateAlloca(vt);
                builder.CreateStore(jv,mem);
                return mem;
            }
        }

        emit_error("ccall: argument type did not match declaration", ctx);
    }
    if (jl_is_tuple(jt)) {
        return emit_unbox(ty,jv,jt);
    }
    if (jl_is_cpointer_type(jt) && addressOf) {
        assert(ty->isPointerTy());
        jl_value_t *ety = jl_tparam0(jt);
        if (aty != ety && ety != (jl_value_t*)jl_any_type && jt != (jl_value_t*)jl_voidpointer_type) {
            std::stringstream msg;
            msg << "ccall argument ";
            msg << argn;
            emit_typecheck(jv, ety, msg.str(), ctx);
        }
        if (jl_is_mutable_datatype(ety)) {
            // no copy, just reference the data field
            return builder.CreateBitCast(jv, ty);
        }
        else if (jl_is_immutable_datatype(ety) && jt != (jl_value_t*)jl_voidpointer_type) {
            // yes copy
            Value *nbytes;
            if (jl_is_leaf_type(ety))
                nbytes = ConstantInt::get(T_int32, jl_datatype_size(ety));
            else
                nbytes = tbaa_decorate(tbaa_datatype, builder.CreateLoad(
                                builder.CreateGEP(builder.CreatePointerCast(emit_typeof(jv), T_pint32),
                                    ConstantInt::get(T_size, offsetof(jl_datatype_t,size)/sizeof(int32_t))),
                                false));
            *needStackRestore = true;
            AllocaInst *ai = builder.CreateAlloca(T_int8, nbytes);
            ai->setAlignment(16);
            builder.CreateMemCpy(ai, builder.CreateBitCast(jv, T_pint8), nbytes, 1);
            return builder.CreateBitCast(ai, ty);
        }
        // emit maybe copy
        *needStackRestore = true;
        Value *jvt = emit_typeof(jv);
        BasicBlock *mutableBB = BasicBlock::Create(getGlobalContext(),"is-mutable",ctx->f);
        BasicBlock *immutableBB = BasicBlock::Create(getGlobalContext(),"is-immutable",ctx->f);
        BasicBlock *afterBB = BasicBlock::Create(getGlobalContext(),"after",ctx->f);
        Value *ismutable = builder.CreateTrunc(
                tbaa_decorate(tbaa_datatype, builder.CreateLoad(
                        builder.CreateGEP(builder.CreatePointerCast(jvt, T_pint8),
                            ConstantInt::get(T_size, offsetof(jl_datatype_t,mutabl))),
                        false)),
                T_int1);
        builder.CreateCondBr(ismutable, mutableBB, immutableBB);
        builder.SetInsertPoint(mutableBB);
        Value *p1 = builder.CreatePointerCast(jv, ty);
        builder.CreateBr(afterBB);
        builder.SetInsertPoint(immutableBB);
        Value *nbytes = tbaa_decorate(tbaa_datatype, builder.CreateLoad(
                    builder.CreateGEP(builder.CreatePointerCast(jvt, T_pint32),
                        ConstantInt::get(T_size, offsetof(jl_datatype_t,size)/sizeof(int32_t))),
                    false));
        AllocaInst *ai = builder.CreateAlloca(T_int8, nbytes);
        ai->setAlignment(16);
        builder.CreateMemCpy(ai, builder.CreatePointerCast(jv, T_pint8), nbytes, 1);
        Value *p2 = builder.CreatePointerCast(ai, ty);
        builder.CreateBr(afterBB);
        builder.SetInsertPoint(afterBB);
        PHINode *p = builder.CreatePHI(ty, 2);
        p->addIncoming(p1, mutableBB);
        p->addIncoming(p2, immutableBB);
        return p;
    }
    if (addressOf)
        jl_error("ccall: unexpected & on argument"); // the only "safe" thing to emit here is the expected struct
    assert(jl_is_datatype(jt));
    if (aty != jt) {
        std::stringstream msg;
        msg << "ccall argument ";
        msg << argn;
        emit_typecheck(jv, jt, msg.str(), ctx);
    }
    Value *p = data_pointer(jv);
    Value *pjv = builder.CreatePointerCast(p, PointerType::get(ty,0));
    if (byRef) {
        if (!needCopy) {
            return pjv;
        }
        else {
            *needStackRestore = true;
            Value *mem = builder.CreateAlloca(ty);
            builder.CreateMemCpy(mem,pjv,(uint64_t)jl_datatype_size(jt),(uint64_t)((jl_datatype_t*)jt)->alignment);
            return mem;
        }
    }
    else {
        return builder.CreateLoad(pjv,false);
    }
}
QVariant PythonScript::eval()
{
    if (!isFunction) compiled = notCompiled;
    if (compiled != isCompiled && !compile(true))
        return QVariant();

    PyObject *pyret;
    beginStdoutRedirect();
    if (PyCallable_Check(PyCode)) {
        PyObject *empty_tuple = PyTuple_New(0);
        pyret = PyObject_Call(PyCode, empty_tuple, localDict);
        Py_DECREF(empty_tuple);
    } else
        pyret = PyEval_EvalCode((PyCodeObject*)PyCode, env()->globalDict(), localDict);
    endStdoutRedirect();
    if (!pyret) {
        if (PyErr_ExceptionMatches(PyExc_ValueError) ||
                PyErr_ExceptionMatches(PyExc_ZeroDivisionError)) {
            PyErr_Clear(); // silently ignore errors
            return  QVariant("");
        } else {
            emit_error(env()->errorMsg(), 0);
            return QVariant();
        }
    }

    QVariant qret = QVariant();
    /* None */
    if (pyret == Py_None)
        qret = QVariant("");
    /* numeric types */
    else if (PyFloat_Check(pyret))
        qret = QVariant(PyFloat_AS_DOUBLE(pyret));
    else if (PyInt_Check(pyret))
        qret = QVariant((qlonglong)PyInt_AS_LONG(pyret));
    else if (PyLong_Check(pyret))
        qret = QVariant((qlonglong)PyLong_AsLongLong(pyret));
    else if (PyNumber_Check(pyret)) {
        PyObject *number = PyNumber_Float(pyret);
        if (number) {
            qret = QVariant(PyFloat_AS_DOUBLE(number));
            Py_DECREF(number);
        }
        /* bool */
    } else if (PyBool_Check(pyret))
        qret = QVariant(pyret==Py_True, 0);
    // could handle advanced types (such as PyList->QValueList) here if needed
    /* fallback: try to convert to (unicode) string */
    if(!qret.isValid()) {
        PyObject *pystring = PyObject_Unicode(pyret);
        if (pystring) {
            PyObject *asUTF8 = PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(pystring), PyUnicode_GET_DATA_SIZE(pystring), 0);
            Py_DECREF(pystring);
            if (asUTF8) {
                qret = QVariant(QString::fromUtf8(PyString_AS_STRING(asUTF8)));
                Py_DECREF(asUTF8);
            } else if (pystring = PyObject_Str(pyret)) {
                qret = QVariant(QString(PyString_AS_STRING(pystring)));
                Py_DECREF(pystring);
            }
        }
    }

    Py_DECREF(pyret);
    if (PyErr_Occurred()) {
        if (PyErr_ExceptionMatches(PyExc_ValueError) ||
                PyErr_ExceptionMatches(PyExc_ZeroDivisionError)) {
            PyErr_Clear(); // silently ignore errors
            return  QVariant("");
        } else {
            emit_error(env()->errorMsg(), 0);
            return QVariant();
        }
    } else
        return qret;
}
Exemple #26
0
// ccall(pointer, rettype, (argtypes...), args...)
static Value *emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
{
    JL_NARGSV(ccall, 3);
    jl_value_t *ptr=NULL, *rt=NULL, *at=NULL;
    Value *jl_ptr=NULL;
    JL_GC_PUSH(&ptr, &rt, &at);
    ptr = static_eval(args[1], ctx, true);
    if (ptr == NULL) {
        jl_value_t *ptr_ty = expr_type(args[1], ctx);
        Value *arg1 = emit_unboxed(args[1], ctx);
        if (!jl_is_cpointer_type(ptr_ty)) {
            emit_typecheck(arg1, (jl_value_t*)jl_voidpointer_type,
                           "ccall: function argument not a pointer or valid constant", ctx);
        }
        jl_ptr = emit_unbox(T_size, T_psize, arg1);
    }
    rt  = jl_interpret_toplevel_expr_in(ctx->module, args[2],
                                        &jl_tupleref(ctx->sp,0),
                                        jl_tuple_len(ctx->sp)/2);
    if (jl_is_tuple(rt)) {
        std::string msg = "in " + ctx->funcName +
            ": ccall: missing return type";
        jl_error(msg.c_str());
    }
    at  = jl_interpret_toplevel_expr_in(ctx->module, args[3],
                                        &jl_tupleref(ctx->sp,0),
                                        jl_tuple_len(ctx->sp)/2);
    void *fptr=NULL;
    char *f_name=NULL, *f_lib=NULL;
    if (ptr != NULL) {
        if (jl_is_tuple(ptr) && jl_tuple_len(ptr)==1) {
            ptr = jl_tupleref(ptr,0);
        }
        if (jl_is_symbol(ptr))
            f_name = ((jl_sym_t*)ptr)->name;
        else if (jl_is_byte_string(ptr))
            f_name = jl_string_data(ptr);
        if (f_name != NULL) {
            // just symbol, default to JuliaDLHandle
#ifdef __WIN32__
            fptr = jl_dlsym_e(jl_dl_handle, f_name);
            if (!fptr) {
                //TODO: when one of these succeeds, store the f_lib name (and clear fptr)
                fptr = jl_dlsym_e(jl_kernel32_handle, f_name);
                if (!fptr) {
                    fptr = jl_dlsym_e(jl_ntdll_handle, f_name);
                    if (!fptr) {
                        fptr = jl_dlsym_e(jl_crtdll_handle, f_name);
                        if (!fptr) {
                            fptr = jl_dlsym(jl_winsock_handle, f_name);
                        }
                    }
                }
            }
            else {
                // available in process symbol table
                fptr = NULL;
            }
#else
            // will look in process symbol table
#endif
        }
        else if (jl_is_cpointer_type(jl_typeof(ptr))) {
            fptr = *(void**)jl_bits_data(ptr);
        }
        else if (jl_is_tuple(ptr) && jl_tuple_len(ptr)>1) {
            jl_value_t *t0 = jl_tupleref(ptr,0);
            jl_value_t *t1 = jl_tupleref(ptr,1);
            if (jl_is_symbol(t0))
                f_name = ((jl_sym_t*)t0)->name;
            else if (jl_is_byte_string(t0))
                f_name = jl_string_data(t0);
            else
                JL_TYPECHK(ccall, symbol, t0);
            if (jl_is_symbol(t1))
                f_lib = ((jl_sym_t*)t1)->name;
            else if (jl_is_byte_string(t1))
                f_lib = jl_string_data(t1);
            else
                JL_TYPECHK(ccall, symbol, t1);
        }
        else {
            JL_TYPECHK(ccall, pointer, ptr);
        }
    }
    if (f_name == NULL && fptr == NULL && jl_ptr == NULL) {
        JL_GC_POP();
        emit_error("ccall: null function pointer", ctx);
        return literal_pointer_val(jl_nothing);
    }

    JL_TYPECHK(ccall, type, rt);
    JL_TYPECHK(ccall, tuple, at);
    JL_TYPECHK(ccall, type, at);
    jl_tuple_t *tt = (jl_tuple_t*)at;
    std::vector<Type *> fargt(0);
    std::vector<Type *> fargt_sig(0);
    Type *lrt = julia_type_to_llvm(rt);
    if (lrt == NULL) {
        JL_GC_POP();
        return literal_pointer_val(jl_nothing);
    }
    size_t i;
    bool haspointers = false;
    bool isVa = false;
    size_t nargt = jl_tuple_len(tt);
    std::vector<AttributeWithIndex> attrs;

    for(i=0; i < nargt; i++) {
        jl_value_t *tti = jl_tupleref(tt,i);
        if (jl_is_seq_type(tti)) {
            isVa = true;
            tti = jl_tparam0(tti);
        }
        if (jl_is_bits_type(tti)) {
            // see pull req #978. need to annotate signext/zeroext for
            // small integer arguments.
            jl_bits_type_t *bt = (jl_bits_type_t*)tti;
            if (bt->nbits < 32) {
                if (jl_signed_type == NULL) {
                    jl_signed_type = jl_get_global(jl_core_module,jl_symbol("Signed"));
                }
#ifdef LLVM32
                Attributes::AttrVal av;
                if (jl_signed_type && jl_subtype(tti, jl_signed_type, 0))
                    av = Attributes::SExt;
                else
                    av = Attributes::ZExt;
                attrs.push_back(AttributeWithIndex::get(getGlobalContext(), i+1,
                                                        ArrayRef<Attributes::AttrVal>(&av, 1)));
#else
                Attribute::AttrConst av;
                if (jl_signed_type && jl_subtype(tti, jl_signed_type, 0))
                    av = Attribute::SExt;
                else
                    av = Attribute::ZExt;
                attrs.push_back(AttributeWithIndex::get(i+1, av));
#endif
            }
        }
        Type *t = julia_type_to_llvm(tti);
        if (t == NULL) {
            JL_GC_POP();
            return literal_pointer_val(jl_nothing);
        }
        fargt.push_back(t);
        if (!isVa)
            fargt_sig.push_back(t);
    }
    // check for calling convention specifier
    CallingConv::ID cc = CallingConv::C;
    jl_value_t *last = args[nargs];
    if (jl_is_expr(last)) {
        jl_sym_t *lhd = ((jl_expr_t*)last)->head;
        if (lhd == jl_symbol("stdcall")) {
            cc = CallingConv::X86_StdCall;
            nargs--;
        }
        else if (lhd == jl_symbol("cdecl")) {
            cc = CallingConv::C;
            nargs--;
        }
        else if (lhd == jl_symbol("fastcall")) {
            cc = CallingConv::X86_FastCall;
            nargs--;
        }
        else if (lhd == jl_symbol("thiscall")) {
            cc = CallingConv::X86_ThisCall;
            nargs--;
        }
    }
    
    if ((!isVa && jl_tuple_len(tt)  != (nargs-2)/2) ||
        ( isVa && jl_tuple_len(tt)-1 > (nargs-2)/2))
        jl_error("ccall: wrong number of arguments to C function");

    // some special functions
    if (fptr == &jl_array_ptr) {
        Value *ary = emit_expr(args[4], ctx);
        JL_GC_POP();
        return mark_julia_type(builder.CreateBitCast(emit_arrayptr(ary),lrt),
                               rt);
    }

    // see if there are & arguments
    for(i=4; i < nargs+1; i+=2) {
        jl_value_t *argi = args[i];
        if (jl_is_expr(argi) && ((jl_expr_t*)argi)->head == amp_sym) {
            haspointers = true;
            break;
        }
    }

    // make LLVM function object for the target
    Value *llvmf;
    FunctionType *functype = FunctionType::get(lrt, fargt_sig, isVa);
    
    if (jl_ptr != NULL) {
        null_pointer_check(jl_ptr,ctx);
        Type *funcptype = PointerType::get(functype,0);
        llvmf = builder.CreateIntToPtr(jl_ptr, funcptype);
    } else if (fptr != NULL) {
        Type *funcptype = PointerType::get(functype,0);
        llvmf = literal_pointer_val(fptr, funcptype);
    }
    else {
        void *symaddr;
        if (f_lib != NULL)
            symaddr = add_library_sym(f_name, f_lib);
        else
            symaddr = sys::DynamicLibrary::SearchForAddressOfSymbol(f_name);
        if (symaddr == NULL) {
            JL_GC_POP();
            std::stringstream msg;
            msg << "ccall: could not find function ";
            msg << f_name;
            if (f_lib != NULL) {
                msg << " in library ";
                msg << f_lib;
            }
            emit_error(msg.str(), ctx);
            return literal_pointer_val(jl_nothing);
        }
        llvmf = jl_Module->getOrInsertFunction(f_name, functype);
    }

    // save temp argument area stack pointer
    Value *saveloc=NULL;
    Value *stacksave=NULL;
    if (haspointers) {
        // TODO: inline this
        saveloc = builder.CreateCall(save_arg_area_loc_func);
        stacksave =
            builder.CreateCall(Intrinsic::getDeclaration(jl_Module,
                                                         Intrinsic::stacksave));
    }

    // emit arguments
    Value *argvals[(nargs-3)/2];
    int last_depth = ctx->argDepth;
    int nargty = jl_tuple_len(tt);
    for(i=4; i < nargs+1; i+=2) {
        int ai = (i-4)/2;
        jl_value_t *argi = args[i];
        bool addressOf = false;
        if (jl_is_expr(argi) && ((jl_expr_t*)argi)->head == amp_sym) {
            addressOf = true;
            argi = jl_exprarg(argi,0);
        }
        Type *largty;
        jl_value_t *jargty;
        if (isVa && ai >= nargty-1) {
            largty = fargt[nargty-1];
            jargty = jl_tparam0(jl_tupleref(tt,nargty-1));
        }
        else {
            largty = fargt[ai];
            jargty = jl_tupleref(tt,ai);
        }
        Value *arg;
        if (largty == jl_pvalue_llvmt) {
            arg = emit_expr(argi, ctx, true);
        }
        else {
            arg = emit_unboxed(argi, ctx);
            if (jl_is_bits_type(expr_type(argi, ctx))) {
                if (addressOf)
                    arg = emit_unbox(largty->getContainedType(0), largty, arg);
                else
                    arg = emit_unbox(largty, PointerType::get(largty,0), arg);
            }
        }
        /*
#ifdef JL_GC_MARKSWEEP
        // make sure args are rooted
        if (largty->isPointerTy() &&
            (largty == jl_pvalue_llvmt ||
             !jl_is_bits_type(expr_type(args[i], ctx)))) {
            make_gcroot(boxed(arg), ctx);
        }
#endif
        */
        argvals[ai] = julia_to_native(largty, jargty, arg, argi, addressOf,
                                      ai+1, ctx);
    }
    // the actual call
    Value *result = builder.CreateCall(llvmf,
                                       ArrayRef<Value*>(&argvals[0],(nargs-3)/2));
    if (cc != CallingConv::C)
        ((CallInst*)result)->setCallingConv(cc);

#ifdef LLVM32
    ((CallInst*)result)->setAttributes(AttrListPtr::get(getGlobalContext(), ArrayRef<AttributeWithIndex>(attrs)));
#else
    ((CallInst*)result)->setAttributes(AttrListPtr::get(attrs.data(),attrs.size()));
#endif
    // restore temp argument area stack pointer
    if (haspointers) {
        assert(saveloc != NULL);
        builder.CreateCall(restore_arg_area_loc_func, saveloc);
        assert(stacksave != NULL);
        builder.CreateCall(Intrinsic::getDeclaration(jl_Module,
                                                     Intrinsic::stackrestore),
                           stacksave);
    }
    ctx->argDepth = last_depth;
    if (0) { // Enable this to turn on SSPREQ (-fstack-protector) on the function containing this ccall
#ifdef LLVM32        
        ctx->f->addFnAttr(Attributes::StackProtectReq);
#else
        ctx->f->addFnAttr(Attribute::StackProtectReq);
#endif
    }

    JL_GC_POP();
    if (lrt == T_void)
        return literal_pointer_val((jl_value_t*)jl_nothing);
    return mark_julia_type(result, rt);
}
Exemple #27
0
int mpm_run_em(EM_ENG_PTR emptr) {
	int     r, iterate, old_valid, converged, saved=0;
	double  likelihood, log_prior;
	double  lambda, old_lambda=0.0;

	config_em(emptr);

	for (r = 0; r < num_restart; r++) {
		SHOW_PROGRESS_HEAD("#em-iters", r);

		initialize_params();
		mpm_bcast_inside();
		clear_sw_msg_send();

		itemp = daem ? itemp_init : 1.0;
		iterate = 0;

		while (1) {
			if (daem) {
				SHOW_PROGRESS_TEMP(itemp);
			}
			old_valid = 0;

			while (1) {
				if (CTRLC_PRESSED) {
					SHOW_PROGRESS_INTR();
					RET_ERR(err_ctrl_c_pressed);
				}

				if (failure_observed) {
					inside_failure = mp_sum_value(0.0);
				}

				log_prior  = emptr->smooth ? emptr->compute_log_prior() : 0.0;
				lambda = mp_sum_value(log_prior);
				likelihood = lambda - log_prior;

				mp_debug("local lambda = %.9f, lambda = %.9f", log_prior, lambda);

				if (verb_em) {
					if (emptr->smooth) {
						prism_printf("Iteration #%d:\tlog_likelihood=%.9f\tlog_prior=%.9f\tlog_post=%.9f\n", iterate, likelihood, log_prior, lambda);
					} else {
						prism_printf("Iteration #%d:\tlog_likelihood=%.9f\n", iterate, likelihood);
					}
				}

				if (!isfinite(lambda)) {
					emit_internal_error("invalid log likelihood or log post: %s (at iterateion #%d)",
					                    isnan(lambda) ? "NaN" : "infinity", iterate);
					RET_ERR(ierr_invalid_likelihood);
				}
				if (old_valid && old_lambda - lambda > prism_epsilon) {
					emit_error("log likelihood or log post decreased [old: %.9f, new: %.9f] (at iteration #%d)",
					           old_lambda, lambda, iterate);
					RET_ERR(err_invalid_likelihood);
				}
				if (itemp == 1.0 && likelihood > 0.0) {
					emit_error("log likelihood greater than zero [value: %.9f] (at iteration #%d)",
					           likelihood, iterate);
					RET_ERR(err_invalid_likelihood);
				}

				converged = (old_valid && lambda - old_lambda <= prism_epsilon);
				if (converged || REACHED_MAX_ITERATE(iterate)) {
					break;
				}

				old_lambda = lambda;
				old_valid  = 1;

				mpm_share_expectation();

				SHOW_PROGRESS(iterate);
				RET_ON_ERR(emptr->update_params());
				iterate++;
			}

			if (itemp == 1.0) {
				break;
			}
			itemp *= itemp_rate;
			if (itemp >= 1.0) {
				itemp = 1.0;
			}
		}

		SHOW_PROGRESS_TAIL(converged, iterate, lambda);

		if (r == 0 || lambda > emptr->lambda) {
			emptr->lambda     = lambda;
			emptr->likelihood = likelihood;
			emptr->iterate    = iterate;

			saved = (r < num_restart - 1);
			if (saved) {
				save_params();
			}
		}
	}

	if (saved) {
		restore_params();
	}

	emptr->bic = compute_bic(emptr->likelihood);
	emptr->cs  = emptr->smooth ? compute_cs(emptr->likelihood) : 0.0;

	return BP_TRUE;
}