mirror of
https://github.com/php/frankenphp.git
synced 2026-03-24 00:52:11 +01:00
fix: improve generated C extension code (#1698)
This commit is contained in:
committed by
GitHub
parent
291dd4eed9
commit
58fde42654
@@ -44,11 +44,6 @@ func TestHeaderGenerator_BuildContent(t *testing.T) {
|
||||
"#define _SIMPLE_H",
|
||||
"#include <php.h>",
|
||||
"extern zend_module_entry ext_module_entry;",
|
||||
"typedef struct go_value go_value;",
|
||||
"typedef struct go_string {",
|
||||
"size_t len;",
|
||||
"char *data;",
|
||||
"} go_string;",
|
||||
"#endif",
|
||||
},
|
||||
},
|
||||
@@ -134,11 +129,6 @@ func TestHeaderGenerator_BasicStructure(t *testing.T) {
|
||||
expectedElements := []string{
|
||||
"#include <php.h>",
|
||||
"extern zend_module_entry ext_module_entry;",
|
||||
"typedef struct go_value go_value;",
|
||||
"typedef struct go_string {",
|
||||
"size_t len;",
|
||||
"char *data;",
|
||||
"} go_string;",
|
||||
}
|
||||
|
||||
for _, element := range expectedElements {
|
||||
@@ -209,9 +199,6 @@ func TestHeaderGenerator_ContentValidation(t *testing.T) {
|
||||
assert.Equal(t, 1, strings.Count(content, "#define"), "Header should have exactly one #define")
|
||||
assert.Equal(t, 1, strings.Count(content, "#endif"), "Header should have exactly one #endif")
|
||||
assert.False(t, strings.Contains(content, "{{") || strings.Contains(content, "}}"), "Generated header contains unresolved template syntax")
|
||||
assert.Contains(t, content, "typedef struct go_string {", "Header should contain go_string typedef")
|
||||
assert.Contains(t, content, "size_t len;", "Header should contain len field in go_string")
|
||||
assert.Contains(t, content, "char *data;", "Header should contain data field in go_string")
|
||||
}
|
||||
|
||||
func TestHeaderGenerator_SpecialCharacterHandling(t *testing.T) {
|
||||
@@ -278,7 +265,6 @@ func TestHeaderGenerator_MinimalContent(t *testing.T) {
|
||||
"#define _MINIMAL_H",
|
||||
"#include <php.h>",
|
||||
"extern zend_module_entry ext_module_entry;",
|
||||
"typedef struct go_value go_value;",
|
||||
"#endif",
|
||||
}
|
||||
|
||||
@@ -302,11 +288,6 @@ func testHeaderBasicStructure(t *testing.T, content, baseName string) {
|
||||
"#define _" + headerGuard,
|
||||
"#include <php.h>",
|
||||
"extern zend_module_entry ext_module_entry;",
|
||||
"typedef struct go_value go_value;",
|
||||
"typedef struct go_string {",
|
||||
"size_t len;",
|
||||
"char *data;",
|
||||
"} go_string;",
|
||||
"#endif",
|
||||
}
|
||||
|
||||
|
||||
@@ -8,12 +8,19 @@
|
||||
|
||||
{{- if .Classes}}
|
||||
|
||||
#define VALIDATE_GO_HANDLE(intern) \
|
||||
do { \
|
||||
if ((intern)->go_handle == 0) { \
|
||||
zend_throw_error(NULL, "Go object not found in registry"); \
|
||||
RETURN_THROWS(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static zend_object_handlers object_handlers_{{.BaseName}};
|
||||
|
||||
typedef struct {
|
||||
uintptr_t go_handle;
|
||||
char* class_name;
|
||||
zend_object std; /* This MUST be the last struct field to memory alignement problems */
|
||||
zend_object std; /* This must be the last field in the structure: the property store starts at this offset */
|
||||
} {{.BaseName}}_object;
|
||||
|
||||
static inline {{.BaseName}}_object *{{.BaseName}}_object_from_obj(zend_object *obj) {
|
||||
@@ -28,18 +35,13 @@ static zend_object *{{.BaseName}}_create_object(zend_class_entry *ce) {
|
||||
|
||||
intern->std.handlers = &object_handlers_{{.BaseName}};
|
||||
intern->go_handle = 0; /* will be set in __construct */
|
||||
intern->class_name = estrdup(ZSTR_VAL(ce->name));
|
||||
|
||||
|
||||
return &intern->std;
|
||||
}
|
||||
|
||||
static void {{.BaseName}}_free_object(zend_object *object) {
|
||||
{{.BaseName}}_object *intern = {{.BaseName}}_object_from_obj(object);
|
||||
|
||||
if (intern->class_name) {
|
||||
efree(intern->class_name);
|
||||
}
|
||||
|
||||
|
||||
if (intern->go_handle != 0) {
|
||||
removeGoObject(intern->go_handle);
|
||||
}
|
||||
@@ -47,14 +49,10 @@ static void {{.BaseName}}_free_object(zend_object *object) {
|
||||
zend_object_std_dtor(&intern->std);
|
||||
}
|
||||
|
||||
static zend_function *{{.BaseName}}_get_method(zend_object **object, zend_string *method, const zval *key) {
|
||||
return zend_std_get_method(object, method, key);
|
||||
}
|
||||
|
||||
void init_object_handlers() {
|
||||
memcpy(&object_handlers_{{.BaseName}}, &std_object_handlers, sizeof(zend_object_handlers));
|
||||
object_handlers_{{.BaseName}}.get_method = {{.BaseName}}_get_method;
|
||||
object_handlers_{{.BaseName}}.free_obj = {{.BaseName}}_free_object;
|
||||
object_handlers_{{.BaseName}}.clone_obj = NULL;
|
||||
object_handlers_{{.BaseName}}.offset = offsetof({{.BaseName}}_object, std);
|
||||
}
|
||||
{{- end}}
|
||||
@@ -67,7 +65,12 @@ PHP_METHOD({{.Name}}, __construct) {
|
||||
}
|
||||
|
||||
{{$.BaseName}}_object *intern = {{$.BaseName}}_object_from_obj(Z_OBJ_P(ZEND_THIS));
|
||||
|
||||
|
||||
/* Constructor is called more than once, make it no-op */
|
||||
if (intern->go_handle != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
intern->go_handle = create_{{.GoStruct}}_object();
|
||||
}
|
||||
|
||||
@@ -75,10 +78,7 @@ PHP_METHOD({{.Name}}, __construct) {
|
||||
PHP_METHOD({{.ClassName}}, {{.PhpName}}) {
|
||||
{{$.BaseName}}_object *intern = {{$.BaseName}}_object_from_obj(Z_OBJ_P(ZEND_THIS));
|
||||
|
||||
if (intern->go_handle == 0) {
|
||||
zend_throw_error(NULL, "Go object not found in registry");
|
||||
RETURN_THROWS();
|
||||
}
|
||||
VALIDATE_GO_HANDLE(intern);
|
||||
|
||||
{{- if .Params -}}
|
||||
{{range $i, $param := .Params -}}
|
||||
|
||||
@@ -6,13 +6,6 @@
|
||||
|
||||
extern zend_module_entry ext_module_entry;
|
||||
|
||||
typedef struct go_value go_value;
|
||||
|
||||
typedef struct go_string {
|
||||
size_t len;
|
||||
char *data;
|
||||
} go_string;
|
||||
|
||||
{{if .Constants}}
|
||||
/* User defined constants */{{end}}
|
||||
{{range .Constants}}#define {{.Name}} {{.CValue}}
|
||||
|
||||
Reference in New Issue
Block a user