@@ -4756,97 +4756,197 @@ jerry_set_prototype (const jerry_value_t obj_val,
4756
4756
4757
4757
**Summary**
4758
4758
4759
- Get native pointer and its type information.
4759
+ Get native pointer by the given type information.
4760
4760
The pointer and the type information are previously associated with the object by jerry_set_object_native_pointer.
4761
4761
4762
- *Note*: It is recommended to ensure that the `out_native_info_p` value pointer
4763
- is equal to the native info pointer that is expected, before casting
4764
- and accessing the `out_native_pointer_p`.
4765
- An example of when this is important: external functions that expect
4766
- `this` to have a native pointer of a certain C type.
4767
- It is possible in JavaScript to change `this` at will – using `call()`,
4768
- `apply()` or `bind()`. Therefore, it is possible that the native pointer
4769
- of `this` is not of the expected C type. To handle this safely and
4770
- securely, one must always add type checks to make sure that the
4771
- `out_native_pointer_p` is of the expected type, before casting
4772
- and dereferencing `out_native_pointer_p`.
4773
-
4774
- *Note*: `out_native_pointer_p` and `out_native_info_p` can be NULL, and it means the
4775
- caller doesn't want to get the native_pointer or type information.
4762
+ *Note*: `out_native_pointer_p` can be NULL, and it means the
4763
+ caller doesn't want to get the native_pointer.
4776
4764
4777
4765
**Prototype**
4778
4766
4779
4767
```c
4780
4768
bool
4781
4769
jerry_get_object_native_pointer (const jerry_value_t obj_val,
4782
4770
void **out_native_pointer_p,
4783
- const jerry_object_native_info_t **out_native_info_p )
4771
+ const jerry_object_native_info_t *native_info_p )
4784
4772
```
4785
4773
4786
4774
- `obj_val` - object value to get native pointer from.
4787
4775
- `out_native_pointer_p` - native pointer (output parameter).
4788
- - `out_native_info_p ` - native pointer's type information (output parameter) .
4776
+ - `native_info_p ` - native pointer's type information.
4789
4777
- return value
4790
- - true, if there is native pointer associated with the object
4778
+ - true, if there is native pointer associated of the specified object with the given native type info
4791
4779
- false, otherwise
4792
4780
4793
4781
**Example**
4794
4782
4783
+ [doctest]: # ()
4784
+
4795
4785
```c
4796
- typedef struct {
4797
- int foo;
4798
- bool bar;
4799
- } native_obj_t;
4786
+ #include <stdio.h>
4787
+ #include <stdlib.h>
4788
+ #include <string.h>
4789
+ #include "jerryscript.h"
4800
4790
4801
- static void native_freecb (void *native_p)
4791
+ typedef struct
4802
4792
{
4803
- ... // free the native pointer
4793
+ char *data_p;
4794
+ unsigned int length;
4795
+ } buffer_native_object_t;
4796
+
4797
+ typedef struct
4798
+ {
4799
+ int area;
4800
+ int perimeter;
4801
+ } shape_native_object_t;
4802
+
4803
+ #define SECRET_INFO ((void *) 42)
4804
+
4805
+ static void
4806
+ buffer_native_freecb (void *native_p)
4807
+ {
4808
+ char *data_p = ((buffer_native_object_t*)native_p)->data_p;
4809
+
4810
+ if (data_p != NULL)
4811
+ {
4812
+ free (data_p);
4813
+ }
4814
+
4815
+ free (native_p);
4816
+ }
4817
+
4818
+ static void
4819
+ shape_native_freecb (void *native_p)
4820
+ {
4821
+ free (native_p);
4822
+ }
4823
+
4824
+ static void
4825
+ destructor_freecb (void *native_p)
4826
+ {
4827
+ printf("Note: the object has been freed\n");
4804
4828
}
4805
4829
4806
4830
// NOTE: The address (!) of type_info acts as a way to uniquely "identify" the
4807
- // C type `native_obj_t *`.
4808
- static const jerry_object_native_info_t native_obj_type_info =
4831
+ // C type `buffer_native_object_t *`.
4832
+ static const jerry_object_native_info_t buffer_obj_type_info =
4809
4833
{
4810
- .free_cb = native_freecb
4834
+ .free_cb = buffer_native_freecb
4811
4835
};
4812
4836
4813
- // Function creating JS object that is "backed" by a native_obj_t *:
4837
+ // NOTE: The address (!) of type_info acts as a way to uniquely "identify" the
4838
+ // C type `shape_native_object_t *`.
4839
+ static const jerry_object_native_info_t shape_obj_type_info =
4814
4840
{
4815
- ...
4841
+ .free_cb = shape_native_freecb
4842
+ };
4816
4843
4817
- // construct object and native_set value:
4818
- jerry_value_t object = ...;
4819
- native_obj_t *native_obj = malloc(sizeof(*native_obj));
4820
- jerry_set_object_native_pointer (object, native_obj, &native_obj_type_info);
4844
+ // NOTE: The address (!) of type_info is the unique "identifier"
4845
+ static const jerry_object_native_info_t destructor_obj_type_info =
4846
+ {
4847
+ .free_cb = destructor_freecb
4848
+ };
4821
4849
4822
- ...
4850
+ static void
4851
+ print_buffer (char *data_p,
4852
+ unsigned int length)
4853
+ {
4854
+ for (unsigned int i = 0; i < length; ++i)
4855
+ {
4856
+ printf("%c", data_p[i]);
4857
+ }
4858
+
4859
+ printf("\n");
4823
4860
}
4824
4861
4825
- // Native method, `this` is expected to be "backed" by a native_obj_t *:
4862
+ static void
4863
+ do_stuff (jerry_value_t object)
4826
4864
{
4827
4865
void *native_p;
4828
- const jerry_object_native_info_t *type_p;
4829
- bool has_p = jerry_get_object_native_pointer (this_val, &native_p, &type_p);
4866
+ bool has_p = jerry_get_object_native_pointer (object, &native_p, &buffer_obj_type_info);
4830
4867
4831
- if (has_p)
4868
+ if (! has_p)
4832
4869
{
4833
- // The type_p pointer address itself is used to identify the type:
4834
- if (type_p == &native_obj_type_info)
4870
+ // Process the error
4871
+ return;
4872
+ }
4873
+
4874
+ // It is safe to cast to buffer_native_object_t * and dereference the pointer:
4875
+ buffer_native_object_t *buffer_p = (buffer_native_object_t *) native_p;
4876
+ print_buffer (buffer_p->data_p, buffer_p->length); // Usage of buffer_p
4877
+
4878
+ bool need_shape_info = true; // implementation dependent
4879
+
4880
+ if (need_shape_info)
4881
+ {
4882
+ has_p = jerry_get_object_native_pointer (object, &native_p, &shape_obj_type_info);
4883
+
4884
+ if (!has_p)
4835
4885
{
4836
- // The type of this's native pointer matches what is expected.
4837
- // Only now is it safe to cast to native_obj_t * and dereference the
4838
- // pointer:
4839
- native_obj_t *native_obj = native_p;
4840
- native_obj->bar = ...; // Safe to access now!
4886
+ // Process the error
4887
+ return;
4841
4888
}
4842
- else
4889
+
4890
+ // It is safe to cast to shape_native_object_t * and dereference the pointer:
4891
+ shape_native_object_t *shape_p = (shape_native_object_t *) native_p;
4892
+
4893
+ printf("Area: %d\tPerimeter: %d\n", shape_p->area, shape_p->perimeter); // Usage of shape_p
4894
+ }
4895
+
4896
+ bool need_secret_info = true; // implementation dependent
4897
+
4898
+ if (need_secret_info)
4899
+ {
4900
+ has_p = jerry_get_object_native_pointer (object, &native_p, NULL);
4901
+
4902
+ if (!has_p)
4843
4903
{
4844
- // The type of this's native pointer is NOT what we expected!
4845
- // We should not cast to native_obj_t * and dereference because it's unsafe.
4846
- // Handle the error here, for example throw an error.
4904
+ // Process the error
4905
+ return;
4906
+ }
4907
+
4908
+ printf("Secret: %d\n", (int)((uintptr_t) native_p)); // Usage of native_p
4909
+
4910
+ bool deleted = jerry_delete_object_native_pointer (object, NULL);
4911
+
4912
+ if (deleted)
4913
+ {
4914
+ printf("The secret is no longer available\n");
4847
4915
}
4848
4916
}
4849
- ...
4917
+ }
4918
+
4919
+ int
4920
+ main (void)
4921
+ {
4922
+ jerry_init (JERRY_INIT_EMPTY);
4923
+
4924
+ jerry_value_t object = jerry_create_object ();
4925
+ buffer_native_object_t *buffer_p = (buffer_native_object_t *) malloc (sizeof (buffer_native_object_t));
4926
+ buffer_p->length = 14;
4927
+ buffer_p->data_p = (char *) malloc (buffer_p->length * sizeof (char));
4928
+ memcpy (buffer_p->data_p, "My buffer data", buffer_p->length);
4929
+ jerry_set_object_native_pointer (object, buffer_p, &buffer_obj_type_info);
4930
+
4931
+ shape_native_object_t *shape_p = (shape_native_object_t *) malloc (sizeof (shape_native_object_t));
4932
+ shape_p->area = 6;
4933
+ shape_p->perimeter = 12;
4934
+ jerry_set_object_native_pointer (object, shape_p, &shape_obj_type_info);
4935
+
4936
+ // The native pointer can be NULL. This gives possibily to get notified via the native type info's
4937
+ // free callback when the object has been freed by the GC.
4938
+ jerry_set_object_native_pointer (object, NULL, &destructor_obj_type_info);
4939
+
4940
+ // The native type info can be NULL as well. In this case the registered property is simply freed
4941
+ // when the object is freed by te GC.
4942
+ jerry_set_object_native_pointer (object, SECRET_INFO, NULL);
4943
+
4944
+ do_stuff (object);
4945
+
4946
+ jerry_release_value (object);
4947
+ jerry_cleanup ();
4948
+
4949
+ return 0;
4850
4950
}
4851
4951
```
4852
4952
@@ -4897,6 +4997,40 @@ best-practice example.
4897
4997
- [jerry_get_object_native_pointer](#jerry_get_object_native_pointer)
4898
4998
- [jerry_object_native_info_t](#jerry_object_native_info_t)
4899
4999
5000
+ ## jerry_delete_object_native_pointer
5001
+
5002
+ **Summary**
5003
+
5004
+ Delete the native pointer of the specified object associated with the given native type info.
5005
+ You can get them by calling jerry_get_object_native_pointer later.
5006
+
5007
+ *Note*: If the specified object has no matching native pointer for the given native type info the operation has no effect.
5008
+
5009
+ *Note*: This operation cannot throw an exception.
5010
+
5011
+ **Prototype**
5012
+
5013
+ ```c
5014
+ bool
5015
+ jerry_delete_object_native_pointer (const jerry_value_t obj_val,
5016
+ const jerry_object_native_info_t *info_p)
5017
+ ```
5018
+
5019
+ - `obj_val` - object to delete native pointer from.
5020
+ - `info_p` - native pointer's type information.
5021
+
5022
+ **Example**
5023
+
5024
+ See [jerry_get_object_native_pointer](#jerry_get_object_native_pointer) for a
5025
+ best-practice example.
5026
+
5027
+ **See also**
5028
+
5029
+ - [jerry_create_object](#jerry_create_object)
5030
+ - [jerry_get_object_native_pointer](#jerry_get_object_native_pointer)
5031
+ - [jerry_get_object_native_pointer](#jerry_set_object_native_pointer)
5032
+ - [jerry_object_native_info_t](#jerry_object_native_info_t)
5033
+
4900
5034
4901
5035
## jerry_foreach_object_property
4902
5036
0 commit comments