• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1## Reference counting in JerryScript
2
3In JerryScript all `jerry_value_t` values are independent
4references to internal objects. Values returned by JerryScript
5API functions are always live references and must be released
6by `jerry_release_value`.
7
8```c
9  jerry_value_t global = jerry_get_global_object ();
10
11  /* The value stored in the 'global' variable contains a live
12   * reference to the global object. The system also keeps its
13   * own live reference to the global object. These two references
14   * are independent, and both must be destroyed before the global
15   * object can be freed. */
16
17  jerry_release_value (global);
18
19  /* Without jerry_release_value() the global object will not
20   * be freed even by jerry_cleanup(). After the reference
21   * is released it becomes a dead reference and cannot be
22   * used anymore. */
23```
24
25Multiple references might refer to the same internal object
26even though their `jerry_value_t` representation might be different.
27
28```c
29  jerry_value_t pi_ref1 = jerry_create_number (3.14);
30  jerry_value_t pi_ref2 = jerry_acquire_value (pi_ref1);
31
32  /* Both pi_ref1 and pi_ref2 refer to the same 3.14 value
33   * although they might not be equal in C (pi_ref1 != pi_ref2). */
34
35  /* Both references must be released. */
36  jerry_release_value (pi_ref1);
37  jerry_release_value (pi_ref2);
38```
39
40Releasing the same `jerry_value_t` twice to release two live
41references is not allowed and it might cause crashes. Hence the
42following code is an **INCORRECT WAY** of releasing the 3.14 value.
43
44```c
45  jerry_release_value (pi_ref1);
46  jerry_release_value (pi_ref1);
47```
48
49JerryScript API functions returning with a `jerry_value_t` always
50return with a new live reference. Passing a `jerry_value_t` to
51an API function never releases its reference (unless explicitly
52stated in the documentation). The next example shows this
53behaviour through property getting and setting.
54
55```c
56  jerry_value_t prop_value = jerry_get_property (...);
57
58  /* The prop_value must be released later because both the base
59   * object and the prop_value have an independent reference to
60   * the same JavaScript value. When the operation fails, the
61   * prop_value contains a live reference to an error object.
62   * This reference must be released as well. */
63
64  if (jerry_value_is_error (prop_value))
65  {
66    /* Errors can be handled here. */
67  }
68  else
69  {
70    /* The application has a live reference to the property
71     * value even if the base object is freed by the garbage
72     * collector. */
73  }
74
75  /* The prop_value must be released. */
76  jerry_release_value (prop_value);
77
78  /* Property setting is the same. */
79
80  jerry_value_t new_prop_value = jerry_create_number (2.718);
81  jerry_value_t result = jerry_set_property (..., new_prop_value);
82
83  /* If the property set is successful, a new reference is created
84   * for the value referenced by new_prop_value. The new_prop_value
85   * reference must be released regardless of whether the operation
86   * is successful. */
87
88  /* The new_prop_value can be passed to other JerryScript API
89   * functions before the jerry_release_value () call. */
90
91  jerry_release_value (new_prop_value);
92
93  /* The reference stored in the 'result' variable is live whether
94   * the operation is successful or not, and must also be freed. */
95
96  if (jerry_value_is_error (result))
97  {
98    /* Errors can be handled here. */
99  }
100  else
101  {
102    /* A reference to a true primitive value is returned. */
103  }
104
105  jerry_release_value (result);
106```
107
108The simplest form of setting a property without error checking
109is the following:
110
111```c
112  /* There are no 'ifs' in this snippet. */
113  jerry_release_value (jerry_set_property (..., new_prop_value));
114  jerry_release_value (new_prop_value);
115```
116
117The reference returned by a `jerry_external_handler_t` callback
118transfers the ownership of the live reference. Otherwise the
119referenced object could be freed by the garbage collector.
120
121```c
122jerry_value_t my_external_handler (const jerry_value_t function_obj,
123                                   const jerry_value_t this_val,
124                                   const jerry_value_t args_p[],
125                                   const jerry_length_t args_count
126{
127  /* Do not release function_obj, this_val, and args_p because
128   * these references are automatically released after the handler
129   * is returned. This approach reduces code size which is useful
130   * on embedded systems. However you can create other references
131   * to them by calling jerry_acquire_value () if needed. */
132
133  /* Since the ownership of the reference is transferred to the
134   * caller the following snippet is valid. */
135
136  /* If the value to be returned is needed for other purposes the
137   * jerry_acquire_value () can be used to create new references. */
138  return jerry_create_string (...);
139}
140```
141
142Duplicating a `jerry_value_t` in C does not create another live reference.
143
144```c
145  jerry_value_t undef = jerry_create_undefined ();
146  jerry_value_t undef2 = undef;
147
148  /* Releasing either undef or undef2 is valid but not both.
149   * After the release both references become dead (invalid). */
150  jerry_release_value (undef2);
151
152  /* Dead references can be reassigned again. */
153  undef = jerry_create_boolean (true);
154```
155
156References can be duplicated in C as long as only one of them is freed.
157
158```c
159  jerry_value_t a = jerry_create_boolean (true);
160
161  jerry_value_t b = a;
162  jerry_value_t c = a;
163
164  /* A new reference is assigned to 'a'. */
165  a = jerry_create_boolean (false);
166
167  [...]
168
169  jerry_release_value (a);
170  /* The 'a' (boolean false) reference becomes dead (invalid). */
171
172  jerry_release_value (c);
173  /* Both 'b' and 'c' (boolean true) references become dead. */
174
175  /* Since all references are released, no memory leak occurs. */
176```
177