1# Reference 2 3## Termination 4 5It is questionable whether a library should be able to terminate an application. Any API function can signal an error (ex.: cannot allocate memory), so the engine use the termination approach with this port function. 6 7```c 8/** 9 * Signal the port that jerry experienced a fatal failure from which it cannot 10 * recover. 11 * 12 * @param code gives the cause of the error. 13 * 14 * Note: 15 * Jerry expects the function not to return. 16 * 17 * Example: a libc-based port may implement this with exit() or abort(), or both. 18 */ 19void jerry_port_fatal (jerry_fatal_code_t code); 20``` 21 22Error codes 23 24```c 25typedef enum 26{ 27 ERR_OUT_OF_MEMORY = 10, 28 ERR_REF_COUNT_LIMIT = 12, 29 ERR_DISABLED_BYTE_CODE = 13, 30 ERR_FAILED_INTERNAL_ASSERTION = 120 31} jerry_fatal_code_t; 32``` 33 34## I/O 35 36These are the only I/O functions jerry calls. 37 38```c 39/** 40 * Jerry log levels. The levels are in severity order 41 * where the most serious levels come first. 42 */ 43typedef enum 44{ 45 JERRY_LOG_LEVEL_ERROR, /**< the engine will terminate after the message is printed */ 46 JERRY_LOG_LEVEL_WARNING, /**< a request is aborted, but the engine continues its operation */ 47 JERRY_LOG_LEVEL_DEBUG, /**< debug messages from the engine, low volume */ 48 JERRY_LOG_LEVEL_TRACE /**< detailed info about engine internals, potentially high volume */ 49} jerry_log_level_t; 50 51/** 52 * Display or log a debug/error message, and sends it to the debugger client as well. 53 * The function should implement a printf-like interface, where the first argument 54 * specifies the log level and the second argument specifies a format string on how 55 * to stringify the rest of the parameter list. 56 * 57 * This function is only called with messages coming from the jerry engine as 58 * the result of some abnormal operation or describing its internal operations 59 * (e.g., data structure dumps or tracing info). 60 * 61 * It should be the port that decides whether error and debug messages are logged to 62 * the console, or saved to a database or to a file. 63 * 64 * Example: a libc-based port may implement this with vfprintf(stderr) or 65 * vfprintf(logfile), or both, depending on log level. 66 * 67 * Note: 68 * This port function is called by jerry-core when JERRY_LOGGING is 69 * enabled. It is also common practice though to use this function in 70 * application code. 71 */ 72void jerry_port_log (jerry_log_level_t level, const char *fmt, ...); 73``` 74 75The `jerry_port_print_char` is currenlty not used by the jerry-core directly. 76However, it provides a port specifc way for `jerry-ext` components to print 77information. 78 79```c 80/** 81 * Print a character to stdout. 82 */ 83void jerry_port_print_char (char c); 84``` 85 86### ES2015 Module system 87 88The port API provides functions that can be used by the module system to open 89and close source files, and normalize file paths. 90The `jerry_port_get_native_module` port function can be used to provide native 91modules to the engine. This function will be called when an import/export 92statement is encountered with an unknown module specifier, which embedders can 93use to supply native module objects based on the module name argument. 94 95```c 96/** 97 * Opens file with the given path and reads its source. 98 * @return the source of the file 99 */ 100uint8_t * 101jerry_port_read_source (const char *file_name_p, /**< file name */ 102 size_t *out_size_p) /**< [out] read bytes */ 103{ 104 // open file from given path 105 // return its source 106} /* jerry_port_read_source */ 107 108/** 109 * Release the previously opened file's content. 110 */ 111void 112jerry_port_release_source (uint8_t *buffer_p) /**< buffer to free */ 113{ 114 free (buffer_p); 115} /* jerry_port_release_source */ 116 117/** 118 * Normalize a file path 119 * 120 * @return length of the path written to the output buffer 121 */ 122size_t 123jerry_port_normalize_path (const char *in_path_p, /**< input file path */ 124 char *out_buf_p, /**< output buffer */ 125 size_t out_buf_size, /**< size of output buffer */ 126 char *base_file_p) /**< base file path */ 127{ 128 // normalize in_path_p by expanding relative paths etc. 129 // if base_file_p is not NULL, in_path_p is relative to that file 130 // write to out_buf_p the normalized path 131 // return length of written path 132} /* jerry_port_normalize_path */ 133 134/** 135 * Get the module object of a native module. 136 * 137 * Note: 138 * This port function is called by jerry-core when ES2015_MODULE_SYSTEM 139 * is enabled. 140 * 141 * @param name String value of the module specifier. 142 * 143 * @return Undefined, if 'name' is not a native module 144 * jerry_value_t containing the module object, otherwise 145 */ 146jerry_value_t 147jerry_port_get_native_module (jerry_value_t name) /**< module specifier */ 148{ 149 (void) name; 150 return jerry_create_undefined (); 151} 152``` 153 154## Date 155 156```c 157/** 158 * Get local time zone adjustment, in milliseconds, for the given timestamp. 159 * The timestamp can be specified in either UTC or local time, depending on 160 * the value of is_utc. Adding the value returned from this function to 161 * a timestamp in UTC time should result in local time for the current time 162 * zone, and subtracting it from a timestamp in local time should result in 163 * UTC time. 164 * 165 * Ideally, this function should satisfy the stipulations applied to LocalTZA 166 * in section 20.3.1.7 of the ECMAScript version 9.0 spec. 167 * 168 * See Also: 169 * ECMA-262 v9, 20.3.1.7 170 * 171 * Note: 172 * This port function is called by jerry-core when 173 * JERRY_BUILTIN_DATE is set to 1. Otherwise this function is 174 * not used. 175 * 176 * @param unix_ms The unix timestamp we want an offset for, given in 177 * millisecond precision (could be now, in the future, 178 * or in the past). As with all unix timestamps, 0 refers to 179 * 1970-01-01, a day is exactly 86 400 000 milliseconds, and 180 * leap seconds cause the same second to occur twice. 181 * @param is_utc Is the given timestamp in UTC time? If false, it is in local 182 * time. 183 * 184 * @return milliseconds between local time and UTC for the given timestamp, 185 * if available 186 *. 0 if not available / we are in UTC. 187 */ 188double jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc); 189 190/** 191 * Get system time 192 * 193 * Note: 194 * This port function is called by jerry-core when 195 * JERRY_BUILTIN_DATE is set to 1. It is also common practice 196 * in application code to use this function for the initialization of the 197 * random number generator. 198 * 199 * @return milliseconds since Unix epoch 200 */ 201double jerry_port_get_current_time (void); 202``` 203 204## External context 205 206Allow user to provide external buffer for isolated engine contexts, so that user 207can configure the heap size at runtime and run multiple JS applications 208simultaneously. 209 210```c 211/** 212 * Get the current context of the engine. Each port should provide its own 213 * implementation of this interface. 214 * 215 * Note: 216 * This port function is called by jerry-core when 217 * JERRY_EXTERNAL_CONTEXT is enabled. Otherwise this function is not 218 * used. 219 * 220 * @return the pointer to the engine context. 221 */ 222struct jerry_context_t *jerry_port_get_current_context (void); 223``` 224 225## Sleep 226 227```c 228/** 229 * Makes the process sleep for a given time. 230 * 231 * Note: 232 * This port function is called by jerry-core when JERRY_DEBUGGER is set to 1. 233 * Otherwise this function is not used. 234 * 235 * @param sleep_time milliseconds to sleep. 236 */ 237void jerry_port_sleep (uint32_t sleep_time); 238``` 239 240# How to port JerryScript 241 242This section describes a basic port implementation which was created for Unix based systems. 243 244## Termination 245 246```c 247#include <stdlib.h> 248#include "jerryscript-port.h" 249 250/** 251 * Default implementation of jerry_port_fatal. 252 */ 253void jerry_port_fatal (jerry_fatal_code_t code) 254{ 255 exit (code); 256} /* jerry_port_fatal */ 257``` 258 259## I/O 260 261```c 262#include <stdarg.h> 263#include "jerryscript-port.h" 264 265/** 266 * Provide log message implementation for the engine. 267 * 268 * Note: 269 * This example ignores the log level. 270 */ 271void 272jerry_port_log (jerry_log_level_t level, /**< log level */ 273 const char *format, /**< format string */ 274 ...) /**< parameters */ 275{ 276 va_list args; 277 va_start (args, format); 278 vfprintf (stderr, format, args); 279 va_end (args); 280} /* jerry_port_log */ 281``` 282 283```c 284/** 285 * Print a character to stdout with putchar. 286 */ 287void 288jerry_port_print_char (char c) 289{ 290 putchar (c); 291} /* jerr_port_print_char */ 292``` 293 294## Date 295 296```c 297#include <time.h> 298#include <sys/time.h> 299#include "jerryscript-port.h" 300 301/** 302 * Default implementation of jerry_port_get_local_time_zone_adjustment. 303 */ 304double jerry_port_get_local_time_zone_adjustment (double unix_ms, /**< ms since unix epoch */ 305 bool is_utc) /**< is the time above in UTC? */ 306{ 307 struct tm tm; 308 time_t now = (time_t) (unix_ms / 1000); 309 localtime_r (&now, &tm); 310 if (!is_utc) 311 { 312 now -= tm.tm_gmtoff; 313 localtime_r (&now, &tm); 314 } 315 return ((double) tm.tm_gmtoff) * 1000; 316} /* jerry_port_get_local_time_zone_adjustment */ 317 318/** 319 * Default implementation of jerry_port_get_current_time. 320 */ 321double jerry_port_get_current_time (void) 322{ 323 struct timeval tv; 324 325 if (gettimeofday (&tv, NULL) != 0) 326 { 327 return 0; 328 } 329 330 return ((double) tv.tv_sec) * 1000.0 + ((double) tv.tv_usec) / 1000.0; 331} /* jerry_port_get_current_time */ 332``` 333 334## External context 335 336```c 337#include "jerryscript-port.h" 338#include "jerryscript-port-default.h" 339 340/** 341 * Pointer to the current context. 342 * Note that it is a global variable, and is not a thread safe implementation. 343 */ 344static jerry_context_t *current_context_p = NULL; 345 346/** 347 * Set the current_context_p as the passed pointer. 348 */ 349void 350jerry_port_default_set_current_context (jerry_context_t *context_p) /**< points to the created context */ 351{ 352 current_context_p = context_p; 353} /* jerry_port_default_set_current_context */ 354 355/** 356 * Get the current context. 357 * 358 * @return the pointer to the current context 359 */ 360jerry_context_t * 361jerry_port_get_current_context (void) 362{ 363 return current_context_p; 364} /* jerry_port_get_current_context */ 365``` 366 367## Sleep 368 369```c 370#include "jerryscript-port.h" 371#include "jerryscript-port-default.h" 372 373#ifdef HAVE_TIME_H 374#include <time.h> 375#elif defined (HAVE_UNISTD_H) 376#include <unistd.h> 377#endif /* HAVE_TIME_H */ 378 379#if defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) 380void jerry_port_sleep (uint32_t sleep_time) 381{ 382#ifdef HAVE_TIME_H 383 nanosleep (&(const struct timespec) 384 { 385 (time_t) sleep_time / 1000, ((long int) sleep_time % 1000) * 1000000L /* Seconds, nanoseconds */ 386 } 387 , NULL); 388#elif defined (HAVE_UNISTD_H) 389 usleep ((useconds_t) sleep_time * 1000); 390#endif /* HAVE_TIME_H */ 391 (void) sleep_time; 392} /* jerry_port_sleep */ 393#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */ 394``` 395