update
This commit is contained in:
parent
bff5c6b8dc
commit
aaf11592c7
|
@ -306,7 +306,7 @@ namespace php_arma
|
|||
return nullptr;
|
||||
}
|
||||
if (UNEXPECTED(type != BP_VAR_R)) {
|
||||
zend_throw_exception_ex(zend_ce_exception, -2,
|
||||
zend_throw_exception_ex(zend_ce_exception, 0,
|
||||
"Numeric offset of class %s is read-only", Z_OBJNAME_P(obj));
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ namespace php_arma
|
|||
return OBJ_PROP_NUM(zobj, idx);
|
||||
}
|
||||
|
||||
zend_throw_exception_ex(zend_ce_exception, -2,
|
||||
zend_throw_exception_ex(zend_ce_exception, 0,
|
||||
"Bad offset for %s, expected 0 or 1, %ld given.", Z_OBJNAME_P(obj), idx);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -327,7 +327,7 @@ namespace php_arma
|
|||
{
|
||||
// Theoretically we won't get non-string values here, add type check just in case.
|
||||
if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) {
|
||||
zend_throw_exception(zend_ce_error, "Unexpected error. Please contact developer.", -2);
|
||||
zend_throw_exception(zend_ce_error, "Unexpected error. Please contact developer.", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -343,7 +343,7 @@ namespace php_arma
|
|||
return;
|
||||
}
|
||||
|
||||
zend_throw_exception_ex(zend_ce_exception, -2,
|
||||
zend_throw_exception_ex(zend_ce_exception, 0,
|
||||
"Bad property name for %s, expected 'real' or 'imag', '%s' given.", Z_OBJNAME_P(obj), Z_STRVAL_P(member));
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace php_arma
|
|||
{
|
||||
template <typename... Ts>
|
||||
zend_always_inline
|
||||
void const_declare(zend_class_entry *ce, Ts... constants)
|
||||
void const_declare(zend_class_entry *ce, Ts&&... constants)
|
||||
{
|
||||
for (auto [name, val] : { constants... }) {
|
||||
zend_declare_class_constant_long(ce, name, strlen(name), val);
|
||||
|
|
|
@ -23,12 +23,19 @@ namespace php_arma
|
|||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
auto native = to_native_object<native_t>(Z_OBJ_P(getThis()));
|
||||
|
||||
zend_object *zobj;
|
||||
if (EX_NUM_ARGS() == 1) {
|
||||
zobj = mapval_dense<T>::create(&native->operator()(i));
|
||||
} else {
|
||||
zobj = mapval_dense<T>::create(&native->operator()(i, j));
|
||||
try {
|
||||
if (EX_NUM_ARGS() == 1) {
|
||||
zobj = mapval_dense<T>::create(&native->operator()(i));
|
||||
} else {
|
||||
zobj = mapval_dense<T>::create(&native->operator()(i, j));
|
||||
}
|
||||
} catch (std::logic_error& err) {
|
||||
zend_throw_exception(zend_ce_exception, "index out of bounds", 0);
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
RETVAL_OBJ(zobj);
|
||||
}
|
||||
|
||||
|
|
24
src/mat.cc
24
src/mat.cc
|
@ -26,7 +26,13 @@ namespace php_arma
|
|||
template <typename T>
|
||||
PHP_ARMA_METHOD(mat, fromString, T)
|
||||
{
|
||||
|
||||
zend_string *text;
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_STR_DEREF(text)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
auto zobj = create(ZSTR_VAL(text));
|
||||
RETVAL_OBJ(zobj);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -39,20 +45,20 @@ namespace php_arma
|
|||
void mat<T>::ce_init(zend_class_entry *parent_ce)
|
||||
{
|
||||
ce = class_register<php_name::val>(parent_ce, fentry_list_concat(
|
||||
PHP_ARMA_FENTRY((base<T, mat<T>>::me)),
|
||||
PHP_ARMA_FENTRY((dense<T, mat<T>>::me)),
|
||||
PHP_ARMA_FENTRY((matrix<T, mat<T>>::me)),
|
||||
PHP_ARMA_FENTRY((dense_matrix<T, mat<T>>::me)),
|
||||
PHP_ARMA_FENTRY((resizable<T, mat<T>>::me)),
|
||||
PHP_ARMA_FENTRY((resizable_matrix<T, mat<T>>::me)),
|
||||
PHP_ARMA_FENTRY((dense_resizable_matrix<T, mat<T>>::me)),
|
||||
PHP_ARMA_FENTRY((base <T, mat>::me)),
|
||||
PHP_ARMA_FENTRY((dense <T, mat>::me)),
|
||||
PHP_ARMA_FENTRY((matrix <T, mat>::me)),
|
||||
PHP_ARMA_FENTRY((dense_matrix <T, mat>::me)),
|
||||
PHP_ARMA_FENTRY((resizable <T, mat>::me)),
|
||||
PHP_ARMA_FENTRY((resizable_matrix <T, mat>::me)),
|
||||
PHP_ARMA_FENTRY((dense_resizable_matrix<T, mat>::me)),
|
||||
PHP_ARMA_FENTRY(me)
|
||||
));
|
||||
ce->create_object = object_non_constructible;
|
||||
object_handlers_init(&handlers);
|
||||
handlers.offset = sizeof(native_t);
|
||||
handlers.clone_obj = nullptr;
|
||||
|
||||
handlers.dtor_obj = object_destroy<native_t>;
|
||||
}
|
||||
|
||||
PHP_ARMA_NAME_DECLARE(mat, "DMat", double);
|
||||
|
|
|
@ -26,6 +26,13 @@ namespace php_arma
|
|||
|
||||
friend void mat_init();
|
||||
|
||||
template <typename... Ts>
|
||||
zend_always_inline
|
||||
static zend_object *create(Ts&&... args)
|
||||
{
|
||||
return object_create_ctor<native_t>(ce, &handlers, args...);
|
||||
}
|
||||
|
||||
PHP_ARMA_CE_HANDLRES_DECLARE();
|
||||
|
||||
private:
|
||||
|
|
|
@ -201,7 +201,7 @@ namespace php_arma
|
|||
|
||||
template <typename... Ts>
|
||||
zend_always_inline
|
||||
void set_op_handlers(Ts... op_handlers)
|
||||
void set_op_handlers(Ts&&... op_handlers)
|
||||
{
|
||||
for (auto [opcode, handler] : { op_handlers... }) {
|
||||
zend_set_user_opcode_handler(opcode, handler);
|
||||
|
|
|
@ -78,10 +78,13 @@
|
|||
Z_PARAM_DOUBLE_EX2(dest, _dummy, 0, 1, 0)
|
||||
#define Z_PARAM_LONG_DEREF(dest) \
|
||||
Z_PARAM_LONG_EX2(dest, _dummy, 0, 1, 0)
|
||||
#define Z_PARAM_STR_DEREF(dest) \
|
||||
Z_PARAM_STR_EX2(dest, 0, 1, 0)
|
||||
#else
|
||||
// Before PHP 7.2, parameter is dereferenced by default here.
|
||||
#define Z_PARAM_DOUBLE_DEREF Z_PARAM_DOUBLE
|
||||
#define Z_PARAM_LONG_DEREF Z_PARAM_LONG
|
||||
#define Z_PARAM_STR_DEREF Z_PARAM_STR
|
||||
#endif
|
||||
|
||||
#ifdef PHP_ARMA_OPERATORS
|
||||
|
@ -122,7 +125,7 @@ namespace php_arma
|
|||
template <const char*, typename, const char*, typename>
|
||||
struct concat_impl;
|
||||
|
||||
template <const char* Str1, size_t... Len1, const char* Str2, size_t... Len2>
|
||||
template <const char *Str1, size_t... Len1, const char *Str2, size_t... Len2>
|
||||
struct concat_impl<Str1, seq<Len1...>, Str2, seq<Len2...>>
|
||||
{
|
||||
static constexpr const char value[]
|
||||
|
@ -251,13 +254,13 @@ namespace php_arma
|
|||
|
||||
template <typename... Ts>
|
||||
zend_always_inline
|
||||
zend_function_entry *fentry_list_concat_impl(size_t mem_size, Ts... function_entry)
|
||||
zend_function_entry *fentry_list_concat_impl(size_t mem_size, Ts&&... function_entry)
|
||||
{
|
||||
auto retval = reinterpret_cast<zend_function_entry*>(malloc(mem_size));
|
||||
size_t offset = 0;
|
||||
for (auto [size, fentry] : { function_entry... }) {
|
||||
memcpy(retval + offset, fentry, size);
|
||||
++offset;
|
||||
offset += size / sizeof(zend_function_entry);
|
||||
}
|
||||
zend_function_entry empty_fentry PHP_FE_END;
|
||||
memcpy(retval + offset, &empty_fentry, sizeof(zend_function_entry));
|
||||
|
@ -266,7 +269,7 @@ namespace php_arma
|
|||
|
||||
template <typename... Ts>
|
||||
zend_always_inline
|
||||
zend_function_entry *fentry_list_concat(Ts... function_entry)
|
||||
zend_function_entry *fentry_list_concat(Ts&&... function_entry)
|
||||
{
|
||||
size_t mem_size = sizeof(zend_function_entry);
|
||||
for (auto [size, _] : { function_entry... }) {
|
||||
|
@ -288,6 +291,19 @@ namespace php_arma
|
|||
return zobj;
|
||||
}
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
zend_always_inline
|
||||
zend_object *object_create_ctor(zend_class_entry *ce, zend_object_handlers *handlers, Ts&&... args)
|
||||
{
|
||||
// If only I can use C++20 here...
|
||||
return object_create<T>(ce, [args = std::forward_as_tuple(args...), handlers](auto obj) {
|
||||
std::apply([obj](auto&&... args) {
|
||||
new(obj) T(args...);
|
||||
}, std::move(args));
|
||||
return handlers;
|
||||
});
|
||||
}
|
||||
|
||||
zend_always_inline
|
||||
zend_object *object_create(zend_class_entry *ce, const zend_object_handlers *handlers)
|
||||
{
|
||||
|
@ -299,6 +315,14 @@ namespace php_arma
|
|||
return zobj;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
zend_always_inline
|
||||
void object_destroy(zend_object *zobj)
|
||||
{
|
||||
zend_object_std_dtor(zobj);
|
||||
to_native_object<T>(zobj)->~T();
|
||||
}
|
||||
|
||||
zend_always_inline
|
||||
void object_set_property(zend_object *obj, size_t idx, zval *val)
|
||||
{
|
||||
|
@ -309,7 +333,7 @@ namespace php_arma
|
|||
zend_always_inline
|
||||
zend_object *object_non_constructible(zend_class_entry *ce)
|
||||
{
|
||||
zend_throw_exception_ex(zend_ce_error, -3,
|
||||
zend_throw_exception_ex(zend_ce_error, 0,
|
||||
"Class %s is not explicitly constructible.", ZSTR_VAL(ce->name));
|
||||
return zend_objects_new(ce);
|
||||
}
|
||||
|
@ -416,7 +440,7 @@ namespace php_arma
|
|||
zend_always_inline
|
||||
void ex_bad_type(const char *expected, const char *got)
|
||||
{
|
||||
zend_throw_exception_ex(zend_ce_type_error, -1, "Bad type, expected %s, %s given.", expected, got);
|
||||
zend_throw_exception_ex(zend_ce_type_error, 0, "Bad type, expected %s, %s given.", expected, got);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
|
Reference in New Issue