Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Inside the Sausage Factory: A Journey from PHP to C

Inside the Sausage Factory: A Journey from PHP to C

Presented May 8, 2014 at OpenWest: https://joind.in/talk/view/11189

Presented September 18, 2013 at Web & PHP Conference: https://joind.in/talk/view/8869

Reveal.js presentation published at: http://jmikola.github.io/slides/from_php_to_c/

Jeremy Mikola

May 08, 2014
Tweet

More Decks by Jeremy Mikola

Other Decks in Programming

Transcript

  1. I've done a bit of this TI-83 Basic Perl PHP

    JavaScript C++ Delphi Java Scheme C Assembly Ada95 Python
  2. More specifically… Finding C in PHP A crash course in

    C PHP internals Creating extensions
  3. Finding C in PHP Standard IO: f o p e

    n ( ) , f w r i t e ( ) Strings functions: s p r i n t f ( ) , s t r c h r ( ) Date/Time functions: s t r f t i m e ( ) , t i m e ( ) Extensions modeled on C APIs c u r l , g d , g m p , m y s q l , p c n t l
  4. Simple file IO in PHP $ f p = f

    o p e n ( " e x a m p l e . t x t " , " w " ) ; i f ( $ f p ) { f p u t s ( $ f p , " h e l l o " ) ; f c l o s e ( $ f p ) ; }
  5. Simple file IO in C # i n c l

    u d e < s t d i o . h > i n t m a i n ( ) { F I L E * f p = f o p e n ( " e x a m p l e . t x t " , " w " ) ; i f ( f p ) { f p u t s ( " h e l l o " , f p ) ; f c l o s e ( f p ) ; } r e t u r n 0 ; }
  6. Language differences PHP C Source Interpreted Compiled Typing Dynamic Static

    Scoping Function-level Block-level Memory Automatic Manual
  7. A crash course in C Header files and compiling Static

    and dynamic linking Declarations and data types Stack and heap memory
  8. Compiling C → Preprocessor → Translation Unit Translation Unit →

    Compiler → Object File Object Files → Linker → Executable
  9. Static and dynamic linking Static linking Monolithic binaries No external

    dependencies Dynamic linking (. s o , . d l l ) Modules loaded at run-time More flexibility, slight overhead
  10. Declarations Declare it before you use it Functions, types, variables

    Block-level scoping Source and header files e x t e r n and s t a t i c
  11. Data types Signed and unsigned integers c h a r

    , s h o r t , i n t , l o n g Floating point numbers f l o a t , d o u b l e Array and s t r u c t aggregates
  12. Pointers are a type i n t a = 3

    ; i n t * p t r = N U L L ; Variable Address Value a 0 x 8 1 3 0 0 x 0 0 0 0 0 0 0 3 p t r 0 x 8 1 3 4 0 x 0 0 0 0 0 0 0 0
  13. Pointer assignments p t r = & a ; Variable

    Address Value a 0 x 8 1 3 0 0 x 0 0 0 0 0 0 0 3 p t r 0 x 8 1 3 4 0 x 0 0 0 0 8 1 3 0
  14. Dereferencing pointers * p t r = 6 ; Variable

    Address Value a 0 x 8 1 3 0 0 x 0 0 0 0 0 0 0 6 p t r 0 x 8 1 3 4 0 x 0 0 0 0 8 1 3 0
  15. Pointers and arrays i n t a [ 4 ]

    = { 0 , 0 , 0 , 0 } ; i n t * p t r = a ; a [ 0 ] = 1 ; p t r [ 1 ] = 2 ; * ( a + 2 ) = 3 ; * ( p t r + 3 ) = 4 ; s i z e o f ( a ) ; / * 4 × s i z e o f ( i n t ) * / s i z e o f ( p t r ) ; / * s i z e o f ( i n t * ) * /
  16. Stack and heap memory / * S t a c

    k a l l o c a t i o n * / i n t z e n d _ a t o i ( c o n s t c h a r * s t r , i n t s t r _ l e n ) ; / * S t a c k a l l o c a t i o n * / i n t f o o [ 1 0 ] ; / * H e a p a l l o c a t i o n * / i n t * f o o = m a l l o c ( 1 0 * s i z e o f ( i n t ) ) ;
  17. Heap memory needs to be freed i n t *

    f o o = m a l l o c ( 1 0 * s i z e o f ( i n t ) ) ; i f ( f o o = = N U L L ) { / * R e q u i s i t e e r r o r h a n d l i n g * / } f r e e ( f o o ) ; / * R e t u r n a l l o c a t e d m e m o r y t o t h e h e a p * / f o o = N U L L ; / * A v o i d a c c e s s i n g f r e e d m e m o r y l a t e r * /
  18. PHP core does the heavy lifting Language parsing, compiling Macros

    for code scaffolding Data structures, utility functions Memory management, persistence Thread safety
  19. A place for everything Core source and syntax in Z

    e n d / Parser, types, internal API Extensions in e x t / and PECL Server APIs in s a p i / Tests live in t e s t s /
  20. PHPT tests Name, code, and expected output Used by both

    core and extensions Single-purpose and debuggable Documentation on qa.php.net Why not PHPUnit, PHPSpec, etc?
  21. An example PHPT test - - T E S T

    - - s t r r c h r ( ) t e s t s - - F I L E - - < ? p h p v a r _ d u m p ( s t r r c h r ( " " , " " ) ) ; v a r _ d u m p ( s t r r c h r ( " a b c " , " " ) ) ; v a r _ d u m p ( s t r r c h r ( " " , " a b c " ) ) ; v a r _ d u m p ( s t r r c h r ( " a b c " , " a b c " ) ) ; ? > - - E X P E C T F - - b o o l ( f a l s e ) b o o l ( f a l s e ) b o o l ( f a l s e ) s t r i n g ( 3 ) " a b c "
  22. It looks like you're giving a presentation on PHP internals.

    Would you like help? Talk about zvals
  23. PHP variables are zvals t y p e d e

    f u n i o n _ z v a l u e _ v a l u e { l o n g l v a l ; / * l o n g v a l u e * / d o u b l e d v a l ; / * d o u b l e v a l u e * / s t r u c t { / * s t r i n g v a l u e * / c h a r * v a l ; i n t l e n ; } s t r ; H a s h T a b l e * h t ; / * h a s h t a b l e v a l u e * / z e n d _ o b j e c t _ v a l u e o b j ; / * o b j e c t v a l u e * / } z v a l u e _ v a l u e ; t y p e d e f s t r u c t _ z v a l _ s t r u c t { z v a l u e _ v a l u e v a l u e ; / * v a l u e * / z e n d _ u i n t r e f c o u n t _ _ g c ; / * r e f e r e n c e c o u n t * / z e n d _ u c h a r t y p e ; / * a c t i v e t y p e * / z e n d _ u c h a r i s _ r e f _ _ g c ; / * i s a r e f e r e n c e ? * / } z v a l ;
  24. Macros for accessing zval data z v a l z

    v a l * z v a l * * Z _ L V A L Z _ L V A L _ P Z _ L V A L _ P P Z _ B V A L Z _ B V A L _ P Z _ B V A L _ P P Z _ D V A L Z _ D V A L _ P Z _ D V A L _ P P Z _ S T R V A L Z _ S T R V A L _ P Z _ S T R V A L _ P P Z _ S T R L E N Z _ S T R L E N _ P Z _ S T R L E N _ P P Z _ A R R V A L Z _ A R R V A L _ P Z _ A R R V A L _ P P Z _ O B J V A L Z _ O B J V A L _ P Z _ O B J V A L _ P P Z _ T Y P E Z _ T Y P E _ P Z _ T Y P E _ P P
  25. Macros for defining methods P H P _ M E

    T H O D ( M o n g o C u r s o r , l i m i t ) { l o n g l ; m o n g o _ c u r s o r * c u r s o r ; c u r s o r = ( m o n g o _ c u r s o r * ) z e n d _ o b j e c t _ s t o r e _ g e t _ o b j e c t ( g e t T h i s ( ) T S R M L S _ C C ) ; i f ( z e n d _ p a r s e _ p a r a m e t e r s ( Z E N D _ N U M _ A R G S ( ) T S R M L S _ C C , " l " , & l ) = = F A I L U R E ) { r e t u r n ; } p h p _ m o n g o _ c u r s o r _ s e t _ l i m i t ( c u r s o r , l ) ; R E T V A L _ Z V A L ( g e t T h i s ( ) , 1 , 0 ) ; }
  26. Our method after pre-processing v o i d z i

    m _ M o n g o C u r s o r _ l i m i t ( i n t h t , z v a l * r e t u r n _ v a l u e , z v a l * * r e t u r n _ v a l u e _ p t r , z v a l * t h i s _ p t r , i n t r e t u r n _ v a l u e _ u s e d ) { l o n g l ; m o n g o _ c u r s o r * c u r s o r ; c u r s o r = ( m o n g o _ c u r s o r * ) z e n d _ o b j e c t _ s t o r e _ g e t _ o b j e c t ( t h i s _ p t r ) ; i f ( z e n d _ p a r s e _ p a r a m e t e r s ( h t , " l " , & l ) = = F A I L U R E ) { r e t u r n ; } p h p _ m o n g o _ c u r s o r _ s e t _ l i m i t ( c u r s o r , l ) ; z e n d _ u c h a r i s _ r e f = z v a l _ i s r e f _ p ( r e t u r n _ v a l u e ) ; z e n d _ u i n t r e f c o u n t = z v a l _ r e f c o u n t _ p ( r e t u r n _ v a l u e ) ; r e t u r n _ v a l u e - > v a l u e = t h i s _ p t r - > v a l u e ; ( * r e t u r n _ v a l u e ) . t y p e = ( * t h i s _ p t r ) . t y p e ; z v a l _ c o p y _ c t o r ( r e t u r n _ v a l u e ) ; z v a l _ s e t _ i s r e f _ t o _ p ( r e t u r n _ v a l u e , i s _ r e f ) ; z v a l _ s e t _ r e f c o u n t _ p ( r e t u r n _ v a l u e , r e f c o u n t ) ; }
  27. Macros for… Memory allocation Working with hash tables Comparisons, casts,

    operations Defining class/function entries Other macros # d e f i n e Z _ T Y P E ( z v a l ) ( z v a l ) . t y p e # d e f i n e Z _ T Y P E _ P ( z v a l _ p ) Z _ T Y P E ( * z v a l _ p ) # d e f i n e Z _ T Y P E _ P P ( z v a l _ p p ) Z _ T Y P E ( * * z v a l _ p p )
  28. Ingredients for an extension Autoconf, p h p i z

    e , core libs c o n f i g . m 4 and c o n f i g . w 3 2 p h p _ m y e x t . c and p h p _ m y e x t . h and test coverage Coding standards Windows? Difficult but . not impossible
  29. The recipe $ p h p i z e C

    o n f i g u r i n g f o r : P H P A p i V e r s i o n : 2 0 1 0 0 4 1 2 Z e n d M o d u l e A p i N o : 2 0 1 0 0 5 2 5 Z e n d E x t e n s i o n A p i N o : 2 2 0 1 0 0 5 2 5 $
  30. The recipe $ . / c o n f i

    g u r e c h e c k i n g f o r g r e p t h a t h a n d l e s l o n g l i n e s a n d - e . . . / b i n / g r e p c h e c k i n g f o r e g r e p . . . / b i n / g r e p - E c h e c k i n g f o r a s e d t h a t d o e s n o t t r u n c a t e o u t p u t . . . / b i n / s e d c h e c k i n g f o r c c . . . c c c h e c k i n g w h e t h e r t h e C c o m p i l e r w o r k s . . . y e s . . . c h e c k i n g w h e t h e r t o b u i l d s t a t i c l i b r a r i e s . . . n o c o n f i g u r e : c r e a t i n g . / c o n f i g . s t a t u s c o n f i g . s t a t u s : c r e a t i n g c o n f i g . h c o n f i g . s t a t u s : e x e c u t i n g l i b t o o l c o m m a n d s $
  31. The recipe $ m a k e . . .

    B u i l d c o m p l e t e . D o n ' t f o r g e t t o r u n ' m a k e t e s t ' . $
  32. Recommended reading Developer blogs , , Kristina Chodorow's (2011) Marcus

    Börger's (2009) Zend Developer Zone articles (2009) Sara Golemon's (2005) PHP Internals Book Nikita Popov Sara Golemon Anthony Ferrara tutorial series conference talks Wrapping C++ Classes in a PHP Extension tutorial series