This commit is contained in:
CismonX 2019-05-26 12:39:35 +08:00
parent bff5c6b8dc
commit aaf11592c7
7 changed files with 69 additions and 25 deletions

View File

@ -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));
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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:

View File

@ -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);

View File

@ -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>