コード例 #1
0
ファイル: number.c プロジェクト: danielballan/numpy
/*
 * Convert the array to a scalar if allowed, and apply the builtin function
 * to it. The where argument is passed onto Py_EnterRecursiveCall when the
 * array contains python objects.
 */
NPY_NO_EXPORT PyObject *
array_scalar_forward(PyArrayObject *v,
                     PyObject *(*builtin_func)(PyObject *),
                     const char *where)
{
    PyObject *scalar;
    if (PyArray_SIZE(v) != 1) {
        PyErr_SetString(PyExc_TypeError, "only size-1 arrays can be"\
                        " converted to Python scalars");
        return NULL;
    }

    scalar = PyArray_GETITEM(v, PyArray_DATA(v));
    if (scalar == NULL) {
        return NULL;
    }

    /* Need to guard against recursion if our array holds references */
    if (PyDataType_REFCHK(PyArray_DESCR(v))) {
        PyObject *res;
        if (Npy_EnterRecursiveCall(where) != 0) {
            Py_DECREF(scalar);
            return NULL;
        }
        res = builtin_func(scalar);
        Py_DECREF(scalar);
        Py_LeaveRecursiveCall();
        return res;
    }
    else {
        PyObject *res;
        res = builtin_func(scalar);
        Py_DECREF(scalar);
        return res;
    }
}
コード例 #2
0
ファイル: zend-wrap-func.cpp プロジェクト: 409033632/hhvm
TypedValue* zend_wrap_func(
    ActRec* ar,
    zend_ext_func builtin_func,
    int numParams,
    bool isReturnRef) {
  TSRMLS_FETCH();

  // Prepare the arguments and return value before they are
  // exposed to the PHP extension
  zPrepArgs(ar);

  // Using Variant so exceptions will decref them
  Variant return_value_var(Variant::NullInit{});
  auto const return_value = return_value_var.asTypedValue();
  tvBox(return_value);

  Variant this_ptr_var(Variant::NullInit{});
  auto const this_ptr = this_ptr_var.asTypedValue();
  tvBox(this_ptr);

  if (ar->hasThis()) {
    tvWriteObject(
      ar->getThis(),
      this_ptr->m_data.pref->tv()
    );
  }

  auto *return_value_ptr = &return_value->m_data.pref;

  // Clear any stored exception
  ZendExceptionStore& exceptionStore = ZendExceptionStore::getInstance();
  exceptionStore.clear();

  // Invoke the PHP extension function/method
  ZendExecutionStack::pushHHVMStack();
  try {
    builtin_func(
      ar->numArgs(),
      return_value->m_data.pref,
      return_value_ptr,
      this_ptr_var.isNull() ? nullptr : this_ptr->m_data.pref,
      1
	  TSRMLS_CC
    );
  } catch (...) {
    ZendExecutionStack::popHHVMStack();
    throw;
  }
  ZendExecutionStack::popHHVMStack();

  // If an exception was caught, rethrow it
  if (!exceptionStore.empty()) {
    exceptionStore.rethrow();
  }

  // Take care of freeing the args, tearing down the ActRec,
  // and moving the return value to the right place
  frame_free_locals_inl(ar, numParams);
  memcpy(&ar->m_r, return_value, sizeof(TypedValue));
  return_value->m_type = KindOfNull;
  if (isReturnRef) {
    if (!ar->m_r.m_data.pref->isReferenced()) {
      tvUnbox(&ar->m_r);
    }
  } else {
    tvUnbox(&ar->m_r);
  }

  return &ar->m_r;
}