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 #ifndef JERRYX_MODULE_H 17 #define JERRYX_MODULE_H 18 19 #include "jerryscript.h" 20 21 #ifdef __cplusplus 22 extern "C" 23 { 24 #endif /* __cplusplus */ 25 26 /** 27 * Declare the signature for the module initialization function. 28 */ 29 typedef jerry_value_t (*jerryx_native_module_on_resolve_t) (void); 30 31 /** 32 * Declare the structure used to define a module. One should only make use of this structure via the 33 * JERRYX_NATIVE_MODULE macro declared below. 34 */ 35 typedef struct jerryx_native_module_t 36 { 37 const jerry_char_t *name_p; /**< name of the module */ 38 const jerryx_native_module_on_resolve_t on_resolve_p; /**< function that returns a new instance of the module */ 39 struct jerryx_native_module_t *next_p; /**< pointer to next module in the list */ 40 } jerryx_native_module_t; 41 42 /** 43 * Declare the constructor and destructor attributes. These evaluate to nothing if this extension is built without 44 * library constructor/destructor support. 45 */ 46 #ifdef ENABLE_INIT_FINI 47 #ifdef _MSC_VER 48 #error "`FEATURE_INIT_FINI` build flag isn't supported on Windows, because Microsoft Visual C/C++ Compiler \ 49 doesn't support library constructors and destructors." 50 #endif 51 #define JERRYX_MODULE_CONSTRUCTOR_ATTRIBUTE __attribute__((constructor)) 52 #define JERRYX_MODULE_DESTRUCTOR_ATTRIBUTE __attribute__((destructor)) 53 #define JERRYX_MODULE_REGISTRATION_QUALIFIER static 54 #else /* !ENABLE_INIT_FINI */ 55 #define JERRYX_MODULE_CONSTRUCTOR_ATTRIBUTE 56 #define JERRYX_MODULE_DESTRUCTOR_ATTRIBUTE 57 #define JERRYX_MODULE_REGISTRATION_QUALIFIER 58 #endif /* ENABLE_INIT_FINI */ 59 60 /** 61 * Having two levels of macros allows strings to be used unquoted. 62 */ 63 #define JERRYX_NATIVE_MODULE(module_name, on_resolve_cb) \ 64 JERRYX_NATIVE_MODULE_IMPLEM(module_name, on_resolve_cb) 65 66 #define JERRYX_NATIVE_MODULE_IMPLEM(module_name, on_resolve_cb) \ 67 static jerryx_native_module_t _ ## module_name ## _definition = \ 68 { \ 69 .name_p = (jerry_char_t *) #module_name, \ 70 .on_resolve_p = (on_resolve_cb), \ 71 .next_p = NULL \ 72 }; \ 73 \ 74 JERRYX_MODULE_REGISTRATION_QUALIFIER void \ 75 module_name ## _register (void) JERRYX_MODULE_CONSTRUCTOR_ATTRIBUTE; \ 76 JERRYX_MODULE_REGISTRATION_QUALIFIER void \ 77 module_name ## _register (void) \ 78 { \ 79 jerryx_native_module_register(&_##module_name##_definition); \ 80 } \ 81 \ 82 JERRYX_MODULE_REGISTRATION_QUALIFIER void \ 83 module_name ## _unregister (void) \ 84 JERRYX_MODULE_DESTRUCTOR_ATTRIBUTE; \ 85 JERRYX_MODULE_REGISTRATION_QUALIFIER void \ 86 module_name ## _unregister (void) \ 87 { \ 88 jerryx_native_module_unregister(&_##module_name##_definition); \ 89 } 90 91 /** 92 * Register a native module. This makes it available for loading via jerryx_module_resolve, when 93 * jerryx_module_native_resolver is passed in as a possible resolver. 94 */ 95 void jerryx_native_module_register (jerryx_native_module_t *module_p); 96 97 /** 98 * Unregister a native module. This removes the module from the list of available native modules, meaning that 99 * subsequent calls to jerryx_module_resolve with jerryx_module_native_resolver will not be able to find it. 100 */ 101 void jerryx_native_module_unregister (jerryx_native_module_t *module_p); 102 103 /** 104 * Declare the function pointer type for canonical name resolution. 105 */ 106 typedef jerry_value_t (*jerryx_module_get_canonical_name_t) (const jerry_value_t name); /**< The name for which to 107 * compute the canonical 108 * name */ 109 110 /** 111 * Declare the function pointer type for module resolution. 112 */ 113 typedef bool (*jerryx_module_resolve_t) (const jerry_value_t canonical_name, /**< The module's canonical name */ 114 jerry_value_t *result); /**< The resulting module, if the function returns 115 * true */ 116 117 /** 118 * Declare the structure for module resolvers. 119 */ 120 typedef struct 121 { 122 jerryx_module_get_canonical_name_t get_canonical_name_p; /**< function pointer to establish the canonical name of a 123 * module */ 124 jerryx_module_resolve_t resolve_p; /**< function pointer to resolve a module */ 125 } jerryx_module_resolver_t; 126 127 /** 128 * Declare the JerryScript module resolver so that it may be added to an array of jerryx_module_resolver_t items and 129 * thus passed to jerryx_module_resolve. 130 */ 131 extern jerryx_module_resolver_t jerryx_module_native_resolver; 132 133 /** 134 * Load a copy of a module into the current context using the provided module resolvers, or return one that was already 135 * loaded if it is found. 136 */ 137 jerry_value_t jerryx_module_resolve (const jerry_value_t name, 138 const jerryx_module_resolver_t **resolvers, 139 size_t count); 140 141 /** 142 * Delete a module from the cache or, if name has the JavaScript value of undefined, clear the entire cache. 143 */ 144 void jerryx_module_clear_cache (const jerry_value_t name, 145 const jerryx_module_resolver_t **resolvers, 146 size_t count); 147 148 #ifdef __cplusplus 149 } 150 #endif /* __cplusplus */ 151 #endif /* !JERRYX_MODULE_H */ 152