--- layout: page title: Development permalink: /dev-guide/ --- # Embedding The JerryScript Engine can be embedded into any application, providing way to run JavaScript in large range of environments - from desktops to low-memory microcontrollers. ## How to execute simple JavaScript file from your application ```cpp #include #include "jerry.h" int main (int argc, char * argv[]) { char script [] = "print ('Hello, World!');"; jerry_completion_code_t code = jerry_run_simple (script, strlen (script), JERRY_FLAG_EMPTY); } ``` The described application will generate the following output: ```bash Hello, World! ``` ## Adding more control over what's happening Here we perform the same actions, as `jerry_run_simple`, while splitting into several steps: - engine initialization - script code setup - script execution - engine free ```cpp #include #include "jerry.h" int main (int argc, char * argv[]) { char script [] = "print ('Hello, World!');"; jerry_init (JERRY_FLAG_EMPTY); jerry_parse (script, strlen (script)); jerry_run (); jerry_cleanup (); } ``` While the code became a bit more complex, the change introduced possibilities to interact with JavaScript step by step, setup native objects and functions, etc. ## 'eval'-mode execution ```cpp #include #include "jerry.h" int main (int argc, char * argv[]) { char script1 [] = "var s = 'Hello, World!';"; char script2 [] = "print (s);"; jerry_init (JERRY_FLAG_EMPTY); jerry_api_value_t eval_ret; // Step 1 jerry_api_eval (script1, strlen (script1), false, false, &eval_ret); jerry_api_release_value (&eval_ret); // Step 2 jerry_api_eval (script2, strlen (script2), false, false, &eval_ret); jerry_api_release_value (&eval_ret); jerry_cleanup (); } ``` This way, we execute two independent script parts in one execution environment. The first part initializes string variable, and the second outputs the variable. ## Interaction with JavaScript data ```cpp #include #include "jerry.h" int main (int argc, char * argv[]) { char str [] = "Hello, World!"; char var_name [] = "s"; char script [] = "print (s);"; // Initializing JavaScript environment jerry_init (JERRY_FLAG_EMPTY); // Getting pointer to the Global object jerry_api_object_t *obj_p = jerry_api_get_global_object (); // Constructing string jerry_api_string_t *str_val_p = jerry_api_create_string (str); // Construction string value descriptor jerry_api_value_t val; val.type = JERRY_API_DATA_TYPE_STRING; val.string_p = str_val_p; // Setting the string value to field of the Global object jerry_api_set_object_field_value (obj_p, var_name, &val); // Releasing string value, as it is no longer necessary outside of engine jerry_api_release_string (str_val_p); // Same for pointer to the Global object jerry_api_release_object (obj_p); jerry_api_value_t eval_ret; // Now starting script that would output value of just initialized field jerry_api_eval (script, strlen (script), false, false, &eval_ret); jerry_api_release_value (&eval_ret); // Freeing engine jerry_cleanup (); } ``` The sample would also output 'Hello, World!'. However, now we have base for some real application. ## Simple JavaScript shell Let's construct simple JavaScript shell. Shell operation can be described with following loop: - read command; - if command is 'quit' - exit loop; - else - eval (command); - print result of eval; - loop. ```cpp #include #include #include #include #include "jerry.h" static void print_value (const jerry_api_value_t * value_p); int main (int argc, char * argv[]) { jerry_init (JERRY_FLAG_EMPTY); char cmd [256]; while (true) { printf ("> "); if (fgets (cmd, sizeof (cmd), stdin) == NULL || strcmp (cmd, "quit\n") == 0) { break; } jerry_api_value_t ret_val; jerry_completion_code_t status = jerry_api_eval (cmd, strlen (cmd), false, false, &ret_val); if (status == JERRY_COMPLETION_CODE_OK) { // 'eval' completed successfully print_value (&ret_val); jerry_api_release_value (&ret_val); } else { // evaluated JS code thrown an exception // and didn't handle it with try-catch-finally printf ("Unhandled JS exception occured\n"); } printf ("\n"); fflush (stdout); } jerry_cleanup (); return 0; } static void print_value (const jerry_api_value_t * value_p) { switch (value_p->type) { case JERRY_API_DATA_TYPE_UNDEFINED: printf ("undefined"); break; case JERRY_API_DATA_TYPE_NULL: printf ("null"); break; case JERRY_API_DATA_TYPE_BOOLEAN: if (value_p->v_bool) printf ("true"); else printf ("false"); break; case JERRY_API_DATA_TYPE_FLOAT64: printf ("%lf", value_p->v_float64); break; case JERRY_API_DATA_TYPE_STRING: { ssize_t neg_req_sz, sz; // determining required buffer size neg_req_sz = jerry_api_string_to_char_buffer (value_p->v_string, NULL, 0); assert (neg_req_sz < 0); char * str_buf_p = (char*) malloc (-neg_req_sz); sz = jerry_api_string_to_char_buffer (value_p->v_string, str_buf_p, -neg_req_sz); assert (sz == -neg_req_sz); printf ("%s", str_buf_p); free (str_buf_p); break; } case JERRY_API_DATA_TYPE_OBJECT: printf ("[JS object]"); break; } printf ("\n"); } ```