Update development guide

This commit is contained in:
Ruben Ayrapetyan
2015-06-14 23:16:14 +03:00
parent 8c5ecfd1d2
commit e0c5e10e49
+109 -62
View File
@@ -4,10 +4,11 @@ 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
This guide is intended to introduce you to JerryScript embedding API through creation of simple JavaScript shell.
## Step 1. Execute JavaScript from your application
```cpp
#include <string.h>
@@ -23,20 +24,20 @@ main (int argc, char * argv[]) {
}
```
The described application will generate the following output:
The application will generate the following output:
```bash
Hello, World!
```
## Adding more control over what's happening
## Step 2. Split execution environment initialization, script execution and execution environment cleanup
Here we perform the same actions, as `jerry_run_simple`, while splitting into several steps:
- engine initialization
- script code setup
- script execution
- engine free
- engine cleanup
```cpp
@@ -47,18 +48,23 @@ int
main (int argc, char * argv[]) {
char script [] = "print ('Hello, World!');";
// Initialize engine
jerry_init (JERRY_FLAG_EMPTY);
// Setup Global scope code
jerry_parse (script, strlen (script));
jerry_run ();
// Execute Global scope code
jerry_completion_code_t code = jerry_run ();
// Cleanup engine
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.
While code became a bit more complex, the change introduced possibilities to interact with JerryScript step by step, setup native objects, call Javascript functions, etc.
## 'eval'-mode execution
## Step 3. Execution in 'eval'-mode
```cpp
#include <string.h>
@@ -69,27 +75,31 @@ main (int argc, char * argv[]) {
char script1 [] = "var s = 'Hello, World!';";
char script2 [] = "print (s);";
// Initialize engine
jerry_init (JERRY_FLAG_EMPTY);
jerry_api_value_t eval_ret;
// Step 1
// Evaluate script1
jerry_api_eval (script1, strlen (script1),
false, false, &eval_ret);
// Free JavaScript value, returned by eval
jerry_api_release_value (&eval_ret);
// Step 2
// Evaluate script2
jerry_api_eval (script2, strlen (script2),
false, false, &eval_ret);
// Free JavaScript value, returned by eval
jerry_api_release_value (&eval_ret);
// Cleanup engine
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
## Step 4. Interaction with JavaScript environment
```cpp
#include <string.h>
@@ -110,7 +120,7 @@ main (int argc, char * argv[]) {
// Constructing string
jerry_api_string_t *str_val_p = jerry_api_create_string (str);
// Construction string value descriptor
// Constructing string value descriptor
jerry_api_value_t val;
val.type = JERRY_API_DATA_TYPE_STRING;
val.string_p = str_val_p;
@@ -136,13 +146,89 @@ main (int argc, char * argv[]) {
}
```
The sample would also output 'Hello, World!'.
The sample would also output 'Hello, World!'. However, now it is not just part of source script, but value, dynamically supplied to the engine.
However, now we have base for some real application.
## Step 5. Description of JavaScript value descriptors
Structure, used to put values to / receive values from engine is the following:
- `type` of value:
- JERRY_API_DATA_TYPE_UNDEFINED (undefined);
- JERRY_API_DATA_TYPE_NULL (null);
- JERRY_API_DATA_TYPE_BOOLEAN (true / false);
- JERRY_API_DATA_TYPE_FLOAT64 (number);
- JERRY_API_DATA_TYPE_STRING (string);
- JERRY_API_DATA_TYPE_OBJECT (object reference);
- `v_bool` (if JERRY_API_DATA_TYPE_BOOLEAN) - boolean value;
- `v_float64` (if JERRY_API_DATA_TYPE_FLOAT64) - number value;
- `v_string` (if JERRY_API_DATA_TYPE_STRING) - pointer to string;
- `v_object` (if JERRY_API_DATA_TYPE_OBJECT) - pointer to object.
Abstract values, to be sent to / received from engine are described with the structure.
Pointers to strings / objects and values should be released just when become unnecessary, using `jerry_api_release_string` / `jerry_api_release_object` and `jerry_api_release_value`, correspondingly.
The following example function would output a JavaScript value:
```cpp
static void
print_value (const jerry_api_value_t * value_p)
{
switch (value_p->type)
{
// Simple values: undefined, null, false, true
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;
// Number value
case JERRY_API_DATA_TYPE_FLOAT64:
printf ("%lf", value_p->v_float64);
break;
// String value
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;
}
// Object reference
case JERRY_API_DATA_TYPE_OBJECT:
printf ("[JS object]");
break;
}
printf ("\n");
}
```
## Simple JavaScript shell
Let's construct simple JavaScript shell.
Now we have build blocks to construct JavaScript shell.
Shell operation can be described with following loop:
@@ -167,23 +253,28 @@ print_value (const jerry_api_value_t * value_p);
int
main (int argc, char * argv[]) {
// Initialize engine
jerry_init (JERRY_FLAG_EMPTY);
char cmd [256];
while (true) {
printf ("> ");
// Input next command
if (fgets (cmd, sizeof (cmd), stdin) == NULL
|| strcmp (cmd, "quit\n") == 0) {
// If the command is 'quit', exit from loop
break;
}
jerry_api_value_t ret_val;
// Evaluate entered command
jerry_completion_code_t status = jerry_api_eval (cmd, strlen (cmd),
false, false,
&ret_val);
// If command evaluated successfully, print value, returned by eval
if (status == JERRY_COMPLETION_CODE_OK) {
// 'eval' completed successfully
print_value (&ret_val);
@@ -198,55 +289,11 @@ main (int argc, char * argv[]) {
fflush (stdout);
}
// Cleanup engine
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");
}
```
For further API description, please look at [Embedding API](/API).