1 /*
2 +----------------------------------------------------------------------+
3 | Zend Engine |
4 +----------------------------------------------------------------------+
5 | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 2.00 of the Zend license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.zend.com/license/2_00.txt. |
11 | If you did not receive a copy of the Zend license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@zend.com so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Arnaud Le Blanc <arnaud.lb@gmail.com> |
16 +----------------------------------------------------------------------+
17 */
18
19 #ifndef ZEND_LAZY_OBJECT_H
20 #define ZEND_LAZY_OBJECT_H
21
22 #include "Zend/zend_types.h"
23
24 /* Lazy object is a lazy proxy object */
25 #define ZEND_LAZY_OBJECT_STRATEGY_PROXY (1<<0)
26
27 /* Lazy object is a lazy ghost object */
28 #define ZEND_LAZY_OBJECT_STRATEGY_GHOST (1<<1)
29
30 /* Lazy object is initialized (info.u is an instance) */
31 #define ZEND_LAZY_OBJECT_INITIALIZED (1<<2)
32
33 /* Serialization skips initialization */
34 #define ZEND_LAZY_OBJECT_SKIP_INITIALIZATION_ON_SERIALIZE (1<<3)
35
36 /* Do not call destructor when making existing object lazy */
37 #define ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR (1<<4)
38
39 #define ZEND_LAZY_OBJECT_USER_MASK ( \
40 ZEND_LAZY_OBJECT_SKIP_INITIALIZATION_ON_SERIALIZE | \
41 ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR \
42 )
43
44 #define ZEND_LAZY_OBJECT_STRATEGY_MASK ( \
45 ZEND_LAZY_OBJECT_STRATEGY_PROXY | \
46 ZEND_LAZY_OBJECT_STRATEGY_GHOST \
47 )
48
49 typedef uint8_t zend_lazy_object_flags_t;
50
51 typedef struct _zend_lazy_objects_store {
52 /* object handle -> *zend_lazy_object_info */
53 HashTable infos;
54 } zend_lazy_objects_store;
55
56 typedef struct _zend_property_info zend_property_info;
57 typedef struct _zend_fcall_info zend_fcall_info;
58 typedef struct _zend_fcall_info_cache zend_fcall_info_cache;
59
60 ZEND_API bool zend_class_can_be_lazy(zend_class_entry *ce);
61 ZEND_API zend_object *zend_object_make_lazy(zend_object *obj,
62 zend_class_entry *class_type, zval *initializer_zv,
63 zend_fcall_info_cache *initializer_fcc, zend_lazy_object_flags_t flags);
64 ZEND_API zend_object *zend_lazy_object_init(zend_object *obj);
65 ZEND_API zend_object *zend_lazy_object_mark_as_initialized(zend_object *obj);
66
67 void zend_lazy_objects_init(zend_lazy_objects_store *store);
68 void zend_lazy_objects_destroy(zend_lazy_objects_store *store);
69 zval* zend_lazy_object_get_initializer_zv(zend_object *obj);
70 zend_object *zend_lazy_object_get_instance(zend_object *obj);
71 zend_lazy_object_flags_t zend_lazy_object_get_flags(zend_object *obj);
72 void zend_lazy_object_del_info(zend_object *obj);
73 ZEND_API HashTable *zend_lazy_object_get_properties(zend_object *object);
74 zend_object *zend_lazy_object_clone(zend_object *old_obj);
75 HashTable *zend_lazy_object_debug_info(zend_object *object, int *is_temp);
76 HashTable *zend_lazy_object_get_gc(zend_object *zobj, zval **table, int *n);
77 bool zend_lazy_object_decr_lazy_props(zend_object *obj);
78 void zend_lazy_object_realize(zend_object *obj);
79 ZEND_API zend_property_info *zend_lazy_object_get_property_info_for_slot(zend_object *obj, zval *slot);
80
zend_object_is_lazy(zend_object * obj)81 static zend_always_inline bool zend_object_is_lazy(zend_object *obj)
82 {
83 return (OBJ_EXTRA_FLAGS(obj) & (IS_OBJ_LAZY_UNINITIALIZED | IS_OBJ_LAZY_PROXY));
84 }
85
zend_object_is_lazy_proxy(zend_object * obj)86 static zend_always_inline bool zend_object_is_lazy_proxy(zend_object *obj)
87 {
88 return (OBJ_EXTRA_FLAGS(obj) & IS_OBJ_LAZY_PROXY);
89 }
90
zend_lazy_object_initialized(zend_object * obj)91 static zend_always_inline bool zend_lazy_object_initialized(zend_object *obj)
92 {
93 return !(OBJ_EXTRA_FLAGS(obj) & IS_OBJ_LAZY_UNINITIALIZED);
94 }
95
96 /* True if accessing a lazy prop on obj mandates a call to
97 * zend_lazy_object_init() */
zend_lazy_object_must_init(zend_object * obj)98 static zend_always_inline bool zend_lazy_object_must_init(zend_object *obj)
99 {
100 return zend_object_is_lazy(obj);
101 }
102
zend_lazy_object_initialize_on_serialize(zend_object * obj)103 static inline bool zend_lazy_object_initialize_on_serialize(zend_object *obj)
104 {
105 return !(zend_lazy_object_get_flags(obj) & ZEND_LAZY_OBJECT_SKIP_INITIALIZATION_ON_SERIALIZE);
106 }
107
108 #endif /* ZEND_LAZY_OBJECT_H */
109