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:
committed by
László Langó
parent
6e72dd22fe
commit
c0978d1a42
@@ -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
File diff suppressed because it is too large
Load Diff
-100
@@ -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 %}
|
||||
@@ -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/).
|
||||
@@ -10,7 +10,7 @@ permalink: /internals/
|
||||
# High-Level Design
|
||||
{: 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.
|
||||
|
||||
{: 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
|
||||
|
||||
{: 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.
|
||||
|
||||
{: class="thumbnail center-block img-responsive"}
|
||||
{: 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
@@ -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).
|
||||
Reference in New Issue
Block a user