Updated content on the JerryScript GitHub Pages site

- API refenrece is updated.
- API examples are updated.
- How To page renamed to Getting Started.
- Fixes in Internlas.

JerryScript-DCO-1.0-Signed-off-by: István Kádár ikadar@inf.u-szeged.hu
This commit is contained in:
Istvan Kadar
2016-07-13 13:33:46 +02:00
committed by László Langó
parent 6e72dd22fe
commit c0978d1a42
7 changed files with 3529 additions and 3135 deletions
+76
View File
@@ -0,0 +1,76 @@
---
layout: page
title: Getting Started
permalink: /getting-started/
---
* toc
{:toc}
### Setting Up Prerequisites
Currently, only Ubuntu 14.04+ is officially supported as primary development environment.
There are several dependencies, that should be installed manually. The following list is required for building:
- `gcc` higher than `4.8.2`
- native
- arm-none-eabi
- `cmake` higher than `2.8.12.2`
- `make` higher than `3.81`
- `bash` higher than `4.3.11`
- `cppcheck` higher than 1.61
- `vera++` higher than 1.2.1
```bash
sudo apt-get install gcc g++ gcc-arm-none-eabi cmake cppcheck vera++
```
To make our scripts run correctly, several shell utilities should be available on the system:
- `find`
- `bc`
- `awk`
- `sed`
- `sha256sum`
- `wget`
Upon first build, `make` would try to setup prerequisites, required for further development and pre-commit testing:
- STM32F3 and STM32F4 libraries
```bash
make prerequisites -j
```
It may take time, so go grab some coffee:
```bash
Setting up prerequisites... (log file: ./build/prerequisites/prerequisites.log)
```
### Building Debug Version
To build debug version for Linux:
```bash
make debug.linux -j
```
To build debug version for Linux without LTO (Link Time Optimization):
```bash
LTO=OFF make debug.linux -j
```
### Checking Patch
```bash
make precommit -j
```
If some style guidelines, build or test runs fail during precommit, then this is indicated with a message like this:
```
Build failed. See ./build/bin/unittests/make.log for details.
```
+2931
View File
File diff suppressed because it is too large Load Diff
-100
View File
@@ -1,100 +0,0 @@
---
layout: page
title: How To
permalink: /how-to/
---
* toc
{:toc}
# How to Get the Sources
This step should be simple:
{% highlight bash %}
git clone https://github.com/Samsung/jerryscript.git
cd jerryscript
{% endhighlight %}
# How to Setup Recommended Prerequisites
Currently, we are using Ubuntu Linux 14.04+ as our development environment, so this tutorial was written based on this assumption. Additionaly, it'll be useful to read [Prerequisites]({{ site.baseurl }}/wiki/Prerequisites) wiki page, also.
There are dependencies, that should be installed manually. The following list is required for building:
- `gcc` or `g++` higher than `4.8.2`
- native
- arm-none-eabi
- `cmake` higher than `2.8.12.2`
- `make` higher than `3.81`
- `bash` higher than `4.3.11`
These tools are required for development:
- `cppcheck` requires `libpcre`
- `vera++` requires `tcl`, `tk` and `boost`
{% highlight bash %}
sudo apt-get install gcc g++
sudo apt-get install gcc-arm-none-eabi
sudo apt-get install cmake
sudo apt-get install libpcre3 libpcre3-dev
sudo apt-get install tcl8.6 tcl8.6-dev tk8.6-dev libboost-all-dev
{% endhighlight %}
To make our scripts run correctly, several shell utilities should be available on the system:
- `find`
- `bc`
- `awk`
- `sed`
- `sha256sum`
- `wget`
# How to Build
After setting up prerequisites, let's built the engine:
{% highlight bash %}
make
{% endhighlight %}
Upon first build, `make` would try to setup prerequisites, required for further development and pre-commit testing:
- stm32f3 and stm32f4 libraries
- nuttx's headers
- cppcheck 1.66
- vera++ 1.2.1
It may take time, so go grab some coffee:
{% highlight bash %}
Setting up prerequisites... (log file: ./build/prerequisites/prerequisites.log)
{% endhighlight %}
# How to Build Debug Version
To build debug version for Linux:
{% highlight bash %}
make debug.linux
{% endhighlight %}
To build debug version for Linux without LTO (Link Time Optimization):
{% highlight bash %}
LTO=off make debug.linux
{% endhighlight %}
# How to Run Unittests
{% highlight bash %}
make unittests
{% endhighlight %}
# How to Check the Patch
{% highlight bash %}
make precommit -j
{% endhighlight %}
Sometimes pre-commit testing fails, in that case you'll see message like that:
{% highlight bash %}
Build failed. See ./build/bin/unittests/make.log for details.
{% endhighlight %}
+517
View File
@@ -0,0 +1,517 @@
---
layout: page
title: API Examples
permalink: /api-example/
---
* toc
{:toc}
JerryScript Engine can be embedded into any application, providing the way to run JavaScript in a large range of environments - from desktops to low-memory microcontrollers.
This guide is intended to introduce you to JerryScript embedding API through creation of simple JavaScript shell.
## Step 1. Execute JavaScript from your application
```c
#include <string.h>
#include "jerry-api.h"
int
main (int argc, char * argv[])
{
const jerry_char_t script[] = "print ('Hello, World!');";
size_t script_size = strlen ((const char *) script);
bool ret_value = jerry_run_simple (script, script_size, JERRY_INIT_EMPTY);
return (ret_value ? 1 : 0);
}
```
The application will generate the following output:
```bash
Hello, World!
```
## Step 2. Split engine initialization and script execution
Here we perform the same actions, as `jerry_run_simple`, while splitting into several steps:
- engine initialization
- script code setup
- script execution
- engine cleanup
```c
#include <string.h>
#include "jerry-api.h"
int
main (int argc, char * argv[])
{
const jerry_char_t script[] = "print ('Hello, World!');";
size_t script_size = strlen ((const char *) script);
/* Initialize engine */
jerry_init (JERRY_INIT_EMPTY);
/* Setup Global scope code */
jerry_value_t parsed_code = jerry_parse (script, script_size, false);
if (!jerry_value_has_error_flag (parsed_code))
{
/* Execute the parsed source code in the Global scope */
jerry_value_t ret_value = jerry_run (parsed_code);
/* Returned value must be freed */
jerry_release_value (ret_value);
}
/* Parsed source code must be freed */
jerry_release_value (parsed_code);
/* Cleanup engine */
jerry_cleanup ();
return 0;
}
```
Our code is more complex now, but it introduces possibilities to interact with JerryScript step-by-step: setup native objects, call JavaScript functions, etc.
## Step 3. Execution in 'eval'-mode
```c
#include <string.h>
#include "jerry-api.h"
int
main (int argc, char * argv[])
{
const jerry_char_t script_1[] = "var s = 'Hello, World!';";
const jerry_char_t script_2[] = "print (s);";
/* Initialize engine */
jerry_init (JERRY_INIT_EMPTY);
jerry_value_t eval_ret;
/* Evaluate script1 */
eval_ret = jerry_eval (script_1,
strlen ((const char *) script_1),
false);
/* Free JavaScript value, returned by eval */
jerry_release_value (eval_ret);
/* Evaluate script2 */
eval_ret = jerry_eval (script_2,
strlen ((const char *) script_2),
false);
/* Free JavaScript value, returned by eval */
jerry_release_value (eval_ret);
/* Cleanup engine */
jerry_cleanup ();
return 0;
}
```
This way, we execute two independent script parts in one execution environment. The first part initializes string variable, and the second outputs the variable.
## Step 4. Interaction with JavaScript environment
```c
#include <string.h>
#include "jerry-api.h"
int
main (int argc, char * argv[]) {
const jerry_char_t str[] = "Hello, World!";
const jerry_char_t script[] = "print (s);";
/* Initializing JavaScript environment */
jerry_init (JERRY_INIT_EMPTY);
/* Getting pointer to the Global object */
jerry_value_t global_object = jerry_get_global_object ();
/* Constructing strings */
jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "s");
jerry_value_t prop_value = jerry_create_string (str);
/* Setting the string value as a property of the Global object */
jerry_set_property (global_object, prop_name, prop_value);
/* Releasing string values, as it is no longer necessary outside of engine */
jerry_release_value (prop_name);
jerry_release_value (prop_value);
/* Releasing the Global object */
jerry_release_value (global_object);
/* Now starting script that would output value of just initialized field */
jerry_value_t eval_ret = jerry_eval (script,
strlen ((const char *) script),
false);
/* Free JavaScript value, returned by eval */
jerry_release_value (eval_ret);
/* Freeing engine */
jerry_cleanup ();
return 0;
}
```
The sample will also output 'Hello, World!'. However, now it is not just a part of the source script, but the value, dynamically supplied to the engine.
## Step 5. Description of JerryScript value descriptors
JerryScript value can be a boolean, number, null, object, string or undefined. The value has an error flag,
that indicates whether is an error or not. Every type has an error flag not only objects. The error flag should
be cleared before the value is passed as an argument, otherwise it can lead to a type error. The error objects
created by API functions has the error flag set.
The following example function will output a JavaScript value:
```c
#include <stdlib.h>
#include <string.h>
#include "jerry-api.h"
#include "jerry-port.h"
static void
print_value (const jerry_value_t value)
{
if (jerry_value_is_undefined (value))
{
jerry_port_logmsg (stdout, "undefined");
}
else if (jerry_value_is_null (value))
{
jerry_port_logmsg (stdout, "null");
}
else if (jerry_value_is_boolean (value))
{
if (jerry_get_boolean_value (value))
{
jerry_port_logmsg (stdout, "true");
}
else
{
jerry_port_logmsg (stdout, "false");
}
}
/* Float value */
else if (jerry_value_is_number (value))
{
jerry_port_logmsg (stdout, "number");
}
/* String value */
else if (jerry_value_is_string (value))
{
/* Determining required buffer size */
jerry_size_t req_sz = jerry_get_string_size (value);
jerry_char_t str_buf_p[req_sz];
jerry_string_to_char_buffer (value, str_buf_p, req_sz);
jerry_port_logmsg (stdout, "%s", (const char *) str_buf_p);
}
/* Object reference */
else if (jerry_value_is_object (value))
{
jerry_port_logmsg (stdout, "[JS object]");
}
jerry_port_logmsg (stdout, "\n");
}
```
## Simple JavaScript shell
Now all building blocks, necessary to construct JavaScript shell, are ready.
Shell operation can be described with the following loop:
- read command;
- if command is 'quit'
- exit loop;
- else
- eval (command);
- print result of eval;
- loop.
```c
#include <stdlib.h>
#include <string.h>
#include "jerry-api.h"
#include "jerry-port.h"
static void print_value (const jerry_api_value_t);
int
main (int argc, char * argv[])
{
bool is_done = false;
/* Initialize engine */
jerry_init (JERRY_INIT_EMPTY);
while (!is_done)
{
char cmd [256];
char *cmd_tail = cmd;
size_t len = 0;
jerry_port_logmsg (stdout, "> ");
/* Read next command */
while (true)
{
if (fread (cmd_tail, 1, 1, stdin) != 1 && len == 0)
{
is_done = true;
break;
}
if (*cmd_tail == '\n')
{
break;
}
cmd_tail++;
len++;
}
jerry_value_t ret_val;
/* Evaluate entered command */
ret_val = jerry_eval ((const jerry_char_t *) cmd,
len,
false);
/* If command evaluated successfully, print value, returned by eval */
if (jerry_value_has_error_flag (ret_val))
{
/* Evaluated JS code thrown an exception
* and didn't handle it with try-catch-finally */
jerry_port_errormsg ("Unhandled JS exception occured: ");
}
print_value (ret_val);
jerry_release_value (ret_val);
}
/* Cleanup engine */
jerry_cleanup ();
return 0;
}
```
The application inputs commands and evaluates them, one after another.
## Step 6. Creating JS object in global context
In this example we demonstrate how to use native function and structures in JavaScript.
```c
#include <string.h>
#include "jerry-api.h"
struct my_struct
{
const char *msg;
} my_struct;
/**
* Get a string from a native object
*/
static jerry_value_t
get_msg_handler (const jerry_value_t func_value, /**< function object */
const jerry_value_t this_value, /**< this arg */
const jerry_value_t *args_p, /**< function arguments */
const jerry_length_t args_cnt) /**< number of function arguments */
{
return jerry_create_string ((const jerry_char_t *) my_struct.msg);
} /* get_msg_handler */
int
main (int argc, char * argv[])
{
/* Initialize engine */
jerry_init (JERRY_INIT_EMPTY);
/* Do something with the native object */
my_struct.msg = "Hello World";
/* Create an empty JS object */
jerry_value_t object = jerry_create_object ();
/* Create a JS function object and wrap into a jerry value */
jerry_value_t func_obj = jerry_create_external_function (get_msg_handler);
/* Set the native function as a property of the empty JS object */
jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "myFunc");
jerry_set_property (object, prop_name, func_obj);
jerry_release_value (prop_name);
jerry_release_value (func_obj);
/* Wrap the JS object (not empty anymore) into a jerry api value */
jerry_value_t global_object = jerry_get_global_object ();
/* Add the JS object to the global context */
prop_name = jerry_create_string ((const jerry_char_t *) "MyObject");
jerry_set_property (global_object, prop_name, object);
jerry_release_value (prop_name);
jerry_release_value (object);
jerry_release_value (global_object);
/* Now we have a "builtin" object called MyObject with a function called myFunc()
*
* Equivalent JS code:
* var MyObject = { myFunc : function () { return "some string value"; } }
*/
const jerry_char_t script[] = " \
var str = MyObject.myFunc (); \
print (str); \
";
size_t script_size = strlen ((const char *) script);
/* Evaluate script */
jerry_value_t eval_ret = jerry_eval (script, script_size, false);
/* Free JavaScript value, returned by eval */
jerry_release_value (eval_ret);
/* Cleanup engine */
jerry_cleanup ();
return 0;
}
```
The application will generate the following output:
```bash
Hello World
```
## Step 7. Extending JS Objects with native functions
Here we create a JS Object with `jerry_eval`, then extend it with a native function. This function shows how to get a property value from the object and how to manipulate it.
```c
#include <string.h>
#include "jerry-api.h"
/**
* Add param to 'this.x'
*/
static jerry_value_t
add_handler (const jerry_value_t func_value, /**< function object */
const jerry_value_t this_val, /**< this arg */
const jerry_value_t *args_p, /**< function arguments */
const jerry_length_t args_cnt) /**< number of function arguments */
{
/* Get 'this.x' */
jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "x");
jerry_value_t x_val = jerry_get_property (this_val, prop_name);
if (!jerry_value_has_error_flag (x_val))
{
/* Convert Jerry API values to double */
double x = jerry_get_number_value (x_val);
double d = jerry_get_number_value (*args_p);
/* Add the parameter to 'x' */
jerry_value_t res_val = jerry_create_number (x + d);
/* Set the new value of 'this.x' */
jerry_set_property (this_val, prop_name, res_val);
jerry_release_value (res_val);
}
jerry_release_value (x_val);
jerry_release_value (prop_name);
return jerry_create_undefined ();
} /* add_handler */
int
main (int argc, char * argv[])
{
/* Initialize engine */
jerry_init (JERRY_INIT_EMPTY);
/* Create a JS object */
const jerry_char_t my_js_object[] = " \
MyObject = \
{ x : 12, \
y : 'Value of x is ', \
foo: function () \
{ \
return this.y + this.x; \
} \
} \
";
jerry_value_t my_js_obj_val;
/* Evaluate script */
my_js_obj_val = jerry_eval (my_js_object,
strlen ((const char *) my_js_object),
false);
/* Create a JS function object and wrap into a jerry value */
jerry_value_t add_func_obj = jerry_create_external_function (add_handler);
/* Set the native function as a property of previously created MyObject */
jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "add2x");
jerry_set_property (my_js_obj_val, prop_name, add_func_obj);
jerry_release_value (add_func_obj);
jerry_release_value (prop_name);
/* Free JavaScript value, returned by eval (my_js_object) */
jerry_release_value (my_js_obj_val);
const jerry_char_t script[] = " \
var str = MyObject.foo (); \
print (str); \
MyObject.add2x (5); \
print (MyObject.foo ()); \
";
size_t script_size = strlen ((const char *) script);
/* Evaluate script */
jerry_value_t eval_ret = jerry_eval (script, script_size, false);
/* Free JavaScript value, returned by eval */
jerry_release_value (eval_ret);
/* Cleanup engine */
jerry_cleanup ();
return 0;
}
```
The application will generate the following output:
```bash
Value of x is 12
Value of x is 17
```
## Further steps
For further API description, please visit [API Reference page](https://samsung.github.io/jerryscript/API/) on [JerryScript home page](https://samsung.github.io/jerryscript/).
-2725
View File
File diff suppressed because it is too large Load Diff
+5 -3
View File
@@ -10,7 +10,7 @@ permalink: /internals/
# High-Level Design
![High-Level Design]({{ site.baseurl }}/img/engines_high_level_design.png){: class="thumbnail center-block img-responsive" }
On the diagram above is shown interaction of major components of JerryScript: Parser and Virtual Machine (VM). Parser performs translation of input ECMAScript application into the byte-code with the specified format (refer to [Bytecode](#byte-code) and [Parser](#parser) page for details). Prepared bytecode is executed by the Virtual Machine that performs interpretation (refer to [Virtual Machine](#virtual-machine) and [ECMA](#ecma) pages for details).
The diagram above shows the interactions between the major components of JerryScript: Parser and Virtual Machine (VM). Parser performs translation of input ECMAScript application into the byte-code with the specified format (refer to [Bytecode](#byte-code) and [Parser](#parser) page for details). Prepared bytecode is executed by the Virtual Machine that performs interpretation (refer to [Virtual Machine](#virtual-machine) and [ECMA](#ecma) pages for details).
# Parser
@@ -134,7 +134,7 @@ Since most functions require less than 255 literal, small encoding provides a si
## Literal Store
JerryScript do not have a global string table for literals, but stores them into the Literal Store. During the parsing phase, when a new literal appears with the same identifier that already has occurred before, the string won't be stored once again, but the identifier in the Literal Store will be used. If a new literal is not in the Literal Store yet, it will be inserted.
JerryScript does not have a global string table for literals, but stores them into the Literal Store. During the parsing phase, when a new literal appears with the same identifier that has already occurred before, the string won't be stored once again, but the identifier in the Literal Store will be used. If a new literal is not in the Literal Store yet, it will be inserted.
## Byte-code Categories
@@ -245,6 +245,7 @@ simple value is a pre-defined constant which can be:
### Compressed Pointers
Compressed pointers were introduced to save heap space.
![Compressed Pointer]({{ site.baseurl }}/img/ecma_compressed.png){: class="thumbnail center-block img-responsive" }
These pointers are 8 byte alligned 16 bit long pointers which can address 512 Kb of memory which is also the maximum size of the JerryScript heap.
@@ -283,6 +284,7 @@ The objects are represented as following structure:
* type (function object, lexical environment, etc.)
### Properties of Objects
![Object properties]({{ site.baseurl }}/img/ecma_object_property.png){: class="thumbnail center-block img-responsive" }
Objects have a linked list that contains their properties. This list actually contains property pairs, in order to save memory described in the followings:
@@ -314,7 +316,7 @@ Internal properties are special properties that carry meta-information that cann
LCache is a hashmap for finding a property specified by an object and by a property name. The object-name-property layout of the LCache presents multiple times in a row as it is shown in the figure below.
![LCache]({{ site.baseurl }}/img/ecma_lcache.png){: class="thumbnail center-block img-responsive"}
![LCache]({{ site.baseurl }}/img/ecma_lcache.png){: class="thumbnail center-block img-responsive" }
When a property access occurs, a hash value is extracted form the demanded property name and than this hash is used to index the LCache. After that, in the indexed row the specified object and property name will be searched.
-307
View File
@@ -1,307 +0,0 @@
---
layout: page
title: Development
permalink: /dev-guide/
---
* toc
{:toc}
JerryScript Engine can be embedded into any application, providing the way to run JavaScript in a large range of environments - from desktops to low-memory microcontrollers.
This guide is intended to introduce you to JerryScript embedding API through creation of simple JavaScript shell.
## Step 1. Execute JavaScript from your application
{% highlight cpp %}
#include <string.h>
#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);
}
{% endhighlight %}
The application will generate the following output:
{% highlight bash %}
Hello, World!
{% endhighlight %}
## Step 2. Split engine initialization and script execution
Here we perform the same actions, as `jerry_run_simple`, while splitting into several steps:
- engine initialization
- script code setup
- script execution
- engine cleanup
{% highlight cpp %}
#include <string.h>
#include "jerry.h"
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));
// Execute Global scope code
jerry_completion_code_t code = jerry_run ();
// Cleanup engine
jerry_cleanup ();
}
{% endhighlight %}
Our code is more complex now, but it introduces possibilities to interact with JerryScript step-by-step: setup native objects, call JavaScript functions, etc.
## Step 3. Execution in 'eval'-mode
{% highlight cpp %}
#include <string.h>
#include "jerry.h"
int
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;
// Evaluate script1
jerry_api_eval (script1, strlen (script1),
false, false, &eval_ret);
// Free JavaScript value, returned by eval
jerry_api_release_value (&eval_ret);
// 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 ();
}
{% endhighlight %}
This way, we execute two independent script parts in one execution environment. The first part initializes string variable, and the second outputs the variable.
## Step 4. Interaction with JavaScript environment
{% highlight cpp %}
#include <string.h>
#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);
// Constructing 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 ();
}
{% endhighlight %}
The sample will also output 'Hello, World!'. However, now it is not just a part of the source script, but the value, dynamically supplied to the engine.
## Step 5. Description of JavaScript value descriptors
Structure, used to put values to or receive values from the engine is the following:
- `type` of the 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 or received from the engine are described with the structure.
Pointers to strings or objects and values should be released just when become unnecessary, using `jerry_api_release_string` or `jerry_api_release_object` and `jerry_api_release_value`, correspondingly.
The following example function will output a JavaScript value:
{% highlight 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");
}
{% endhighlight %}
## Simple JavaScript shell
Now all building blocks, necessary to construct JavaScript shell, are ready.
Shell operation can be described with the following loop:
- read command;
- if command is 'quit'
- exit loop;
- else
- eval (command);
- print result of eval;
- loop.
{% highlight cpp %}
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerry.h"
static void
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);
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);
}
// Cleanup engine
jerry_cleanup ();
return 0;
}
{% endhighlight %}
The application inputs commands and evaluates them, one after another.
## Further steps
For further API description, please look at [Embedding API](/API).