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