Top Banner
Diving into HHVM Extensions James Titcumb BrnoPHP Conference 2015
78

Diving into HHVM Extensions (Brno PHP Conference 2015)

Jan 26, 2017

Download

Technology

James Titcumb
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Diving into HHVM Extensions (Brno PHP Conference 2015)

Diving intoHHVM Extensions

James TitcumbBrnoPHP Conference 2015

Page 3: Diving into HHVM Extensions (Brno PHP Conference 2015)

First, some background...

source: Microsoft

Page 4: Diving into HHVM Extensions (Brno PHP Conference 2015)
Page 5: Diving into HHVM Extensions (Brno PHP Conference 2015)
Page 6: Diving into HHVM Extensions (Brno PHP Conference 2015)
Page 7: Diving into HHVM Extensions (Brno PHP Conference 2015)

How PHP works

PHP code

OpCache

Execute (VM)

Lexer + Parser

Compiler

Page 8: Diving into HHVM Extensions (Brno PHP Conference 2015)

How HHVM worksPHP code

OpCache

Execute (VM)

Lexer + Parser

Compiler

JIT

Execute (Native)

Page 9: Diving into HHVM Extensions (Brno PHP Conference 2015)

Hack features

● Return/parameter type hints● ?nullable● Collections (Vectors, Sets, Maps, etc.)● Async functions● Enums● Generics● Lambda expressions ==>● XHP● more stuff

Page 10: Diving into HHVM Extensions (Brno PHP Conference 2015)

The HHVM codebase

Page 11: Diving into HHVM Extensions (Brno PHP Conference 2015)

The Engine

hphp/parser

Page 12: Diving into HHVM Extensions (Brno PHP Conference 2015)

The Engine

hphp/parserhphp/compiler

Page 13: Diving into HHVM Extensions (Brno PHP Conference 2015)

The Engine

hphp/parserhphp/compilerhphp/hhbbc

Page 14: Diving into HHVM Extensions (Brno PHP Conference 2015)

The Engine

hphp/parserhphp/compilerhphp/hhbbchphp/hhvm

Page 15: Diving into HHVM Extensions (Brno PHP Conference 2015)

The Engine

hphp/parserhphp/compilerhphp/hhbbchphp/hhvmhphp/runtime/vm

Page 16: Diving into HHVM Extensions (Brno PHP Conference 2015)

The Engine

hphp/parserhphp/compilerhphp/hhbbchphp/hhvmhphp/runtime/vmhphp/runtime/vm/jit

Page 17: Diving into HHVM Extensions (Brno PHP Conference 2015)

The Extensions

hphp/runtime/ext

Page 18: Diving into HHVM Extensions (Brno PHP Conference 2015)

The Extensions

hphp/runtime/exthphp/system/php

Page 19: Diving into HHVM Extensions (Brno PHP Conference 2015)

Compile HHVM?

Page 20: Diving into HHVM Extensions (Brno PHP Conference 2015)

source: https://xkcd.com/303/

Page 21: Diving into HHVM Extensions (Brno PHP Conference 2015)

My First HHVM Extension™

Page 22: Diving into HHVM Extensions (Brno PHP Conference 2015)

config.cmake

HHVM_EXTENSION(calc ext_calc.cpp)

Page 23: Diving into HHVM Extensions (Brno PHP Conference 2015)

ext_calc.cpp#include "hphp/runtime/ext/extension.h"

namespace HPHP {

static class CalcExtension : public Extension {

public:

CalcExtension(): Extension("calc") {}

virtual void moduleInit() {}

} s_calc_extension;

HHVM_GET_MODULE(calc);

} // namespace HPHP

Page 24: Diving into HHVM Extensions (Brno PHP Conference 2015)

ext_calc.cpp#include "hphp/runtime/ext/extension.h"

namespace HPHP {

static class CalcExtension : public Extension {

public:

CalcExtension(): Extension("calc") {}

virtual void moduleInit() {}

} s_calc_extension;

HHVM_GET_MODULE(calc);

} // namespace HPHP

Page 25: Diving into HHVM Extensions (Brno PHP Conference 2015)

ext_calc.cpp#include "hphp/runtime/ext/extension.h"

namespace HPHP {

static class CalcExtension : public Extension {

public:

CalcExtension(): Extension("calc") {}

virtual void moduleInit() {}

} s_calc_extension;

HHVM_GET_MODULE(calc);

} // namespace HPHP

Page 26: Diving into HHVM Extensions (Brno PHP Conference 2015)

ext_calc.cpp#include "hphp/runtime/ext/extension.h"

namespace HPHP {

static class CalcExtension : public Extension {

public:

CalcExtension(): Extension("calc") {}

virtual void moduleInit() {}

} s_calc_extension;

HHVM_GET_MODULE(calc);

} // namespace HPHP

Page 27: Diving into HHVM Extensions (Brno PHP Conference 2015)

ext_calc.cpp#include "hphp/runtime/ext/extension.h"

namespace HPHP {

static class CalcExtension : public Extension {

public:

CalcExtension(): Extension("calc") {}

virtual void moduleInit() {}

} s_calc_extension;

HHVM_GET_MODULE(calc);

} // namespace HPHP

Page 28: Diving into HHVM Extensions (Brno PHP Conference 2015)

… that’s it.

<?php

var_dump(extension_loaded('calc'));

test.php

Page 29: Diving into HHVM Extensions (Brno PHP Conference 2015)

Compile it.(waaaat?!)

Page 30: Diving into HHVM Extensions (Brno PHP Conference 2015)

Compile & run the test#!/bin/bash

hphpize

cmake . && make

/usr/bin/hhvm \

-d extension_dir=. \

-d hhvm.extensions[]=calc.so \

test.php

Page 31: Diving into HHVM Extensions (Brno PHP Conference 2015)

Compile & run the test$ ./build.sh

bool(true)

$

Page 32: Diving into HHVM Extensions (Brno PHP Conference 2015)

Hack it!

Page 33: Diving into HHVM Extensions (Brno PHP Conference 2015)

source: http://goo.gl/kUAxBI

Page 34: Diving into HHVM Extensions (Brno PHP Conference 2015)

config.cmake

HHVM_EXTENSION(calc ext_calc.cpp)HHVM_SYSTEMLIB(calc ext_calc.php)

Page 35: Diving into HHVM Extensions (Brno PHP Conference 2015)

ext_calc.cpp#include "hphp/runtime/ext/extension.h"

namespace HPHP {

static class CalcExtension : public Extension {

public:

CalcExtension(): Extension("calc") {}

virtual void moduleInit() {

loadSystemlib();

}

} s_calc_extension;

HHVM_GET_MODULE(calc);

} // namespace HPHP

Page 36: Diving into HHVM Extensions (Brno PHP Conference 2015)

ext_calc.php<?hh

function calc_sub(int $a, int $b): int {

return $a - $b;

}

Page 37: Diving into HHVM Extensions (Brno PHP Conference 2015)

… that’s it.

<?php

var_dump(extension_loaded('calc'));

var_dump(calc_sub(5, 3));

test.php

Page 38: Diving into HHVM Extensions (Brno PHP Conference 2015)

Compile & run the test$ ./build.sh

bool(true)

int(2)

$

Page 39: Diving into HHVM Extensions (Brno PHP Conference 2015)

Sprinkle some C++ infor good measure

Page 40: Diving into HHVM Extensions (Brno PHP Conference 2015)

ext_calc.cpp// ... SNIP ...

virtual void moduleInit() {

HHVM_FE(calc_add);

loadSystemlib();

}

// ... SNIP ...

Page 41: Diving into HHVM Extensions (Brno PHP Conference 2015)

ext_calc.cpp// ... SNIP ...

static int64_t HHVM_FUNCTION(calc_add, int64_t a, int64_t b) {

return a + b;

}

// ... SNIP ...

Page 42: Diving into HHVM Extensions (Brno PHP Conference 2015)

in php extensions...PHP_FUNCTION(calc_add)

{

// ... SNIP ...

#ifndef FAST_ZPP

if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &a, &b) == FAILURE) {

return;

}

#else

ZEND_PARSE_PARAMETERS_START(2, 2)

Z_PARAM_LONG(a)

Z_PARAM_LONG(b)

ZEND_PARSE_PARAMETERS_END();

#endif

// ... SNIP ...

Page 43: Diving into HHVM Extensions (Brno PHP Conference 2015)

ext_calc.php<?hh

<<__Native>>

function calc_add(int $a, int $b): int;

function calc_sub(int $a, int $b): int {

return $a - $b;

}

Page 44: Diving into HHVM Extensions (Brno PHP Conference 2015)

… that’s it.

<?php

var_dump(extension_loaded('calc'));

var_dump(calc_sub(5, 3));

var_dump(calc_add(5, 3));

test.php

Page 45: Diving into HHVM Extensions (Brno PHP Conference 2015)

Compile & run the test$ ./build.sh

bool(true)

int(2)

int(8)

$

Page 46: Diving into HHVM Extensions (Brno PHP Conference 2015)

Debugging?!

Page 47: Diving into HHVM Extensions (Brno PHP Conference 2015)

source: http://www.gnu.org/software/gdb/

Page 48: Diving into HHVM Extensions (Brno PHP Conference 2015)

Add debug mode#!/bin/bash

hphpize

cmake \

-DCMAKE_C_FLAGS="-O0 -ggdb3" \

-DCMAKE_CXX_FLAGS="-O0 -ggdb3" \

-DCMAKE_BUILD_TYPE=Debug \

.

make

# ... SNIP ...

Page 49: Diving into HHVM Extensions (Brno PHP Conference 2015)

Run with gdb$ gdb --args \

/usr/bin/hhvm \

-d extension_dir=. \

-d hhvm.extensions[]=calc.so \

test.php

GNU gdb (Ubuntu 7.9-1ubuntu1) 7.9

Copyright (C) 2015 Free Software Foundation, Inc.

License GPLv3+: GNU GPL version 3 or later <http://gnu.

org/licenses/gpl.html>

--- snip ---

Reading symbols from /usr/bin/hhvm...done.

(gdb)

Page 50: Diving into HHVM Extensions (Brno PHP Conference 2015)

Breakpoints(gdb) b ext_calc.cpp:6

No source file named ext_calc.cpp.

Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 1 (ext_calc.cpp:6) pending.

(gdb)

Page 51: Diving into HHVM Extensions (Brno PHP Conference 2015)

Running(gdb) r

Starting program: /usr/bin/hhvm -d extension_dir=. -d hhvm.extensions\[\]

=calc.so smoke.php

[Thread debugging using libthread_db enabled]

Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 2, HPHP::f_calc_add (a=5, b=3) at /home/james/workspace/hhvm-

calc/ext_calc.cpp:6

6 return a + b;

(gdb) p a

$1 = 5

(gdb) p b

$2 = 3

(gdb)

Page 52: Diving into HHVM Extensions (Brno PHP Conference 2015)

Handy commands

c continue / step out

n step over

s step into

p x print the value of a variable (x)

set x = y set a variable (x) to value (y)

bt print backtrace

q quit :)

Page 53: Diving into HHVM Extensions (Brno PHP Conference 2015)

When NOT to write extensions

Page 54: Diving into HHVM Extensions (Brno PHP Conference 2015)

When to write extensions

Page 55: Diving into HHVM Extensions (Brno PHP Conference 2015)

BUCKLE UP.

Page 56: Diving into HHVM Extensions (Brno PHP Conference 2015)

source: https://goo.gl/x7Srhe

Page 57: Diving into HHVM Extensions (Brno PHP Conference 2015)

Integrating OpenGLinto an HHVM extension

Page 58: Diving into HHVM Extensions (Brno PHP Conference 2015)

Don’t try this in production!

Page 59: Diving into HHVM Extensions (Brno PHP Conference 2015)

srsly.

Page 60: Diving into HHVM Extensions (Brno PHP Conference 2015)

Extension

Browser

Page 61: Diving into HHVM Extensions (Brno PHP Conference 2015)

What I did

Page 62: Diving into HHVM Extensions (Brno PHP Conference 2015)
Page 63: Diving into HHVM Extensions (Brno PHP Conference 2015)

huh?!

Page 64: Diving into HHVM Extensions (Brno PHP Conference 2015)

Make it OOOOOOO

Page 65: Diving into HHVM Extensions (Brno PHP Conference 2015)

ext_foo.php<?hh

<<__NativeData("Foo")>>

class Foo {

<<__Native>>

public function bar(): int;

}

Page 66: Diving into HHVM Extensions (Brno PHP Conference 2015)

C++ object!==

PHP object

Page 67: Diving into HHVM Extensions (Brno PHP Conference 2015)

source: http://goo.gl/HORwLQ

Page 68: Diving into HHVM Extensions (Brno PHP Conference 2015)

HHVM Universe

<?php

$o = new Foo();$o->bar();

PHP Landclass Foo {public: Foo() {} ~Foo() {}

int value = 5;}

Planet C++

int64_t HHVM_METHOD(Foo,bar){ auto data = Native::data<Foo>(this_);

return data->value;}

Time Vortex!?!?!

C++ object !== PHP object

Page 69: Diving into HHVM Extensions (Brno PHP Conference 2015)

HHVM Universe

<?php

$o = new Foo();$o->bar();

PHP Landclass Foo {public: Foo() {} ~Foo() {}

int value = 5;}

Planet C++

int64_t HHVM_METHOD(Foo,bar){ auto data = Native::data<Foo>(this_);

return data->value;}

Time Vortex!?!?!

C++ object !== PHP object

Page 70: Diving into HHVM Extensions (Brno PHP Conference 2015)

HHVM Universe

<?php

$o = new Foo();$o->bar();

PHP Landclass Foo {public: Foo() {} ~Foo() {}

int value = 5;}

Planet C++

int64_t HHVM_METHOD(Foo,bar){ auto data = Native::data<Foo>(this_);

return data->value;}

Time Vortex!?!?!

C++ object !== PHP object

Page 71: Diving into HHVM Extensions (Brno PHP Conference 2015)

HHVM Universe

<?php

$o = new Foo();$o->bar();

PHP Landclass Foo {public: Foo() {} ~Foo() {}

int value = 5;}

Planet C++

int64_t HHVM_METHOD(Foo,bar){ auto data = Native::data<Foo>(this_);

return data->value;}

Time Vortex!?!?!

C++ object !== PHP object

Page 72: Diving into HHVM Extensions (Brno PHP Conference 2015)

this slide is intentionally left blank

Page 73: Diving into HHVM Extensions (Brno PHP Conference 2015)

ext_foo.php<?hh

class Foo {

private int $value

public function bar(): int

{

return $this->value;

}

}

Page 74: Diving into HHVM Extensions (Brno PHP Conference 2015)

Demo?

Page 75: Diving into HHVM Extensions (Brno PHP Conference 2015)
Page 76: Diving into HHVM Extensions (Brno PHP Conference 2015)

source: http://goo.gl/7gWfNz

Page 77: Diving into HHVM Extensions (Brno PHP Conference 2015)

Resources

● OpenGL Tutorial○ http://www.opengl-tutorial.org/

● HHVM Example Extension○ https://github.com/hhvm/extension-example

● Sara Golemon - HHVM extension blog series○ http://blog.golemon.com/2015/01/hhvm-extension-writing-part-iii.html

● Derick Rethans’ extension API cookbook○ https://github.com/derickr/hhvm-hni-cookbook

● The official API documentation○ https://github.com/facebook/hhvm/wiki/Extension%20API

● Journey of a Thousand Bytecodes○ http://hhvm.com/blog/6323/the-journey-of-a-thousand-bytecodes

Page 78: Diving into HHVM Extensions (Brno PHP Conference 2015)

Any questions? :)

https://joind.in/16263James Titcumb @asgrim