-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 682bbe0
Showing
10 changed files
with
386 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
*.lo | ||
*.la | ||
.libs | ||
acinclude.m4 | ||
aclocal.m4 | ||
autom4te.cache | ||
build | ||
config.guess | ||
config.h | ||
config.h.in | ||
config.log | ||
config.nice | ||
config.status | ||
config.sub | ||
configure | ||
configure.ac | ||
configure.in | ||
include | ||
install-sh | ||
libtool | ||
ltmain.sh | ||
Makefile | ||
Makefile.fragments | ||
Makefile.global | ||
Makefile.objects | ||
missing | ||
mkinstalldirs | ||
modules | ||
run-tests.php | ||
tests/*/*.diff | ||
tests/*/*.out | ||
tests/*/*.php | ||
tests/*/*.exp | ||
tests/*/*.log | ||
tests/*/*.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
cereal | ||
Sammy Kaye Powers <[email protected]> |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
/* cereal extension for PHP (c) 2020 Sammy Kaye Powers <[email protected]> */ | ||
|
||
#ifdef HAVE_CONFIG_H | ||
# include "config.h" | ||
#endif | ||
|
||
#include "php.h" | ||
#include "ext/standard/info.h" | ||
#include "php_cereal.h" | ||
#include "cereal_arginfo.h" | ||
|
||
#define CEREAL_ARENA_SIZE 1024 // TODO Figure out how much we need | ||
|
||
ZEND_DECLARE_MODULE_GLOBALS(cereal) | ||
|
||
typedef struct cereal_obj { | ||
zend_object *obj; | ||
struct cereal_obj *prev; | ||
} cereal_obj; | ||
|
||
ZEND_TLS cereal_obj *cereals; | ||
ZEND_TLS zend_arena *cereal_arena; | ||
|
||
zend_class_entry *cereal_ce_ptr; | ||
|
||
static zend_object *_cereal_obj_create(zend_class_entry *ce) | ||
{ | ||
zend_object *obj; | ||
cereal_obj *c; | ||
|
||
if (CEREAL_G(use_arena) == 1) { | ||
obj = zend_arena_calloc(&cereal_arena, 1, sizeof(zend_object) + zend_object_properties_size(ce)); | ||
zend_object_std_init(obj, ce); | ||
object_properties_init(obj, ce); | ||
obj->handlers = &std_object_handlers; | ||
c = zend_arena_calloc(&cereal_arena, 1, sizeof(cereal_obj)); | ||
} else { | ||
obj = zend_objects_new(ce); | ||
object_properties_init(obj, ce); | ||
c = (cereal_obj *) ecalloc(1, sizeof(cereal_obj)); | ||
} | ||
|
||
c->obj = obj; | ||
c->prev = cereals; | ||
cereals = c; | ||
|
||
GC_ADDREF(obj); | ||
|
||
return obj; | ||
} | ||
|
||
static void php_cereal_init_globals(zend_cereal_globals *cereal_globals) | ||
{ | ||
cereal_globals->use_arena = 0; | ||
} | ||
|
||
/* For compatibility with older PHP versions */ | ||
#ifndef ZEND_PARSE_PARAMETERS_NONE | ||
#define ZEND_PARSE_PARAMETERS_NONE() \ | ||
ZEND_PARSE_PARAMETERS_START(0, 0) \ | ||
ZEND_PARSE_PARAMETERS_END() | ||
#endif | ||
|
||
PHP_FUNCTION(get_cereal) | ||
{ | ||
ZEND_PARSE_PARAMETERS_NONE(); | ||
|
||
ZVAL_OBJ(return_value, cereal_ce_ptr->create_object(cereal_ce_ptr)); | ||
} | ||
|
||
PHP_INI_BEGIN() | ||
STD_PHP_INI_BOOLEAN("cereal.use_arena", "0", PHP_INI_SYSTEM, OnUpdateBool, use_arena, zend_cereal_globals, cereal_globals) | ||
PHP_INI_END() | ||
|
||
static PHP_MINIT_FUNCTION(cereal) | ||
{ | ||
#if defined(ZTS) && defined(COMPILE_DL_CEREAL) | ||
ZEND_TSRMLS_CACHE_UPDATE(); | ||
#endif | ||
ZEND_INIT_MODULE_GLOBALS(cereal, php_cereal_init_globals, NULL); | ||
REGISTER_INI_ENTRIES(); | ||
|
||
zend_class_entry _ce; | ||
INIT_CLASS_ENTRY(_ce, "Cereal", class_Cereal_methods); | ||
_ce.create_object = _cereal_obj_create; | ||
cereal_ce_ptr = zend_register_internal_class_ex(&_ce, NULL); | ||
cereal_ce_ptr->ce_flags |= ZEND_ACC_FINAL; | ||
zend_declare_property_string(cereal_ce_ptr, ZEND_STRL("name"), "", ZEND_ACC_PUBLIC); | ||
zend_declare_property_string(cereal_ce_ptr, ZEND_STRL("milk"), "", ZEND_ACC_PUBLIC); | ||
|
||
return SUCCESS; | ||
} | ||
|
||
static PHP_MSHUTDOWN_FUNCTION(cereal) | ||
{ | ||
return SUCCESS; | ||
} | ||
|
||
static PHP_RINIT_FUNCTION(cereal) | ||
{ | ||
cereals = NULL; | ||
if (CEREAL_G(use_arena) == 1) { | ||
cereal_arena = zend_arena_create(CEREAL_ARENA_SIZE); | ||
} | ||
|
||
return SUCCESS; | ||
} | ||
|
||
static PHP_RSHUTDOWN_FUNCTION(cereal) | ||
{ | ||
if (CEREAL_G(use_arena) == 1) { | ||
php_printf("Freeing arena (%p)\n", cereal_arena); | ||
zend_arena_destroy(cereal_arena); | ||
cereal_arena = NULL; | ||
} else { | ||
cereal_obj *c = cereals; | ||
cereal_obj *tmp; | ||
|
||
while (c) { | ||
tmp = c->prev; | ||
php_printf("Freeing cereal #%lu (%p)\n", (unsigned long) c->obj->handle, c); | ||
GC_DELREF(c->obj); | ||
zend_object_std_dtor(c->obj); | ||
efree(c); | ||
c = tmp; | ||
} | ||
cereals = NULL; | ||
} | ||
|
||
return SUCCESS; | ||
} | ||
|
||
static PHP_MINFO_FUNCTION(cereal) | ||
{ | ||
php_info_print_table_start(); | ||
php_info_print_table_header(2, "cereal support", "enabled"); | ||
php_info_print_table_end(); | ||
|
||
DISPLAY_INI_ENTRIES(); | ||
} | ||
|
||
zend_module_entry cereal_module_entry = { | ||
STANDARD_MODULE_HEADER, | ||
"cereal", /* Extension name */ | ||
ext_functions, /* zend_function_entry */ | ||
PHP_MINIT(cereal), /* PHP_MINIT - Module initialization */ | ||
PHP_MSHUTDOWN(cereal), /* PHP_MSHUTDOWN - Module shutdown */ | ||
PHP_RINIT(cereal), /* PHP_RINIT - Request initialization */ | ||
PHP_RSHUTDOWN(cereal), /* PHP_RSHUTDOWN - Request shutdown */ | ||
PHP_MINFO(cereal), /* PHP_MINFO - Module info */ | ||
PHP_CEREAL_VERSION, /* Version */ | ||
STANDARD_MODULE_PROPERTIES | ||
}; | ||
|
||
#ifdef COMPILE_DL_CEREAL | ||
# ifdef ZTS | ||
ZEND_TSRMLS_CACHE_DEFINE() | ||
# endif | ||
ZEND_GET_MODULE(cereal) | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?php | ||
|
||
/** @generate-function-entries */ | ||
|
||
/** | ||
* @property string $name The name of the cereal | ||
* @property string $milk The type of the milk | ||
*/ | ||
class Cereal {} | ||
|
||
function get_cereal(): Cereal {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* This is a generated file, edit the .stub.php file instead. */ | ||
|
||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_get_cereal, 0, 0, Cereal, 0) | ||
ZEND_END_ARG_INFO() | ||
|
||
|
||
ZEND_FUNCTION(get_cereal); | ||
|
||
|
||
static const zend_function_entry ext_functions[] = { | ||
ZEND_FE(get_cereal, arginfo_get_cereal) | ||
ZEND_FE_END | ||
}; | ||
|
||
|
||
static const zend_function_entry class_Cereal_methods[] = { | ||
ZEND_FE_END | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
PHP_ARG_ENABLE([cereal], | ||
[whether to enable cereal support], | ||
[AS_HELP_STRING([--enable-cereal], | ||
[Enable cereal support])], | ||
[no]) | ||
|
||
if test "$PHP_CEREAL" != "no"; then | ||
AC_DEFINE(HAVE_CEREAL, 1, [ Have cereal support ]) | ||
PHP_NEW_EXTENSION(cereal, cereal.c, $ext_shared) | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* cereal extension for PHP (c) 2020 Sammy Kaye Powers <[email protected]> */ | ||
|
||
#ifndef PHP_CEREAL_H | ||
# define PHP_CEREAL_H | ||
|
||
extern zend_module_entry cereal_module_entry; | ||
# define phpext_cereal_ptr &cereal_module_entry | ||
|
||
# define PHP_CEREAL_VERSION "0.1.0" | ||
|
||
# if defined(ZTS) && defined(COMPILE_DL_CEREAL) | ||
ZEND_TSRMLS_CACHE_EXTERN() | ||
# endif | ||
|
||
ZEND_BEGIN_MODULE_GLOBALS(cereal) | ||
int use_arena; | ||
ZEND_END_MODULE_GLOBALS(cereal) | ||
|
||
#ifdef ZTS | ||
#define CEREAL_G(v) TSRMG(cereal_globals_id, zend_cereal_globals *, v) | ||
#else | ||
#define CEREAL_G(v) (cereal_globals.v) | ||
#endif | ||
|
||
#endif /* PHP_CEREAL_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
--TEST-- | ||
Test non-arena functionality | ||
--SKIPIF-- | ||
<?php if (!extension_loaded('cereal')) die('skip: cereal extension required'); ?> | ||
--INI-- | ||
cereal.use_arena=0 | ||
--FILE-- | ||
<?php | ||
echo 'Where are my Lucky Charms?' . PHP_EOL; | ||
$cereal = new Cereal(); | ||
$cereal->name = 'Lucky Charms'; | ||
var_dump($cereal); | ||
|
||
$cereal2 = get_cereal(); | ||
$cereal2->name = 'Cinnamon Toast Crunch'; | ||
$cereal2->milk = 'almond'; | ||
var_dump($cereal2); | ||
|
||
function userlandCereals() { | ||
foreach (range(0, 3) as $i) { | ||
$c = new Cereal(); | ||
echo 'Made userland cereal #' . spl_object_id($c) . PHP_EOL; | ||
} | ||
} | ||
|
||
function internalCereals() { | ||
foreach (range(0, 3) as $i) { | ||
$c = get_cereal(); | ||
echo 'Made internal cereal #' . spl_object_id($c) . PHP_EOL; | ||
} | ||
} | ||
|
||
userlandCereals(); | ||
internalCereals(); | ||
?> | ||
--EXPECTF-- | ||
Where are my Lucky Charms? | ||
object(Cereal)#1 (2) { | ||
["name"]=> | ||
string(12) "Lucky Charms" | ||
["milk"]=> | ||
string(0) "" | ||
} | ||
object(Cereal)#2 (2) { | ||
["name"]=> | ||
string(21) "Cinnamon Toast Crunch" | ||
["milk"]=> | ||
string(6) "almond" | ||
} | ||
Made userland cereal #3 | ||
Made userland cereal #4 | ||
Made userland cereal #5 | ||
Made userland cereal #6 | ||
Made internal cereal #7 | ||
Made internal cereal #8 | ||
Made internal cereal #9 | ||
Made internal cereal #10 | ||
Freeing cereal #10 (%s) | ||
Freeing cereal #9 (%s) | ||
Freeing cereal #8 (%s) | ||
Freeing cereal #7 (%s) | ||
Freeing cereal #6 (%s) | ||
Freeing cereal #5 (%s) | ||
Freeing cereal #4 (%s) | ||
Freeing cereal #3 (%s) | ||
Freeing cereal #2 (%s) | ||
Freeing cereal #1 (%s) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
--TEST-- | ||
Test arena functionality | ||
--SKIPIF-- | ||
<?php if (!extension_loaded('cereal')) die('skip: cereal extension required'); ?> | ||
--INI-- | ||
cereal.use_arena=1 | ||
--FILE-- | ||
<?php | ||
echo 'Where are my Lucky Charms?' . PHP_EOL; | ||
$cereal = new Cereal(); | ||
$cereal->name = 'Lucky Charms'; | ||
var_dump($cereal); | ||
|
||
$cereal2 = get_cereal(); | ||
$cereal2->name = 'Cinnamon Toast Crunch'; | ||
$cereal2->milk = 'almond'; | ||
var_dump($cereal2); | ||
|
||
function userlandCereals() { | ||
foreach (range(0, 3) as $i) { | ||
$c = new Cereal(); | ||
echo 'Made userland cereal #' . spl_object_id($c) . PHP_EOL; | ||
} | ||
} | ||
|
||
function internalCereals() { | ||
foreach (range(0, 3) as $i) { | ||
$c = get_cereal(); | ||
echo 'Made internal cereal #' . spl_object_id($c) . PHP_EOL; | ||
} | ||
} | ||
|
||
userlandCereals(); | ||
internalCereals(); | ||
?> | ||
--EXPECTF-- | ||
Where are my Lucky Charms? | ||
object(Cereal)#1 (2) { | ||
["name"]=> | ||
string(12) "Lucky Charms" | ||
["milk"]=> | ||
string(0) "" | ||
} | ||
object(Cereal)#2 (2) { | ||
["name"]=> | ||
string(21) "Cinnamon Toast Crunch" | ||
["milk"]=> | ||
string(6) "almond" | ||
} | ||
Made userland cereal #3 | ||
Made userland cereal #4 | ||
Made userland cereal #5 | ||
Made userland cereal #6 | ||
Made internal cereal #7 | ||
Made internal cereal #8 | ||
Made internal cereal #9 | ||
Made internal cereal #10 | ||
Freeing arena (%s) |