• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Common methods to handle properties
2
3The `jerryscript-ext/handler.h` header defines a set of convenience methods
4which makes the property access a bit straightforward.
5
6## jerryx_set_property_str
7
8**Summary**
9
10Set a property on a target object with a given name.
11
12*Note*:
13- The property name must be a zero terminated UTF-8 string.
14- There should be no '\0' (NULL) character in the name excluding the string terminator.
15- Returned value must be freed with [jerry_release_value](#jerry_release_value) when it
16  is no longer needed.
17
18
19**Prototype**
20
21```c
22jerry_value_t
23jerryx_set_property_str (const jerry_value_t target_object,
24                         const char *name,
25                         const jerry_value_t value);
26```
27
28- `target_object` - the object where the property should be set
29- `name` - name of the property
30- `value` - property value to be set
31- return value
32  - JS true value, if success
33  - thrown error, if there was a problem setting the property
34
35**Example**
36
37[doctest]: # ()
38
39```c
40#include "jerryscript.h"
41#include "jerryscript-ext/handler.h"
42
43int
44main (int argc, char **argv)
45{
46  jerry_init (JERRY_INIT_EMPTY);
47
48  jerry_value_t global = jerry_get_global_object ();
49
50  jerry_value_t value = jerry_create_number (3.3);
51  jerry_value_t result = jerryx_set_property_str (global, "value", value);
52  if (jerry_value_is_error (result))
53  {
54    /* The error type/reason can be extracted via the `jerry_get_value_from_error` method */
55    printf ("Error during property configuration\r\n");
56  }
57
58  jerry_release_value (result);
59  jerry_release_value (value);
60  jerry_release_value (global);
61  jerry_cleanup();
62
63  return 0;
64}
65```
66
67## jerryx_get_property_str
68
69**Summary**
70
71Get the value of a property from the specified object with the given name.
72
73*Notes*:
74- The property name must be a zero terminated UTF-8 string.
75- There should be no '\0' (NULL) character in the name excluding the string terminator.
76- Returned value must be freed with [jerry_release_value](#jerry_release_value) when it
77  is no longer needed.
78
79
80**Prototype**
81
82```
83jerry_value_t
84jerryx_get_property_str (const jerry_value_t target_object,
85                         const char *name);
86```
87
88- `target_object` - object on which the property name is accessed
89- `name` - property name as an UTF-8 `char*`
90- return value
91  - value of property, if success
92  - thrown error, if there was a problem accessing the property
93
94**Example**
95
96[doctest]: # ()
97
98```c
99#include "jerryscript.h"
100#include "jerryscript-ext/handler.h"
101
102int
103main (int argc, char **argv)
104{
105  jerry_init (JERRY_INIT_EMPTY);
106
107  jerry_value_t global = jerry_get_global_object ();
108
109  jerry_value_t math_object = jerryx_get_property_str (global, "Math");
110
111  /* use math_object */
112
113  jerry_release_value (math_object);
114  jerry_release_value (global);
115  jerry_cleanup();
116
117  return 0;
118}
119```
120
121## jerryx_has_property_str
122
123**Summary**
124
125Check if a property exists on an object.
126
127*Notes*:
128- The operation performed is the same as what the `jerry_has_property` method.
129- The property name must be a zero terminated UTF-8 string.
130- There should be no '\0' (NULL) character in the name excluding the string terminator.
131
132
133**Prototype**
134
135```
136bool
137jerryx_has_property_str (const jerry_value_t target_object,
138                         const char *name);
139```
140
141- `target_object` - object on which the property name is accessed
142- `name` - property name as an UTF-8 `char*`
143- return value
144  - true, if the given property name exsits on the object
145  - false, if there is no such property name or there was an error accessing the property
146
147**Example**
148
149[doctest]: # ()
150
151```c
152#include "jerryscript.h"
153#include "jerryscript-ext/handler.h"
154
155int
156main (int argc, char **argv)
157{
158  jerry_init (JERRY_INIT_EMPTY);
159
160  jerry_value_t global = jerry_get_global_object ();
161
162  bool have_math = jerryx_has_property_str (global, "Math");
163
164  jerry_release_value (global);
165  jerry_cleanup();
166
167  return have_math ? 0 : 1;
168}
169```
170
171# Utility to register multiple properties in bulk
172
173In some cases it is useful to register multiple properties for a given object
174for this the following utility structures and methods are provided.
175
176## jerryx_property_entry
177
178**Summary**
179
180Structure to define an array of properties with `name` and `value` fields which
181can be registered to a target object.
182
183The engine must be initialied before specifying the `jerry_value_t` in the struct.
184
185
186**Prototype**
187
188```c
189typedef struct {
190  const char *name;
191  jerry_value_t value;
192} jerryx_function_list_entry;
193```
194
195**See also**
196
197- [jerryx_set_properties](#jerryx_set_properties)
198
199
200## jerryx_register_result
201
202**Summary**
203
204Structure returned as the result of the [jerryx_set_properties](#jerryx_set_properties) operation.
205The `result` field will either be a JavaScript undefined value or an error object.
206In every case the `registered` field is used to indicated the number of
207successfully registered methods.
208
209This must be passed for the [jerryx_release_property_entry](#jerryx_release_property_entry) method
210after the property registration.
211
212If any error occured during the property registration the `result` field of the structure
213must be manually released after processing the error value.
214
215**Prototype**
216
217```c
218typedef struct {
219  jerry_value_t result;
220  uint32_t registered;
221} jerryx_register_result;
222```
223
224**See also**
225
226- [jerryx_set_properties](#jerryx_set_properties)
227- [jerryx_release_property_entry](#jerryx_release_property_entry)
228
229
230## jerryx_set_properties
231
232**Summary**
233
234Set multiple properties on a target object.
235
236The properties are an array of (name, jerry_value_t) pairs and
237this list must end with a (NULL, 0) entry.
238
239Important notes:
240* Each property value in the input array is released after a successful property registration.
241* The method [jerryx_release_property_entry](#jerryx_release_property_entry) must be called if there is any failed registration
242  to release the values in the entries array.
243  It is safe to call this cleanup method in every case not just in case of failure.
244* If the error value is reported via the result it must be freed manually.
245
246**Prototype**
247
248```c
249jerryx_register_result
250jerryx_set_properties (const jerry_value_t target_object,
251                       const jerryx_property_entry entries[]);
252```
253
254- `target_object` - object on which the entries will be set.
255- `entries` - array of (name, jerry_value_t) pairs.
256- return a [jerryx_register_result](#jerryx_register_result).
257   - if everything is ok, the struct's `result` field is set to a JS undefined value.
258   - otherwise the `result` field is an error object indicating the problem.
259   - in every case the `registered` field contains the number of successfully registered properties.
260
261**Example**
262
263[doctest]: # ()
264
265```c
266#include "jerryscript.h"
267#include "jerryscript-ext/handler.h"
268
269static jerry_value_t
270handler (const jerry_value_t function_obj,
271         const jerry_value_t this_val,
272         const jerry_value_t args_p[],
273         const jerry_length_t args_cnt)
274{
275  printf ("native handler called!\n");
276
277  return jerry_create_boolean (true);
278}
279
280int
281main (int argc, char **argv)
282{
283  jerry_init (JERRY_INIT_EMPTY);
284
285  jerryx_property_entry methods[] =
286  {
287    { "demo", jerry_create_external_function (handler) },
288    { NULL, 0 },
289  };
290
291  jerry_value_t global = jerry_get_global_object ();
292  jerryx_register_result reg = jerryx_set_properties (global, methods);
293  /* if `reg.result` is undefined all methods are registered */
294  if (jerry_value_is_error (reg.result))
295  {
296    printf ("Only registered %d properties\r\n", reg.registered);
297    /* clean up not registered property values */
298    jerryx_release_property_entry (methods, reg);
299
300    /* clean up the error */
301    jerry_release_value (reg.result);
302  }
303
304  jerry_release_value (global);
305
306  jerry_cleanup();
307
308  return 0;
309}
310```
311
312**Convenience macros**
313
314To make property registration convenient, there are a set of macros to use
315when setting a property entry:
316
317* `JERRYX_PROPERTY_NUMBER(NAME, NUMBER)` - creates a number entry.
318* `JERRYX_PROPERTY_STRING(NAME, STR)` - creates an UTF-8 string entry. This string must be zero terminated.
319* `JERRYX_PROPERTY_STRING_SZ(NAME, STR, SIZE)` - creates an UTF-8 string entry using only `SIZE` bytes from the string.
320* `JERRYX_PROPERTY_BOOLEAN(NAME, VALUE)` - creates a boolean entry.
321* `JERRYX_PROPERTY_FUNCTION(NAME, NATIVE)` - creates a native C function entry.
322* `JERRYX_PROPERTY_UNDEFINED(NAME)` - creates an undefined property entry.
323* `JERRYX_PROPERTY_LIST_END()` - indicates the end of the property list.
324
325**Example usage of Convenience macros**
326
327[doctest]: # ()
328
329```c
330#include "jerryscript.h"
331#include "jerryscript-ext/handler.h"
332
333static jerry_value_t
334handler (const jerry_value_t function_obj,
335         const jerry_value_t this_val,
336         const jerry_value_t args_p[],
337         const jerry_length_t args_cnt)
338{
339  printf ("native handler called!\n");
340
341  return jerry_create_boolean (true);
342}
343
344int
345main (int argc, char **argv)
346{
347  jerry_init (JERRY_INIT_EMPTY);
348
349  /**
350   * Create a array of properties to be registered.
351   * This must be done after initializing the engine as creating `jerry_value_t`
352   * elements are invalid before `jerry_init`.
353   */
354  jerryx_property_entry methods[] =
355  {
356    JERRYX_PROPERTY_FUNCTION ("demo", handler),
357    JERRYX_PROPERTY_NUMBER ("test_num", 2.3),
358    JERRYX_PROPERTY_UNDEFINED ("this_is_undefined"),
359    JERRYX_PROPERTY_LIST_END(),
360  };
361
362  jerry_value_t global = jerry_get_global_object ();
363  jerryx_register_result reg = jerryx_set_properties (global, methods);
364  /* if `reg.result` is undefined all methods are registered */
365  if (jerry_value_is_error (reg.result))
366  {
367    printf ("Only registered %d properties\r\n", reg.registered);
368    /* clean up not registered property values */
369    jerryx_release_property_entry (methods, reg);
370
371    /* clean up the error */
372    jerry_release_value (reg.result);
373  }
374
375  jerry_release_value (global);
376
377  jerry_cleanup();
378
379  return 0;
380}
381```
382
383
384**See also**
385
386- [jerryx_property_entry](#jerryx_property_entry)
387- [jerryx_release_property_entry](#jerryx_release_property_entry)
388- [jerryx_register_result](#jerryx_register_result)
389
390## jerryx_release_property_entry
391
392**Summary**
393
394Release all `jerry_value_t` in a `jerryx_property_entry` array based on a previous [jerryx_set_properties](#jerryx_set_properties) call
395and also the error value (if any) in the `jerryx_register_result` structure.
396In case of a successful registration it is safe to call this method.
397
398After the method call the `ęntries` array should not be used as all values are released.
399
400**Prototype**
401
402```
403void
404jerryx_release_property_entry (const jerryx_property_entry entries[],
405                               const jerryx_register_result register_result);
406```
407
408- `entires` - array of [jerryx_property_entry](#jerryx_property_entry).
409- `register_result` - result of a previous [jerryx_set_properties](#jerryx_set_properties) call.
410
411**Example**
412
413For example usage see [jerryx_set_properties](#jerryx_set_properties).
414
415
416#  Common external function handlers
417
418## jerryx_handler_assert_fatal
419
420**Summary**
421
422Hard assert for scripts. The routine calls `jerry_port_fatal` on assertion failure.
423
424If the `JERRY_FEATURE_LINE_INFO` runtime feature is enabled (build option: `JERRY_LINE_INFO`)
425a backtrace is also printed out.
426
427**Prototype**
428
429```c
430jerry_value_t
431jerryx_handler_assert_fatal (const jerry_value_t func_obj_val, const jerry_value_t this_p,
432                             const jerry_value_t args_p[], const jerry_length_t args_cnt);
433```
434
435- `func_obj_val` - the function object that was called (unused).
436- `this_p` - the `this` value of the call (unused).
437- `args_p` - the array of function arguments.
438- `args_cnt` - the number of function arguments.
439- return value - `jerry_value_t` representing boolean true, if only one argument
440  was passed and that argument was a boolean true. Note that the function does
441  not return otherwise.
442
443**See also**
444
445- [jerryx_handler_register_global](#jerryx_handler_register_global)
446
447
448## jerryx_handler_assert_throw
449
450**Summary**
451
452Soft assert for scripts. The routine throws an error on assertion failure.
453
454**Prototype**
455
456```c
457jerry_value_t
458jerryx_handler_assert_throw (const jerry_value_t func_obj_val, const jerry_value_t this_p,
459                             const jerry_value_t args_p[], const jerry_length_t args_cnt);
460```
461
462- `func_obj_val` - the function object that was called (unused).
463- `this_p` - the `this` value of the call (unused).
464- `args_p` - the array of function arguments.
465- `args_cnt` - the number of function arguments.
466- return value - `jerry_value_t` representing boolean true, if only one argument
467  was passed and that argument was a boolean true, an error otherwise.
468
469**See also**
470
471- [jerryx_handler_register_global](#jerryx_handler_register_global)
472
473
474## jerryx_handler_assert
475
476**Summary**
477
478An alias to `jerryx_handler_assert_fatal`.
479
480**See also**
481
482- [jerryx_handler_assert_fatal](#jerryx_handler_assert_fatal)
483
484
485## jerryx_handler_gc
486
487**Summary**
488
489Expose garbage collector to scripts. If the first argument of the function
490is logical true, it performs a high pressure gc. Otherwise a low pressure
491gc is performed, which is also the default if no parameters passed.
492
493**Prototype**
494
495```c
496jerry_value_t
497jerryx_handler_gc (const jerry_value_t func_obj_val, const jerry_value_t this_p,
498                   const jerry_value_t args_p[], const jerry_length_t args_cnt);
499```
500
501- `func_obj_val` - the function object that was called (unused).
502- `this_p` - the `this` value of the call (unused).
503- `args_p` - the array of function arguments (unused).
504- `args_cnt` - the number of function arguments (unused).
505- return value - `jerry_value_t` representing `undefined`.
506
507**See also**
508
509- [jerryx_handler_register_global](#jerryx_handler_register_global)
510
511
512## jerryx_handler_print
513
514**Summary**
515
516Provide a `print` implementation for scripts. The routine converts all of its
517arguments to strings and outputs them char-by-char using
518`jerry_port_print_char`. The NUL character is output as "\u0000",
519other characters are output bytewise.
520
521*Note*: This implementation does not use standard C `printf` to print its
522output. This allows more flexibility but also extends the core JerryScript
523engine port API. Applications that want to use `jerryx_handler_print` must
524ensure that their port implementation also provides
525`jerry_port_print_char`.
526
527**Prototype**
528
529```c
530jerry_value_t
531jerryx_handler_print (const jerry_value_t func_obj_val, const jerry_value_t this_p,
532                      const jerry_value_t args_p[], const jerry_length_t args_cnt);
533```
534
535- `func_obj_val` - the function object that was called (unused).
536- `this_p` - the `this` value of the call (unused).
537- `args_p` - the array of function arguments.
538- `args_cnt` - the number of function arguments.
539- return value - `jerry_value_t` representing `undefined` if all arguments could
540  be converted to strings, an `Error` otherwise.
541
542**See also**
543
544- [jerryx_handler_register_global](#jerryx_handler_register_global)
545- [jerry_port_print_char](05.PORT-API.md#jerry_port_print_char)
546
547
548# Handler registration helper
549
550## jerryx_handler_register_global
551
552**Summary**
553
554Register a JavaScript function in the global object.
555
556*Note*: Returned value must be freed with `jerry_release_value`, when it is no
557longer needed.
558
559**Prototype**
560
561```c
562jerry_value_t
563jerryx_handler_register_global (const jerry_char_t *name_p,
564                                jerry_external_handler_t handler_p);
565```
566
567- `name_p` - the name of the function to be registered.
568- `handler_p` - the address of the external function handler.
569- return value - `jerry_value_t` representing boolean true, if the operation was
570  successful, an `Error` otherwise.
571
572**Example**
573
574[doctest]: # (test="compile")
575
576```c
577#include "jerryscript.h"
578#include "jerryscript-ext/handler.h"
579
580static const struct {
581  const char *name_p;
582  jerry_external_handler_t handler_p;
583} common_functions[] =
584{
585  { "assert", jerryx_handler_assert },
586  { "gc", jerryx_handler_gc },
587  { "print", jerryx_handler_print },
588  { NULL, NULL }
589};
590
591static void
592register_common_functions (void)
593{
594  jerry_value_t ret = jerry_create_undefined ();
595
596  for (int i = 0; common_functions[i].name_p != NULL && !jerry_value_is_error (ret); i++)
597  {
598    ret = jerryx_handler_register_global ((const jerry_char_t *) common_functions[i].name_p,
599                                          common_functions[i].handler_p);
600  }
601
602  jerry_release_value (ret);
603}
604```
605