Святослав Молодских, ресурс-менеджер, Центр Высоких Технологий Это будет почти технический доклад с привкусом языка C и структур.
Новый доклад (1)
View Slide
Кто я?• Святослав Молодских• Работаю 8 лет в одной компании, большую частьвремени программистом• Перешёл на тёмную сторону
Структураstruct point {int x;int y;};
Указатель
Объединениеunion Data {int i;float f;char str[20];};
Контейнеры
zval// zend_types.htypedef struct _zval_struct zval;// zend.hstruct _zval_struct {/* Variable information */zvalue_value value; /* value */zend_uint refcount__gc;zend_uchar type;/* active type */zend_uchar is_ref__gc;};
zvalue_value// zend.htypedef union _zvalue_value {long lval; /* long value */double dval; /* double value */struct {char *val;int len;} str;HashTable *ht; /* hash table value */zend_object_value obj;zend_ast *ast;} zvalue_value;
Снова zval// zend.hstruct _zval_struct {/* Variable information */zvalue_value value; /* value */zend_uint refcount__gc;zend_uchar type;/* active type */zend_uchar is_ref__gc;};
"foo": {"type": "string","value": {"str": {"val": "foo","len": 3}},"refcount": 1,"is_ref": 0}$foo = 'foo';
"foo", "bar": {"type": "string","value": {"str": {"val": "foo","len": 3}},"refcount": 2,"is_ref": 0}$foo = ‘foo';$bar = $foo;
"bar": {"type": "string","value": {"str": {"val": "foo","len": 3}},"refcount": 1,"is_ref": 0}$foo = 'foo';$bar = $foo;unset($foo);
foo.value.refcount --if refcount == 0del(value)unset($foo);
$foo = 'foo';$bar = $foo;$bar .= 'bar';"foo": {"type": "string","value": {"str": {"val": "foo","len": 3}},"refcount": 1,"is_ref": 0},"bar": {"type": "string","value": {"str": {"val": "foobar","len": 6}},"refcount": 1,"is_ref": 0}
COW
Copy-on-write
$foo = 'foo';$bar = $foo;$baz = &$foo;"baz", "foo": {"type": "string","value": {"str": {"val": "foo","len": 3}},"refcount": 2,"is_ref": 1},"bar": {"type": "string","value": {"str": {"val": "foo","len": 3}},"refcount": 1,"is_ref": 0}
$foo = 'foo';$bar = $foo;$baz = &$foo;$spam = $foo;"baz", "foo": {"type": "string","value": {"str": {"val": "foo","len": 3}},"refcount": 2,"is_ref": 1},"bar": {"type": "string","value": {"str": {"val": "foo","len": 3}},"refcount": 1,"is_ref": 0},"spam": {"type": "string","value": {"str": {"val": "foo","len": 3}},"refcount": 1,"is_ref": 0}
Медленно$foo = [1];$bar = &$foo;count($bar);
PHP 7/* regular data types */#define IS_UNDEF 0#define IS_NULL 1#define IS_FALSE 2#define IS_TRUE 3#define IS_LONG 4#define IS_DOUBLE 5#define IS_STRING 6#define IS_ARRAY 7#define IS_OBJECT 8#define IS_RESOURCE 9#define IS_REFERENCE 10/* constant expressions */#define IS_CONSTANT 11#define IS_CONSTANT_AST 12
zvalstruct _zval_struct {zend_value value; /* value */union {struct {ZEND_ENDIAN_LOHI_4(zend_uchar type, /* active type */zend_uchar type_flags,zend_uchar const_flags,zend_uchar reserved) /* call info for EX(This) */} v;uint32_t type_info;} u1;union {uint32_t var_flags;uint32_t next; /* hash collision chain */uint32_t cache_slot; /* literal cache slot */uint32_t lineno; /* line number (for ast nodes) */uint32_t num_args; /* arguments number for EX(This) */uint32_t fe_pos; /* foreach position */uint32_t fe_iter_idx; /* foreach iterator index */} u2;};
zend_valuetypedef union _zend_value {zend_long lval; /* long value */double dval; /* double value */zend_refcounted *counted;zend_string *str;zend_array *arr;zend_object *obj;zend_resource *res;zend_reference *ref;zend_ast_ref *ast;zval *zv;void *ptr;zend_class_entry *ce;zend_function *func;struct {uint32_t w1;uint32_t w2;} ww;} zend_value;
zend_refcountedtypedef struct _zend_refcounted zend_refcounted;struct _zend_refcounted {zend_refcounted_h gc;};typedef struct _zend_refcounted_h {uint32_t refcount; /* reference counter 32-bit */union {struct {ZEND_ENDIAN_LOHI_3(zend_uchar type,zend_uchar flags, /* used for strings & objects */uint16_t gc_info) /* keeps GC root number (or 0) and color */} v;uint32_t type_info;} u;} zend_refcounted_h;
zend_referencetypedef struct _zend_reference zend_reference;struct _zend_reference {zend_refcounted_h gc;zval val;};
$foo$foo = []; zend_array_1(refcount=1, val=[])$bar = $foo; $foo, $bar zend_array_1(refcount=2, val=[])$baz = $bar; $foo, $bar, $baz zend_array_1(refcount=3, val=[])$spam = &$baz; $foo, $bar zend_array_1(refcount=3, val=[])$baz, $spam zend_reference_1(refcount=2)$spam[] = 1; $foo, $bar zend_array_1(refcount=2, val=[])$baz, $spam zend_reference_1(refcount=2)zend_array_1(refcount=1, val=[1])
Вопросы?