1/* Copyright JS Foundation and other contributors, http://js.foundation 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "jerryscript-ext/handler.h" 17 18/** 19 * Register a JavaScript function in the global object. 20 * 21 * Note: 22 * returned value must be freed with jerry_release_value, when it is no longer needed. 23 * 24 * @return true value - if the operation was successful, 25 * error - otherwise. 26 */ 27jerry_value_t 28jerryx_handler_register_global (const jerry_char_t *name_p, /**< name of the function */ 29 jerry_external_handler_t handler_p) /**< function callback */ 30{ 31 jerry_value_t global_obj_val = jerry_get_global_object (); 32 jerry_value_t function_name_val = jerry_create_string (name_p); 33 jerry_value_t function_val = jerry_create_external_function (handler_p); 34 35 jerry_value_t result_val = jerry_set_property (global_obj_val, function_name_val, function_val); 36 37 jerry_release_value (function_val); 38 jerry_release_value (function_name_val); 39 jerry_release_value (global_obj_val); 40 41 return result_val; 42} /* jerryx_handler_register_global */ 43 44/** 45 * Set multiple properties on a target object. 46 * 47 * The properties are an array of (name, property value) pairs and 48 * this list must end with a (NULL, 0) entry. 49 * 50 * Notes: 51 * - Each property value in the input array is released after a successful property registration. 52 * - The property name must be a zero terminated UTF-8 string. 53 * - There should be no '\0' (NULL) character in the name excluding the string terminator. 54 * - The method `jerryx_release_property_entry` must be called if there is any failed registration 55 * to release the values in the entries array. 56 * 57 * @return `jerryx_register_result` struct - if everything is ok with the (undefined, property entry count) values. 58 * In case of error the (error object, registered property count) pair. 59 */ 60jerryx_register_result 61jerryx_set_properties (const jerry_value_t target_object, /**< target object */ 62 const jerryx_property_entry entries[]) /**< array of method entries */ 63{ 64#define JERRYX_SET_PROPERTIES_RESULT(VALUE, IDX) ((jerryx_register_result) { VALUE, IDX }) 65 uint32_t idx = 0; 66 67 if (entries == NULL) 68 { 69 return JERRYX_SET_PROPERTIES_RESULT (jerry_create_undefined (), 0); 70 } 71 72 for (; (entries[idx].name != NULL); idx++) 73 { 74 const jerryx_property_entry *entry = &entries[idx]; 75 76 jerry_value_t prop_name = jerry_create_string_from_utf8 ((const jerry_char_t *) entry->name); 77 jerry_value_t result = jerry_set_property (target_object, prop_name, entry->value); 78 79 jerry_release_value (prop_name); 80 81 // By API definition: 82 // The jerry_set_property returns TRUE if there is no problem 83 // and error object if there is any problem. 84 // Thus there is no need to check if the boolean value is false or not. 85 if (!jerry_value_is_boolean (result)) 86 { 87 return JERRYX_SET_PROPERTIES_RESULT (result, idx); 88 } 89 90 jerry_release_value (entry->value); 91 jerry_release_value (result); 92 } 93 94 return JERRYX_SET_PROPERTIES_RESULT (jerry_create_undefined (), idx); 95#undef JERRYX_SET_PROPERTIES_RESULT 96} /* jerryx_set_properties */ 97 98/** 99 * Release all jerry_value_t in a jerryx_property_entry array based on 100 * a previous jerryx_set_properties call. 101 * 102 * In case of a successful registration it is safe to call this method. 103 */ 104void 105jerryx_release_property_entry (const jerryx_property_entry entries[], /**< list of property entries */ 106 const jerryx_register_result register_result) /**< previous result of registration */ 107{ 108 if (entries == NULL) 109 { 110 return; 111 } 112 113 for (uint32_t idx = register_result.registered; entries[idx].name != NULL; idx++) 114 { 115 jerry_release_value (entries[idx].value); 116 } 117} /* jerryx_release_property_entry */ 118 119/** 120 * Set a property to a specified value with a given name. 121 * 122 * Notes: 123 * - The operation performed is the same as what the `jerry_set_property` method. 124 * - The property name must be a zero terminated UTF-8 string. 125 * - There should be no '\0' (NULL) character in the name excluding the string terminator. 126 * - Returned value must be freed with jerry_release_value, when it is no longer needed. 127 * 128 * @return true value - if the operation was successful 129 * thrown error - otherwise 130 */ 131jerry_value_t 132jerryx_set_property_str (const jerry_value_t target_object, /**< target object */ 133 const char *name, /**< property name */ 134 const jerry_value_t value) /**< value to set */ 135{ 136 jerry_value_t property_name_val = jerry_create_string_from_utf8 ((const jerry_char_t *) name); 137 jerry_value_t result_val = jerry_set_property (target_object, property_name_val, value); 138 139 jerry_release_value (property_name_val); 140 141 return result_val; 142} /* jerryx_set_property_str */ 143 144/** 145 * Get a property value of a specified object. 146 * 147 * Notes: 148 * - The operation performed is the same as what the `jerry_get_property` method. 149 * - The property name must be a zero terminated UTF-8 string. 150 * - There should be no '\0' (NULL) character in the name excluding the string terminator. 151 * - Returned value must be freed with jerry_release_value, when it is no longer needed. 152 * 153 * @return jerry_value_t - the property value 154 */ 155jerry_value_t 156jerryx_get_property_str (const jerry_value_t target_object, /**< target object */ 157 const char *name) /**< property name */ 158{ 159 jerry_value_t prop_name = jerry_create_string_from_utf8 ((const jerry_char_t *) name); 160 jerry_value_t result_val = jerry_get_property (target_object, prop_name); 161 jerry_release_value (prop_name); 162 163 return result_val; 164} /* jerryx_get_property_str */ 165 166/** 167 * Check if a property exists on an object. 168 * 169 * Notes: 170 * - The operation performed is the same as what the `jerry_has_property` method. 171 * - The property name must be a zero terminated UTF-8 string. 172 * - There should be no '\0' (NULL) character in the name excluding the string terminator. 173 * 174 * @return true - if the property exists on the given object. 175 * false - if there is no such property or there was an error accessing the property. 176 */ 177bool 178jerryx_has_property_str (const jerry_value_t target_object, /**< target object */ 179 const char *name) /**< property name */ 180{ 181 bool has_property = false; 182 183 jerry_value_t prop_name = jerry_create_string_from_utf8 ((const jerry_char_t *) name); 184 jerry_value_t has_prop_val = jerry_has_property (target_object, prop_name); 185 186 if (!jerry_value_is_error (has_prop_val)) 187 { 188 has_property = jerry_get_boolean_value (has_prop_val); 189 } 190 191 jerry_release_value (has_prop_val); 192 jerry_release_value (prop_name); 193 194 return has_property; 195} /* jerryx_has_property_str */ 196