@@ -4469,6 +4469,318 @@ ZEND_METHOD(FFI_CType, getName) /* {{{ */
44694469 RETURN_STR (res );
44704470 }
44714471}
4472+ /* }}} */
4473+
4474+ ZEND_METHOD (FFI_CType , getKind ) /* {{{ */
4475+ {
4476+ zend_ffi_ctype * ctype = (zend_ffi_ctype * )(Z_OBJ_P (ZEND_THIS ));
4477+ zend_ffi_type * type ;
4478+
4479+ if (zend_parse_parameters_none () == FAILURE ) {
4480+ RETURN_THROWS ();
4481+ }
4482+
4483+ type = ZEND_FFI_TYPE (ctype -> type );
4484+ RETURN_LONG (type -> kind );
4485+ }
4486+ /* }}} */
4487+
4488+ ZEND_METHOD (FFI_CType , getSize ) /* {{{ */
4489+ {
4490+ zend_ffi_ctype * ctype = (zend_ffi_ctype * )(Z_OBJ_P (ZEND_THIS ));
4491+ zend_ffi_type * type ;
4492+
4493+ if (zend_parse_parameters_none () == FAILURE ) {
4494+ RETURN_THROWS ();
4495+ }
4496+
4497+ type = ZEND_FFI_TYPE (ctype -> type );
4498+ RETURN_LONG (type -> size );
4499+ }
4500+ /* }}} */
4501+
4502+ ZEND_METHOD (FFI_CType , getAlignment ) /* {{{ */
4503+ {
4504+ zend_ffi_ctype * ctype = (zend_ffi_ctype * )(Z_OBJ_P (ZEND_THIS ));
4505+ zend_ffi_type * type ;
4506+
4507+ if (zend_parse_parameters_none () == FAILURE ) {
4508+ RETURN_THROWS ();
4509+ }
4510+
4511+ type = ZEND_FFI_TYPE (ctype -> type );
4512+ RETURN_LONG (type -> align );
4513+ }
4514+ /* }}} */
4515+
4516+ ZEND_METHOD (FFI_CType , getAttributes ) /* {{{ */
4517+ {
4518+ zend_ffi_ctype * ctype = (zend_ffi_ctype * )(Z_OBJ_P (ZEND_THIS ));
4519+ zend_ffi_type * type ;
4520+
4521+ if (zend_parse_parameters_none () == FAILURE ) {
4522+ RETURN_THROWS ();
4523+ }
4524+
4525+ type = ZEND_FFI_TYPE (ctype -> type );
4526+ RETURN_LONG (type -> attr );
4527+ }
4528+ /* }}} */
4529+
4530+ ZEND_METHOD (FFI_CType , getEnumKind ) /* {{{ */
4531+ {
4532+ zend_ffi_ctype * ctype = (zend_ffi_ctype * )(Z_OBJ_P (ZEND_THIS ));
4533+ zend_ffi_type * type ;
4534+
4535+ if (zend_parse_parameters_none () == FAILURE ) {
4536+ RETURN_THROWS ();
4537+ }
4538+
4539+ type = ZEND_FFI_TYPE (ctype -> type );
4540+ if (type -> kind != ZEND_FFI_TYPE_ENUM ) {
4541+ zend_throw_error (zend_ffi_exception_ce , "FFI\\CType is not an enumeration" );
4542+ RETURN_THROWS ();
4543+ }
4544+ RETURN_LONG (type -> enumeration .kind );
4545+ }
4546+ /* }}} */
4547+
4548+ ZEND_METHOD (FFI_CType , getArrayElementType ) /* {{{ */
4549+ {
4550+ zend_ffi_ctype * ctype = (zend_ffi_ctype * )(Z_OBJ_P (ZEND_THIS ));
4551+ zend_ffi_type * type ;
4552+ zend_ffi_ctype * ret ;
4553+
4554+ if (zend_parse_parameters_none () == FAILURE ) {
4555+ RETURN_THROWS ();
4556+ }
4557+
4558+ type = ZEND_FFI_TYPE (ctype -> type );
4559+ if (type -> kind != ZEND_FFI_TYPE_ARRAY ) {
4560+ zend_throw_error (zend_ffi_exception_ce , "FFI\\CType is not an array" );
4561+ RETURN_THROWS ();
4562+ }
4563+
4564+ ret = (zend_ffi_ctype * )zend_ffi_ctype_new (zend_ffi_ctype_ce );
4565+ ret -> type = ZEND_FFI_TYPE (type -> array .type );
4566+ RETURN_OBJ (& ret -> std );
4567+ }
4568+ /* }}} */
4569+
4570+ ZEND_METHOD (FFI_CType , getArrayLength ) /* {{{ */
4571+ {
4572+ zend_ffi_ctype * ctype = (zend_ffi_ctype * )(Z_OBJ_P (ZEND_THIS ));
4573+ zend_ffi_type * type ;
4574+
4575+ if (zend_parse_parameters_none () == FAILURE ) {
4576+ RETURN_THROWS ();
4577+ }
4578+
4579+ type = ZEND_FFI_TYPE (ctype -> type );
4580+ if (type -> kind != ZEND_FFI_TYPE_ARRAY ) {
4581+ zend_throw_error (zend_ffi_exception_ce , "FFI\\CType is not an array" );
4582+ RETURN_THROWS ();
4583+ }
4584+ RETURN_LONG (type -> array .length );
4585+ }
4586+ /* }}} */
4587+
4588+ ZEND_METHOD (FFI_CType , getPointerType ) /* {{{ */
4589+ {
4590+ zend_ffi_ctype * ctype = (zend_ffi_ctype * )(Z_OBJ_P (ZEND_THIS ));
4591+ zend_ffi_ctype * ret ;
4592+ zend_ffi_type * type ;
4593+
4594+ if (zend_parse_parameters_none () == FAILURE ) {
4595+ RETURN_THROWS ();
4596+ }
4597+
4598+ type = ZEND_FFI_TYPE (ctype -> type );
4599+ if (type -> kind != ZEND_FFI_TYPE_POINTER ) {
4600+ zend_throw_error (zend_ffi_exception_ce , "FFI\\CType is not a pointer" );
4601+ RETURN_THROWS ();
4602+ }
4603+
4604+ ret = (zend_ffi_ctype * )zend_ffi_ctype_new (zend_ffi_ctype_ce );
4605+ ret -> type = ZEND_FFI_TYPE (type -> pointer .type );
4606+ RETURN_OBJ (& ret -> std );
4607+ }
4608+ /* }}} */
4609+
4610+ ZEND_METHOD (FFI_CType , getStructFieldNames ) /* {{{ */
4611+ {
4612+ zend_ffi_ctype * ctype = (zend_ffi_ctype * )(Z_OBJ_P (ZEND_THIS ));
4613+ zend_ffi_type * type ;
4614+ HashTable * ht ;
4615+ zend_string * name ;
4616+ zval zv ;
4617+
4618+ if (zend_parse_parameters_none () == FAILURE ) {
4619+ RETURN_THROWS ();
4620+ }
4621+
4622+ type = ZEND_FFI_TYPE (ctype -> type );
4623+ if (type -> kind != ZEND_FFI_TYPE_STRUCT ) {
4624+ zend_throw_error (zend_ffi_exception_ce , "FFI\\CType is not a structure" );
4625+ RETURN_THROWS ();
4626+ }
4627+
4628+ ht = zend_new_array (zend_hash_num_elements (& type -> record .fields ));
4629+ RETVAL_ARR (ht );
4630+ ZEND_HASH_FOREACH_STR_KEY (& type -> record .fields , name ) {
4631+ ZVAL_STR_COPY (& zv , name );
4632+ zend_hash_next_index_insert_new (ht , & zv );
4633+ } ZEND_HASH_FOREACH_END ();
4634+ }
4635+ /* }}} */
4636+
4637+ ZEND_METHOD (FFI_CType , getStructFieldOffset ) /* {{{ */
4638+ {
4639+ zend_ffi_ctype * ctype = (zend_ffi_ctype * )(Z_OBJ_P (ZEND_THIS ));
4640+ zend_ffi_type * type ;
4641+ zend_string * name ;
4642+ zend_ffi_field * ptr ;
4643+
4644+ ZEND_PARSE_PARAMETERS_START (1 , 1 )
4645+ Z_PARAM_STR (name )
4646+ ZEND_PARSE_PARAMETERS_END ();
4647+
4648+ type = ZEND_FFI_TYPE (ctype -> type );
4649+ if (type -> kind != ZEND_FFI_TYPE_STRUCT ) {
4650+ zend_throw_error (zend_ffi_exception_ce , "FFI\\CType is not a structure" );
4651+ RETURN_THROWS ();
4652+ }
4653+
4654+ ptr = zend_hash_find_ptr (& type -> record .fields , name );
4655+ if (!ptr ) {
4656+ zend_throw_error (zend_ffi_exception_ce , "Wrong fileld name" );
4657+ RETURN_THROWS ();
4658+ }
4659+ RETURN_LONG (ptr -> offset );
4660+ }
4661+ /* }}} */
4662+
4663+ ZEND_METHOD (FFI_CType , getStructFieldType ) /* {{{ */
4664+ {
4665+ zend_ffi_ctype * ctype = (zend_ffi_ctype * )(Z_OBJ_P (ZEND_THIS ));
4666+ zend_ffi_type * type ;
4667+ zend_string * name ;
4668+ zend_ffi_field * ptr ;
4669+ zend_ffi_ctype * ret ;
4670+
4671+ ZEND_PARSE_PARAMETERS_START (1 , 1 )
4672+ Z_PARAM_STR (name )
4673+ ZEND_PARSE_PARAMETERS_END ();
4674+
4675+ type = ZEND_FFI_TYPE (ctype -> type );
4676+ if (type -> kind != ZEND_FFI_TYPE_STRUCT ) {
4677+ zend_throw_error (zend_ffi_exception_ce , "FFI\\CType is not a structure" );
4678+ RETURN_THROWS ();
4679+ }
4680+
4681+ ptr = zend_hash_find_ptr (& type -> record .fields , name );
4682+ if (!ptr ) {
4683+ zend_throw_error (zend_ffi_exception_ce , "Wrong fileld name" );
4684+ RETURN_THROWS ();
4685+ }
4686+
4687+ ret = (zend_ffi_ctype * )zend_ffi_ctype_new (zend_ffi_ctype_ce );
4688+ ret -> type = ZEND_FFI_TYPE (ptr -> type );
4689+ RETURN_OBJ (& ret -> std );
4690+ }
4691+ /* }}} */
4692+
4693+ ZEND_METHOD (FFI_CType , getFuncABI ) /* {{{ */
4694+ {
4695+ zend_ffi_ctype * ctype = (zend_ffi_ctype * )(Z_OBJ_P (ZEND_THIS ));
4696+ zend_ffi_type * type ;
4697+
4698+ if (zend_parse_parameters_none () == FAILURE ) {
4699+ RETURN_THROWS ();
4700+ }
4701+
4702+ type = ZEND_FFI_TYPE (ctype -> type );
4703+ if (type -> kind != ZEND_FFI_TYPE_FUNC ) {
4704+ zend_throw_error (zend_ffi_exception_ce , "FFI\\CType is not a function" );
4705+ RETURN_THROWS ();
4706+ }
4707+ RETURN_LONG (type -> func .abi );
4708+ }
4709+ /* }}} */
4710+
4711+ ZEND_METHOD (FFI_CType , getFuncReturnType ) /* {{{ */
4712+ {
4713+ zend_ffi_ctype * ctype = (zend_ffi_ctype * )(Z_OBJ_P (ZEND_THIS ));
4714+ zend_ffi_ctype * ret ;
4715+ zend_ffi_type * type ;
4716+
4717+ if (zend_parse_parameters_none () == FAILURE ) {
4718+ RETURN_THROWS ();
4719+ }
4720+
4721+ type = ZEND_FFI_TYPE (ctype -> type );
4722+ if (type -> kind != ZEND_FFI_TYPE_FUNC ) {
4723+ zend_throw_error (zend_ffi_exception_ce , "FFI\\CType is not a function" );
4724+ RETURN_THROWS ();
4725+ }
4726+
4727+ ret = (zend_ffi_ctype * )zend_ffi_ctype_new (zend_ffi_ctype_ce );
4728+ ret -> type = ZEND_FFI_TYPE (type -> func .ret_type );
4729+ RETURN_OBJ (& ret -> std );
4730+ }
4731+ /* }}} */
4732+
4733+ ZEND_METHOD (FFI_CType , getFuncArgCount ) /* {{{ */
4734+ {
4735+ zend_ffi_ctype * ctype = (zend_ffi_ctype * )(Z_OBJ_P (ZEND_THIS ));
4736+ zend_ffi_type * type ;
4737+
4738+ if (zend_parse_parameters_none () == FAILURE ) {
4739+ RETURN_THROWS ();
4740+ }
4741+
4742+ type = ZEND_FFI_TYPE (ctype -> type );
4743+ if (type -> kind != ZEND_FFI_TYPE_FUNC ) {
4744+ zend_throw_error (zend_ffi_exception_ce , "FFI\\CType is not a function" );
4745+ RETURN_THROWS ();
4746+ }
4747+ RETURN_LONG (type -> func .args ? zend_hash_num_elements (type -> func .args ) : 0 );
4748+ }
4749+ /* }}} */
4750+
4751+ ZEND_METHOD (FFI_CType , getFuncArgType ) /* {{{ */
4752+ {
4753+ zend_ffi_ctype * ctype = (zend_ffi_ctype * )(Z_OBJ_P (ZEND_THIS ));
4754+ zend_ffi_type * type , * ptr ;
4755+ zend_long n ;
4756+ zend_ffi_ctype * ret ;
4757+
4758+ ZEND_PARSE_PARAMETERS_START (1 , 1 )
4759+ Z_PARAM_LONG (n )
4760+ ZEND_PARSE_PARAMETERS_END ();
4761+
4762+ type = ZEND_FFI_TYPE (ctype -> type );
4763+ if (type -> kind != ZEND_FFI_TYPE_FUNC ) {
4764+ zend_throw_error (zend_ffi_exception_ce , "FFI\\CType is not a function" );
4765+ RETURN_THROWS ();
4766+ }
4767+
4768+ if (!type -> func .args ) {
4769+ zend_throw_error (zend_ffi_exception_ce , "Wrong argument number" );
4770+ RETURN_THROWS ();
4771+ }
4772+
4773+ ptr = zend_hash_index_find_ptr (type -> func .args , n );
4774+ if (!ptr ) {
4775+ zend_throw_error (zend_ffi_exception_ce , "Wrong argument number" );
4776+ RETURN_THROWS ();
4777+ }
4778+
4779+ ret = (zend_ffi_ctype * )zend_ffi_ctype_new (zend_ffi_ctype_ce );
4780+ ret -> type = ZEND_FFI_TYPE (ptr );
4781+ RETURN_OBJ (& ret -> std );
4782+ }
4783+ /* }}} */
44724784
44734785static char * zend_ffi_parse_directives (const char * filename , char * code_pos , char * * scope_name , char * * lib , bool preload ) /* {{{ */
44744786{
@@ -4896,6 +5208,9 @@ static int zend_ffi_preload(char *preload) /* {{{ */
48965208}
48975209/* }}} */
48985210
5211+ #define REGISTER_FFI_TYPE_CONSTANT (name ) \
5212+ zend_declare_class_constant_long(zend_ffi_ctype_ce, #name, sizeof(#name) - 1, ZEND_FFI_ ## name)
5213+
48995214/* {{{ ZEND_MINIT_FUNCTION */
49005215ZEND_MINIT_FUNCTION (ffi )
49015216{
@@ -5046,6 +5361,49 @@ ZEND_MINIT_FUNCTION(ffi)
50465361 zend_ffi_ctype_handlers .get_properties = zend_fake_get_properties ;
50475362 zend_ffi_ctype_handlers .get_gc = zend_fake_get_gc ;
50485363
5364+ REGISTER_FFI_TYPE_CONSTANT (TYPE_VOID );
5365+ REGISTER_FFI_TYPE_CONSTANT (TYPE_FLOAT );
5366+ REGISTER_FFI_TYPE_CONSTANT (TYPE_DOUBLE );
5367+ #ifdef HAVE_LONG_DOUBLE
5368+ REGISTER_FFI_TYPE_CONSTANT (TYPE_LONGDOUBLE );
5369+ #endif
5370+ REGISTER_FFI_TYPE_CONSTANT (TYPE_UINT8 );
5371+ REGISTER_FFI_TYPE_CONSTANT (TYPE_SINT8 );
5372+ REGISTER_FFI_TYPE_CONSTANT (TYPE_UINT16 );
5373+ REGISTER_FFI_TYPE_CONSTANT (TYPE_SINT16 );
5374+ REGISTER_FFI_TYPE_CONSTANT (TYPE_UINT32 );
5375+ REGISTER_FFI_TYPE_CONSTANT (TYPE_SINT32 );
5376+ REGISTER_FFI_TYPE_CONSTANT (TYPE_UINT64 );
5377+ REGISTER_FFI_TYPE_CONSTANT (TYPE_SINT64 );
5378+ REGISTER_FFI_TYPE_CONSTANT (TYPE_ENUM );
5379+ REGISTER_FFI_TYPE_CONSTANT (TYPE_BOOL );
5380+ REGISTER_FFI_TYPE_CONSTANT (TYPE_CHAR );
5381+ REGISTER_FFI_TYPE_CONSTANT (TYPE_POINTER );
5382+ REGISTER_FFI_TYPE_CONSTANT (TYPE_FUNC );
5383+ REGISTER_FFI_TYPE_CONSTANT (TYPE_ARRAY );
5384+ REGISTER_FFI_TYPE_CONSTANT (TYPE_STRUCT );
5385+
5386+ REGISTER_FFI_TYPE_CONSTANT (ATTR_CONST );
5387+ REGISTER_FFI_TYPE_CONSTANT (ATTR_INCOMPLETE_TAG );
5388+ REGISTER_FFI_TYPE_CONSTANT (ATTR_VARIADIC );
5389+ REGISTER_FFI_TYPE_CONSTANT (ATTR_INCOMPLETE_ARRAY );
5390+ REGISTER_FFI_TYPE_CONSTANT (ATTR_VLA );
5391+ REGISTER_FFI_TYPE_CONSTANT (ATTR_UNION );
5392+ REGISTER_FFI_TYPE_CONSTANT (ATTR_PACKED );
5393+ REGISTER_FFI_TYPE_CONSTANT (ATTR_MS_STRUCT );
5394+ REGISTER_FFI_TYPE_CONSTANT (ATTR_GCC_STRUCT );
5395+
5396+ REGISTER_FFI_TYPE_CONSTANT (ABI_DEFAULT );
5397+ REGISTER_FFI_TYPE_CONSTANT (ABI_CDECL );
5398+ REGISTER_FFI_TYPE_CONSTANT (ABI_FASTCALL );
5399+ REGISTER_FFI_TYPE_CONSTANT (ABI_THISCALL );
5400+ REGISTER_FFI_TYPE_CONSTANT (ABI_STDCALL );
5401+ REGISTER_FFI_TYPE_CONSTANT (ABI_PASCAL );
5402+ REGISTER_FFI_TYPE_CONSTANT (ABI_REGISTER );
5403+ REGISTER_FFI_TYPE_CONSTANT (ABI_MS );
5404+ REGISTER_FFI_TYPE_CONSTANT (ABI_SYSV );
5405+ REGISTER_FFI_TYPE_CONSTANT (ABI_VECTORCALL );
5406+
50495407 if (FFI_G (preload )) {
50505408 if (zend_ffi_preload (FFI_G (preload )) != SUCCESS ) {
50515409 return FAILURE ;
0 commit comments