@@ -218,19 +218,18 @@ func phpArray[T any](entries map[string]T, order []string) unsafe.Pointer {
218218 val := entries [key ]
219219 zval := phpValue (val )
220220 C .zend_hash_str_update (zendArray , toUnsafeChar (key ), C .size_t (len (key )), zval )
221+ C .__efree__ (unsafe .Pointer (zval ))
221222 }
222223 } else {
223224 zendArray = createNewArray ((uint32 )(len (entries )))
224225 for key , val := range entries {
225226 zval := phpValue (val )
226227 C .zend_hash_str_update (zendArray , toUnsafeChar (key ), C .size_t (len (key )), zval )
228+ C .__efree__ (unsafe .Pointer (zval ))
227229 }
228230 }
229231
230- var zval C.zval
231- C .__zval_arr__ (& zval , zendArray )
232-
233- return unsafe .Pointer (& zval )
232+ return unsafe .Pointer (zendArray )
234233}
235234
236235// EXPERIMENTAL: PHPPackedArray converts a Go slice to a PHP zval with a zend_array value.
@@ -239,12 +238,10 @@ func PHPPackedArray[T any](slice []T) unsafe.Pointer {
239238 for _ , val := range slice {
240239 zval := phpValue (val )
241240 C .zend_hash_next_index_insert (zendArray , zval )
241+ C .__efree__ (unsafe .Pointer (zval ))
242242 }
243243
244- var zval C.zval
245- C .__zval_arr__ (& zval , zendArray )
246-
247- return unsafe .Pointer (& zval )
244+ return unsafe .Pointer (zendArray )
248245}
249246
250247// EXPERIMENTAL: GoValue converts a PHP zval to a Go value
@@ -364,35 +361,39 @@ func PHPValue(value any) unsafe.Pointer {
364361}
365362
366363func phpValue (value any ) * C.zval {
367- var zval C.zval
364+ zval := ( * C .zval )( C . __emalloc__ ( C . size_t ( unsafe . Sizeof (C. zval {}))))
368365
369366 if toZvalObj , ok := value .(toZval ); ok {
367+ C .__efree__ (unsafe .Pointer (zval ))
370368 return toZvalObj .toZval ()
371369 }
372370
373371 switch v := value .(type ) {
374372 case nil :
375- C .__zval_null__ (& zval )
373+ C .__zval_null__ (zval )
376374 case bool :
377- C .__zval_bool__ (& zval , C ._Bool (v ))
375+ C .__zval_bool__ (zval , C ._Bool (v ))
378376 case int :
379- C .__zval_long__ (& zval , C .zend_long (v ))
377+ C .__zval_long__ (zval , C .zend_long (v ))
380378 case int64 :
381- C .__zval_long__ (& zval , C .zend_long (v ))
379+ C .__zval_long__ (zval , C .zend_long (v ))
382380 case float64 :
383- C .__zval_double__ (& zval , C .double (v ))
381+ C .__zval_double__ (zval , C .double (v ))
384382 case string :
385383 str := (* C .zend_string )(PHPString (v , false ))
386- C .__zval_string__ (& zval , str )
384+ C .__zval_string__ (zval , str )
387385 case map [string ]any :
388- return (* C .zval )(PHPAssociativeArray [any ](AssociativeArray [any ]{Map : v }))
386+ zendArray := (* C .HashTable )(PHPAssociativeArray [any ](AssociativeArray [any ]{Map : v }))
387+ C .__zval_arr__ (zval , zendArray )
389388 case []any :
390- return (* C .zval )(PHPPackedArray (v ))
389+ zendArray := (* C .HashTable )(PHPPackedArray (v ))
390+ C .__zval_arr__ (zval , zendArray )
391391 default :
392+ C .__efree__ (unsafe .Pointer (zval ))
392393 panic (fmt .Sprintf ("unsupported Go type %T" , v ))
393394 }
394395
395- return & zval
396+ return zval
396397}
397398
398399// createNewArray creates a new zend_array with the specified size.
@@ -456,12 +457,19 @@ func CallPHPCallable(cb unsafe.Pointer, params []interface{}) interface{} {
456457 var paramStorage * C.zval
457458 if paramCount > 0 {
458459 paramStorage = (* C .zval )(C .__emalloc__ (C .size_t (paramCount ) * C .size_t (unsafe .Sizeof (C.zval {}))))
459- defer C .__efree__ (unsafe .Pointer (paramStorage ))
460+ defer func () {
461+ for i := 0 ; i < paramCount ; i ++ {
462+ targetZval := (* C .zval )(unsafe .Pointer (uintptr (unsafe .Pointer (paramStorage )) + uintptr (i )* unsafe .Sizeof (C.zval {})))
463+ C .zval_ptr_dtor (targetZval )
464+ }
465+ C .__efree__ (unsafe .Pointer (paramStorage ))
466+ }()
460467
461468 for i , param := range params {
462469 targetZval := (* C .zval )(unsafe .Pointer (uintptr (unsafe .Pointer (paramStorage )) + uintptr (i )* unsafe .Sizeof (C.zval {})))
463470 sourceZval := phpValue (param )
464471 * targetZval = * sourceZval
472+ C .__efree__ (unsafe .Pointer (sourceZval ))
465473 }
466474 }
467475
@@ -473,6 +481,8 @@ func CallPHPCallable(cb unsafe.Pointer, params []interface{}) interface{} {
473481 }
474482
475483 goResult , err := goValue [any ](& retval )
484+ C .zval_ptr_dtor (& retval )
485+
476486 if err != nil {
477487 return nil
478488 }
0 commit comments