Import of the watch repository from Pebble
144
third_party/jerryscript/docs/01.GETTING-STARTED.md
vendored
Normal file
|
@ -0,0 +1,144 @@
|
|||
## 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 the absolute minimum for building:
|
||||
|
||||
- `gcc` or any C99-compliant compiler (native or cross, e.g., arm-none-eabi)
|
||||
- `cmake` >= `2.8.12.2`
|
||||
|
||||
Several scripts and tools help the building and development process, thus it is recommended to have the following installed as well:
|
||||
|
||||
- `bash` >= `4.3.11`
|
||||
- `cppcheck` >= `1.61`
|
||||
- `vera++` >= `1.2.1`
|
||||
- `python` >= `2.7.6`
|
||||
|
||||
```bash
|
||||
sudo apt-get install gcc gcc-arm-none-eabi cmake cppcheck vera++ python
|
||||
```
|
||||
|
||||
To make our scripts run correctly, several shell utilities should be available on the system:
|
||||
|
||||
- `awk`
|
||||
- `bc`
|
||||
- `find`
|
||||
- `sed`
|
||||
|
||||
## Building JerryScript
|
||||
|
||||
**To build debug version for Linux**
|
||||
|
||||
```bash
|
||||
python tools/build.py --debug
|
||||
```
|
||||
|
||||
**To build debug version for Linux without LTO (Link Time Optimization)**
|
||||
|
||||
```bash
|
||||
python tools/build.py --debug --lto=off
|
||||
```
|
||||
|
||||
**Add custom arguments to CMake**
|
||||
|
||||
```bash
|
||||
python tools/build.py --cmake-param=CMAKE_PARAM
|
||||
```
|
||||
|
||||
**Set a profile mode (full, minimal)**
|
||||
|
||||
```bash
|
||||
python tools/build.py --feature=full|minimal
|
||||
```
|
||||
|
||||
**Use (jerry, compiler-default, external) libc**
|
||||
|
||||
The default libc is jerry-libc, but you can use compiler-default libc or an external libc:
|
||||
|
||||
- compiler-default libc:
|
||||
|
||||
```bash
|
||||
python tools/build.py --jerry-libc=off
|
||||
```
|
||||
|
||||
- external libc:
|
||||
|
||||
```bash
|
||||
python tools/build.py --jerry-libc=off --compile-flag="-nostdlib -I/path/to/ext-libc/include" --link-lib="-lext-c"
|
||||
```
|
||||
|
||||
**Add toolchain file**
|
||||
|
||||
The ```cmake``` dir already contains some usable toolchain files, which you can use in the following format:
|
||||
|
||||
```bash
|
||||
python tools/build.py --toolchain=TOOLCHAIN
|
||||
```
|
||||
|
||||
For example the cross-compile to RaspberryPi 2 is something like this:
|
||||
|
||||
```bash
|
||||
python tools/build.py --toolchain=cmake/toolchain_linux_armv7l.cmake
|
||||
```
|
||||
|
||||
**To get a list of all the available buildoptions for Linux**
|
||||
|
||||
```bash
|
||||
python tools/build.py --help
|
||||
```
|
||||
|
||||
## Checking patch
|
||||
|
||||
```bash
|
||||
python tools/run-tests.py --precommit
|
||||
```
|
||||
|
||||
### Running only one type of test
|
||||
|
||||
**To run build option tests**
|
||||
|
||||
```bash
|
||||
python tools/run-tests.py --buildoption-test
|
||||
```
|
||||
|
||||
**To run unittests**
|
||||
|
||||
```bash
|
||||
python tools/run-tests.py --unittests
|
||||
```
|
||||
|
||||
**To run jerry-tests**
|
||||
|
||||
```bash
|
||||
python tools/run-tests.py --jerry-tests
|
||||
```
|
||||
|
||||
**To run jerry-test-suite**
|
||||
|
||||
```bash
|
||||
python tools/run-tests.py --jerry-test-suite
|
||||
```
|
||||
|
||||
**To run signed-off check**
|
||||
|
||||
```bash
|
||||
python tools/run-tests.py --check-signed-off
|
||||
```
|
||||
|
||||
**To run cppcheck**
|
||||
|
||||
```bash
|
||||
python tools/run-tests.py --check-cppcheck
|
||||
```
|
||||
|
||||
**To run vera check**
|
||||
|
||||
```bash
|
||||
python tools/run-tests.py --check-vera
|
||||
```
|
||||
|
||||
**To get a list of all the available test options**
|
||||
|
||||
```bash
|
||||
python tools/run-tests.py --help
|
||||
```
|
3011
third_party/jerryscript/docs/02.API-REFERENCE.md
vendored
Normal file
515
third_party/jerryscript/docs/03.API-EXAMPLE.md
vendored
Normal file
|
@ -0,0 +1,515 @@
|
|||
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 ? 0 : 1);
|
||||
}
|
||||
```
|
||||
|
||||
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_console ("undefined");
|
||||
}
|
||||
else if (jerry_value_is_null (value))
|
||||
{
|
||||
jerry_port_console ("null");
|
||||
}
|
||||
else if (jerry_value_is_boolean (value))
|
||||
{
|
||||
if (jerry_get_boolean_value (value))
|
||||
{
|
||||
jerry_port_console ("true");
|
||||
}
|
||||
else
|
||||
{
|
||||
jerry_port_console ("false");
|
||||
}
|
||||
}
|
||||
/* Float value */
|
||||
else if (jerry_value_is_number (value))
|
||||
{
|
||||
jerry_port_console ("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);
|
||||
str_buf_p[req_sz] = '\0';
|
||||
|
||||
jerry_port_console ("%s", (const char *) str_buf_p);
|
||||
}
|
||||
/* Object reference */
|
||||
else if (jerry_value_is_object (value))
|
||||
{
|
||||
jerry_port_console ("[JS object]");
|
||||
}
|
||||
|
||||
jerry_port_console ("\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_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_console ("> ");
|
||||
|
||||
/* 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++;
|
||||
}
|
||||
|
||||
/* If the command is "quit", break the loop */
|
||||
if (!strncmp (cmd, "quit\n", strlen ("quit\n")))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
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_console ("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-reference/) on [JerryScript home page](https://samsung.github.io/jerryscript/).
|
332
third_party/jerryscript/docs/04.INTERNALS.md
vendored
Normal file
|
@ -0,0 +1,332 @@
|
|||
# High-Level Design
|
||||

|
||||
|
||||
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
|
||||
|
||||
The parser is implemented as a recursive descent parser. The parser converts the JavaScript source code directly into byte-code without building an Abstract Syntax Tree. The parser depends on the following subcomponents.
|
||||
|
||||
## Lexer
|
||||
|
||||
The lexer splits input string (ECMAScript program) into sequence of tokens. It is able to scan the input string not only forward, but it is possible to move to an arbitrary position. The token structure described by structure `lexer_token_t` in `./jerry-core/parser/js/js-lexer.h`.
|
||||
|
||||
## Scanner
|
||||
|
||||
Scanner (`./jerry-core/parser/js/js-parser-scanner.c`) pre-scans the input string to find certain tokens. For example, scanner determines whether the keyword `for` defines a general for or a for-in loop. Reading tokens in a while loop is not enough because a slash (`/`) can indicate the start of a regular expression or can be a division operator.
|
||||
|
||||
## Expression Parser
|
||||
|
||||
Expression parser is responsible for parsing JavaScript expressions. It is implemented in `./jerry-core/parser/js/js-parser-expr.c`.
|
||||
|
||||
## Statement Parser
|
||||
|
||||
JavaScript statements are parsed by this component. It uses the [Expression parser](#expression-parser) to parse the constituent expressions. The implementation of Statement parser is located in `./jerry-core/parser/js/js-parser-statm.c`.
|
||||
|
||||
Function `parser_parse_source` carries out the parsing and compiling of the input EcmaScript source code. When a function appears in the source `parser_parse_source` calls `parser_parse_function` which is responsible for processing the source code of functions recursively including argument parsing and context handling. After the parsing, function `parser_post_processing` dumps the created opcodes and returns an `ecma_compiled_code_t*` that points to the compiled bytecode sequence.
|
||||
|
||||
The interactions between the major components shown on the following figure.
|
||||
|
||||

|
||||
|
||||
# Byte-code
|
||||
|
||||
This section describes the compact byte-code (CBC) byte-code representation. The key focus is reducing memory consumption of the byte-code representation without sacrificing considerable performance. Other byte-code representations often focus on performance only so inventing this representation is an original research.
|
||||
|
||||
CBC is a CISC like instruction set which assigns shorter instructions for frequent operations. Many instructions represent multiple atomic tasks which reduces the byte code size. This technique is basically a data compression method.
|
||||
|
||||
## Compiled Code Format
|
||||
|
||||
The memory layout of the compiled byte code is the following.
|
||||
|
||||

|
||||
|
||||
The header is a `cbc_compiled_code` structure with several fields. These fields contain the key properties of the compiled code.
|
||||
|
||||
The literals part is an array of ecma values. These values can contain any EcmaScript value types, e.g. strings, numbers, function and regexp templates. The number of literals is stored in the `literal_end` field of the header.
|
||||
|
||||
CBC instruction list is a sequence of byte code instructions which represents the compiled code.
|
||||
|
||||
## Byte-code Format
|
||||
|
||||
The memory layout of a byte-code is the following:
|
||||
|
||||

|
||||
|
||||
Each byte-code starts with an opcode. The opcode is one byte long for frequent and two byte long for rare instructions. The first byte of the rare instructions is always zero (`CBC_EXT_OPCODE`), and the second byte represents the extended opcode. The name of common and rare instructions start with `CBC_` and `CBC_EXT_` prefix respectively.
|
||||
|
||||
The maximum number of opcodes is 511, since 255 common (zero value excluded) and 256 rare instructions can be defined. Currently around 230 frequent and 120 rare instructions are available.
|
||||
|
||||
There are three types of bytecode arguments in CBC:
|
||||
|
||||
* __byte argument__: A value between 0 and 255, which often represents the argument count of call like opcodes (function call, new, eval, etc.).
|
||||
|
||||
* __literal argument__: An integer index which is greater or equal than zero and less than the `literal_end` field of the header. For further information see next section Literals (next).
|
||||
|
||||
* __relative branch__: An 1-3 byte long offset. The branch argument might also represent the end of an instruction range. For example the branch argument of `CBC_EXT_WITH_CREATE_CONTEXT` shows the end of a `with` statement. More precisely the position after the last instruction.
|
||||
|
||||
Argument combinations are limited to the following seven forms:
|
||||
|
||||
* no arguments
|
||||
* a literal argument
|
||||
* a byte argument
|
||||
* a branch argument
|
||||
* a byte and a literal arguments
|
||||
* two literal arguments
|
||||
* three literal arguments
|
||||
|
||||
## Literals
|
||||
|
||||
Literals are organized into groups whose represent various literal types. Having these groups consuming less space than assigning flag bits to each literal.
|
||||
(In the followings, the mentioned ranges represent those indicies which are greater than or equal to the left side and less than the right side of the range. For example a range between `ident_end` and `literal_end` fields of the byte-code header contains those indicies, which are greater than or equal to `ident_end`
|
||||
and less than `literal_end`. If `ident_end` equals to `literal_end` the range is empty.)
|
||||
|
||||
The two major group of literals are _identifiers_ and _values_.
|
||||
|
||||
* __identifier__: A named reference to a variable. Literals between zero and `ident_end` of the header belongs to here. All of these literals must be a string or undefined. Undefined can only be used for those literals which cannot be accessed by a literal name. For example `function (arg,arg)` has two arguments, but the `arg` identifier only refers to the second argument. In such cases the name of the first argument is undefined. Furthermore optimizations such as *CSE* may also introduce literals without name.
|
||||
|
||||
* __value__: A reference to an immediate value. Literals between `ident_end` and `const_literal_end` are constant values such as numbers or strings. These literals can be used directly by the Virtual Machine. Literals between `const_literal_end` and `literal_end` are template literals. A new object needs to be constructed each time when their value is accessed. These literals are functions and regular expressions.
|
||||
|
||||
There are two other sub-groups of identifiers. *Registers* are those identifiers which are stored in the function call stack. *Arguments* are those registers which are passed by a caller function.
|
||||
|
||||
There are two types of literal encoding in CBC. Both are variable length, where the length is one or two byte long.
|
||||
|
||||
* __small__: maximum 511 literals can be encoded.
|
||||
|
||||
One byte encoding for literals 0 - 254.
|
||||
|
||||
```c
|
||||
byte[0] = literal_index
|
||||
```
|
||||
|
||||
Two byte encoding for literals 255 - 510.
|
||||
|
||||
```c
|
||||
byte[0] = 0xff
|
||||
byte[1] = literal_index - 0xff
|
||||
```
|
||||
|
||||
* __full__: maximum 32767 literal can be encoded.
|
||||
|
||||
One byte encoding for literals 0 - 127.
|
||||
|
||||
```c
|
||||
byte[0] = literal_index
|
||||
```
|
||||
|
||||
Two byte encoding for literals 128 - 32767.
|
||||
|
||||
```c
|
||||
byte[0] = (literal_index >> 8) | 0x80
|
||||
byte[1] = (literal_index & 0xff)
|
||||
```
|
||||
|
||||
Since most functions require less than 255 literal, small encoding provides a single byte literal index for all literals. Small encoding consumes less space than full encoding, but it has a limited range.
|
||||
|
||||
## Literal Store
|
||||
|
||||
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
|
||||
|
||||
Byte-codes can be placed into four main categories.
|
||||
|
||||
### Push Byte-codes
|
||||
|
||||
Byte-codes of this category serve for placing objects onto the stack. As there are many instructions representing multiple atomic tasks in CBC, there are also many instructions for pushing objects onto the stack according to the number and the type of the arguments. The following table list a few of these opcodes with a brief description.
|
||||
|
||||
<span class="CSSTableGenerator" markdown="block">
|
||||
|
||||
| byte-code | description |
|
||||
| --------------------- | ---------------------------------------------------- |
|
||||
| CBC_PUSH_LITERAL | Pushes the value of the given literal argument. |
|
||||
| CBC_PUSH_TWO_LITERALS | Pushes the value of the given two literal arguments. |
|
||||
| CBC_PUSH_UNDEFINED | Pushes an undefined value. |
|
||||
| CBC_PUSH_TRUE | Pushes a logical true. |
|
||||
| CBC_PUSH_PROP_LITERAL | Pushes a property whose base object is popped from the stack, and the property name is passed as a literal argument. |
|
||||
|
||||
</span>
|
||||
|
||||
### Call Byte-codes
|
||||
|
||||
The byte-codes of this category perform calls in different ways.
|
||||
|
||||
<span class="CSSTableGenerator" markdown="block">
|
||||
|
||||
| byte-code | description |
|
||||
| --------------------- | ------------------------------------------------------------------------------------ |
|
||||
| CBC_CALL0 | Calls a function without arguments. The return value won't be pushed onto the stack. |
|
||||
| CBC_CALL1 | Calls a function with one argument. The return value won't be pushed onto the stack. |
|
||||
| CBC_CALL | Calls a function with n arguments. n is passed as a byte argument. The return value won't be pushed onto the stack. |
|
||||
| CBC_CALL0_PUSH_RESULT | Calls a function without arguments. The return value will be pushed onto the stack. |
|
||||
| CBC_CALL1_PUSH_RESULT | Calls a function with one argument. The return value will be pushed onto the stack. |
|
||||
| CBC_CALL2_PROP | Calls a property function with two arguments. The base object, the property name, and the two arguments are on the stack. |
|
||||
|
||||
</span>
|
||||
|
||||
### Arithmetic, Logical, Bitwise and Assignment Byte-codes
|
||||
|
||||
The opcodes of this category perform arithmetic, logical, bitwise and assignment operations.
|
||||
|
||||
<span class="CSSTableGenerator" markdown="block">
|
||||
|
||||
| byte-code | description |
|
||||
| ----------------------- | --------------------------------------------------------------------------------------------------- |
|
||||
| CBC_LOGICAL_NOT | Negates the logical value that popped from the stack. The result is pushed onto the stack. |
|
||||
| CBC_LOGICAL_NOT_LITERAL | Negates the logical value that given in literal argument. The result is pushed onto the stack. |
|
||||
| CBC_ADD | Adds two values that are popped from the stack. The result is pushed onto the stack. |
|
||||
| CBC_ADD_RIGHT_LITERAL | Adds two values. The left one popped from the stack, the right one is given as literal argument. |
|
||||
| CBC_ADD_TWO_LITERALS | Adds two values. Both are given as literal arguments. |
|
||||
| CBC_ASSIGN | Assigns a value to a property. It has three arguments: base object, property name, value to assign. |
|
||||
| CBC_ASSIGN_PUSH_RESULT | Assigns a value to a property. It has three arguments: base object, property name, value to assign. The result will be pushed onto the stack. |
|
||||
|
||||
</span>
|
||||
|
||||
### Branch Byte-codes
|
||||
|
||||
Branch byte-codes are used to perform conditional and unconditional jumps in the byte-code. The arguments of these instructions are 1-3 byte long relative offsets. The number of bytes is part of the opcode, so each byte-code with a branch argument has three forms. The direction (forward, backward) is also defined by the opcode since the offset is an unsigned value. Thus, certain branch instructions has six forms. Some examples can be found in the following table.
|
||||
|
||||
<span class="CSSTableGenerator" markdown="block">
|
||||
|
||||
| byte-code | description |
|
||||
| -------------------------- | ----------------------------------------------------------- |
|
||||
| CBC_JUMP_FORWARD | Jumps forward by the 1 byte long relative offset argument. |
|
||||
| CBC_JUMP_FORWARD_2 | Jumps forward by the 2 byte long relative offset argument. |
|
||||
| CBC_JUMP_FORWARD_3 | Jumps forward by the 3 byte long relative offset argument. |
|
||||
| CBC_JUMP_BACKWARD | Jumps backward by the 1 byte long relative offset argument. |
|
||||
| CBC_JUMP_BACKWARD_2 | Jumps backward by the 2 byte long relative offset argument. |
|
||||
| CBC_JUMP_BACKWARD_3 | Jumps backward by the 3 byte long relative offset argument. |
|
||||
| CBC_BRANCH_IF_TRUE_FORWARD | Jumps if the value on the top of the stack is true by the 1 byte long relative offset argument. |
|
||||
|
||||
</span>
|
||||
|
||||
## Snapshot
|
||||
|
||||
The compiled byte-code can be saved into a snapshot, which also can be loaded back for execution. Directly executing the snapshot saves the costs of parsing the source in terms of memory consumption and performance. The snapshot can also be executed from ROM, in which case the overhead of loading it into the memory can also be saved.
|
||||
|
||||
|
||||
# Virtual Machine
|
||||
|
||||
Virtual machine is an interpreter which executes byte-code instructions one by one. The function that starts the interpretation is `vm_run` in `./jerry-core/vm/vm.c`. `vm_loop` is the main loop of the virtual machine, which has the peculiarity that it is *non-recursive*. This means that in case of function calls it does not calls itself recursively but returns, which has the benefit that it does not burdens the stack as a recursive implementation.
|
||||
|
||||
# ECMA
|
||||
|
||||
ECMA component of the engine is responsible for the following notions:
|
||||
|
||||
* Data representation
|
||||
* Runtime representation
|
||||
* Garbage collection (GC)
|
||||
|
||||
## Data Representation
|
||||
|
||||
The major structure for data representation is `ECMA_value`. The lower two bits of this structure encode value tag, which determines the type of the value:
|
||||
|
||||
* simple
|
||||
* number
|
||||
* string
|
||||
* object
|
||||
|
||||

|
||||
|
||||
In case of number, string and object the value contains an encoded pointer, and
|
||||
simple value is a pre-defined constant which can be:
|
||||
|
||||
* undefined
|
||||
* null
|
||||
* true
|
||||
* false
|
||||
* empty (uninitialized value)
|
||||
|
||||
### Compressed Pointers
|
||||
|
||||
Compressed pointers were introduced to save heap space.
|
||||
|
||||

|
||||
|
||||
These pointers are 8 byte aligned 16 bit long pointers which can address 512 Kb of
|
||||
memory which is also the maximum size of the JerryScript heap. To support even more
|
||||
memory the size of compressed pointers can be extended to 32 bit to cover the entire
|
||||
address space of a 32 bit system by passing "--cpointer_32_bit on" to the build
|
||||
system. These "uncompressed pointers" increases the memory consumption by around 20%.
|
||||
|
||||
### Number
|
||||
|
||||
There are two possible representation of numbers according to standard IEEE 754:
|
||||
The default is 8-byte (double),
|
||||
but the engine supports the 4-byte (single precision) representation by setting CONFIG_ECMA_NUMBER_TYPE as well.
|
||||
|
||||

|
||||
|
||||
Several references to single allocated number are not supported. Each reference holds its own copy of a number.
|
||||
|
||||
### String
|
||||
|
||||
Strings in JerryScript are not just character sequences, but can hold numbers and so-called magic ids too. For common character sequences there is a table in the read only memory that contains magic id and character sequence pairs. If a string is already in this table, the magic id of its string is stored, not the character sequence itself. Using numbers speeds up the property access. These techniques save memory.
|
||||
|
||||
### Object / Lexical Environment
|
||||
|
||||
An object can be a conventional data object or a lexical environment object. Unlike other data types, object can have references (called properties) to other data types. Because of circular references, reference counting is not always enough to determine dead objects. Hence a chain list is formed from all existing objects, which can be used to find unreferenced objects during garbage collection. The `gc-next` pointer of each object shows the next allocated object in the chain list.
|
||||
|
||||
[Lexical environments](http://www.ecma-international.org/ecma-262/5.1/#sec-10.2) are implemented as objects in JerryScript, since lexical environments contains key-value pairs (called bindings) like objects. This simplifies the implementation and reduces code size.
|
||||
|
||||

|
||||
|
||||
The objects are represented as following structure:
|
||||
|
||||
* Reference counter - number of hard (non-property) references
|
||||
* Next object pointer for the garbage collector
|
||||
* GC's visited flag
|
||||
* type (function object, lexical environment, etc.)
|
||||
|
||||
### Properties of Objects
|
||||
|
||||

|
||||
|
||||
Objects have a linked list that contains their properties. This list actually contains property pairs, in order to save memory described in the followings:
|
||||
A property is 7 bit long and its type field is 2 bit long which consumes 9 bit which does not fit into 1 byte but consumes 2 bytes. Hence, placing together two properties (14 bit) with the 2 bit long type field fits into 2 bytes.
|
||||
|
||||
#### Property Hashmap
|
||||
|
||||
If the number of property pairs reach a limit (currently this limit is defined to 16), a hash map (called [Property Hashmap](#property-hashmap)) is inserted at the first position of the property pair list, in order to find a property using it, instead of finding it by iterating linearly over the property pairs.
|
||||
|
||||
Property hashmap contains 2<sup>n</sup> elements, where 2<sup>n</sup> is larger than the number of properties of the object. Each element can have tree types of value:
|
||||
|
||||
* null, indicating an empty element
|
||||
* deleted, indicating a deleted property, or
|
||||
* reference to the existing property
|
||||
|
||||
This hashmap is a must-return type cache, meaning that every property that the object have, can be found using it.
|
||||
|
||||
#### Internal Properties
|
||||
|
||||
Internal properties are special properties that carry meta-information that cannot be accessed by the JavaScript code, but important for the engine itself. Some examples of internal properties are listed below:
|
||||
|
||||
* [[Class]] - class (type) of the object (ECMA-defined)
|
||||
* [[Code]] - points where to find bytecode of the function
|
||||
* native code - points where to find the code of a native function
|
||||
* [[PrimitiveValue]] for Boolean - stores the boolean value of a Boolean object
|
||||
* [[PrimitiveValue]] for Number - stores the numeric value of a Number object
|
||||
|
||||
### LCache
|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
When a property access occurs, a hash value is extracted from 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.
|
||||
|
||||
It is important to note, that if the specified property is not found in the LCache, it does not mean that it does not exist (i.e. LCache is a may-return cache). If the property is not found, it will be searched in the property-list of the object, and if it is found there, the property will be placed into the LCache.
|
||||
|
||||
### Collections
|
||||
|
||||
Collections are array-like data structures, which are optimized to save memory. Actually, a collection is a linked list whose elements are not single elements, but arrays which can contain multiple elements.
|
||||
|
||||
### Exception Handling
|
||||
|
||||
In order to implement a sense of exception handling, the return values of JerryScript functions are able to indicate their faulty or "exceptional" operation. The return values are actually ECMA values (see section [Data Representation](#data-representation)) in which the error bit is set if an erroneous operation is occurred.
|
||||
|
||||
### Value Management and Ownership
|
||||
|
||||
Every ECMA value stored by the engine is associated with a virtual "ownership", that defines how to manage the value: when to free it when it is not needed anymore and how to pass the value to an other function.
|
||||
|
||||
Initially, value is allocated by its owner (i.e. with ownership). The owner has the responsibility for freeing the allocated value. When the value is passed to a function as an argument, the ownership of it will not pass, the called function have to make an own copy of the value. However, as long as a function returns a value, the ownership will pass, thus the caller will be responsible for freeing it.
|
210
third_party/jerryscript/docs/05.PORT-API.md
vendored
Normal file
|
@ -0,0 +1,210 @@
|
|||
# Reference
|
||||
|
||||
## Termination
|
||||
|
||||
It 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.
|
||||
|
||||
```c
|
||||
/**
|
||||
* Signal the port that jerry experienced a fatal failure from which it cannot
|
||||
* recover.
|
||||
*
|
||||
* @param code gives the cause of the error.
|
||||
*
|
||||
* Note: jerry expects the function not to return.
|
||||
*
|
||||
* Example: a libc-based port may implement this with exit() or abort(), or both.
|
||||
*/
|
||||
void jerry_port_fatal (jerry_fatal_code_t code);
|
||||
```
|
||||
|
||||
Error codes
|
||||
|
||||
```c
|
||||
typedef enum
|
||||
{
|
||||
ERR_OUT_OF_MEMORY = 10,
|
||||
ERR_SYSCALL = 11,
|
||||
ERR_REF_COUNT_LIMIT = 12,
|
||||
ERR_FAILED_INTERNAL_ASSERTION = 120
|
||||
} jerry_fatal_code_t;
|
||||
```
|
||||
|
||||
## I/O
|
||||
|
||||
These are the only I/O functions jerry calls.
|
||||
|
||||
```c
|
||||
/**
|
||||
* Print a string to the console. The function should implement a printf-like
|
||||
* interface, where the first argument specifies a format string on how to
|
||||
* stringify the rest of the parameter list.
|
||||
*
|
||||
* This function is only called with strings coming from the executed ECMAScript
|
||||
* wanting to print something as the result of its normal operation.
|
||||
*
|
||||
* It should be the port that decides what a "console" is.
|
||||
*
|
||||
* Example: a libc-based port may implement this with vprintf().
|
||||
*/
|
||||
void jerry_port_console (const char *fmt, ...);
|
||||
|
||||
/**
|
||||
* Jerry log levels. The levels are in severity order
|
||||
* where the most serious levels come first.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
JERRY_LOG_LEVEL_ERROR, /**< the engine will terminate after the message is printed */
|
||||
JERRY_LOG_LEVEL_WARNING, /**< a request is aborted, but the engine continues its operation */
|
||||
JERRY_LOG_LEVEL_DEBUG, /**< debug messages from the engine, low volume */
|
||||
JERRY_LOG_LEVEL_TRACE /**< detailed info about engine internals, potentially high volume */
|
||||
} jerry_log_level_t;
|
||||
|
||||
/**
|
||||
* Display or log a debug/error message. The function should implement a printf-like
|
||||
* interface, where the first argument specifies the log level
|
||||
* and the second argument specifies a format string on how to stringify the rest
|
||||
* of the parameter list.
|
||||
*
|
||||
* This function is only called with messages coming from the jerry engine as
|
||||
* the result of some abnormal operation or describing its internal operations
|
||||
* (e.g., data structure dumps or tracing info).
|
||||
*
|
||||
* It should be the port that decides whether error and debug messages are logged to
|
||||
* the console, or saved to a database or to a file.
|
||||
*
|
||||
* Example: a libc-based port may implement this with vfprintf(stderr) or
|
||||
* vfprintf(logfile), or both, depending on log level.
|
||||
*/
|
||||
void jerry_port_log (jerry_log_level_t level, const char *fmt, ...);
|
||||
```
|
||||
|
||||
## Date
|
||||
|
||||
```c
|
||||
/**
|
||||
* Jerry time zone structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int offset; /**< minutes from west */
|
||||
int daylight_saving_time; /**< daylight saving time (1 - DST applies, 0 - not on DST) */
|
||||
} jerry_time_zone_t;
|
||||
|
||||
/**
|
||||
* Get timezone and daylight saving data
|
||||
*
|
||||
* @return true - if success
|
||||
* false - otherwise
|
||||
*/
|
||||
bool jerry_port_get_time_zone (jerry_time_zone_t *);
|
||||
|
||||
/**
|
||||
* Get system time
|
||||
*
|
||||
* @return milliseconds since Unix epoch
|
||||
*/
|
||||
double jerry_port_get_current_time (void);
|
||||
```
|
||||
|
||||
# How to port JerryScript
|
||||
|
||||
This section describes a basic port implementation which was created for Unix based systems.
|
||||
|
||||
## Termination
|
||||
|
||||
```c
|
||||
#include <stdlib.h>
|
||||
#include "jerry-port.h"
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_fatal.
|
||||
*/
|
||||
void jerry_port_fatal (jerry_fatal_code_t code)
|
||||
{
|
||||
exit (code);
|
||||
} /* jerry_port_fatal */
|
||||
```
|
||||
|
||||
## I/O
|
||||
|
||||
```c
|
||||
#include <stdarg.h>
|
||||
#include "jerry-port.h"
|
||||
|
||||
/**
|
||||
* Provide console message implementation for the engine.
|
||||
*/
|
||||
void
|
||||
jerry_port_console (const char *format, /**< format string */
|
||||
...) /**< parameters */
|
||||
{
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
vfprintf (stdout, format, args);
|
||||
va_end (args);
|
||||
} /* jerry_port_console */
|
||||
|
||||
/**
|
||||
* Provide log message implementation for the engine.
|
||||
*
|
||||
* Note:
|
||||
* This example ignores the log level.
|
||||
*/
|
||||
void
|
||||
jerry_port_log (jerry_log_level_t level, /**< log level */
|
||||
const char *format, /**< format string */
|
||||
...) /**< parameters */
|
||||
{
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
vfprintf (stderr, format, args);
|
||||
va_end (args);
|
||||
} /* jerry_port_log */
|
||||
```
|
||||
|
||||
## Date
|
||||
|
||||
```c
|
||||
#include <sys/time.h>
|
||||
#include "jerry-port.h"
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_get_time_zone.
|
||||
*/
|
||||
bool jerry_port_get_time_zone (jerry_time_zone_t *tz_p)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
|
||||
/* gettimeofday may not fill tz, so zero-initializing */
|
||||
tz.tz_minuteswest = 0;
|
||||
tz.tz_dsttime = 0;
|
||||
|
||||
if (gettimeofday (&tv, &tz) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
tz_p->offset = tz.tz_minuteswest;
|
||||
tz_p->daylight_saving_time = tz.tz_dsttime > 0 ? 1 : 0;
|
||||
|
||||
return true;
|
||||
} /* jerry_port_get_time_zone */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_get_current_time.
|
||||
*/
|
||||
double jerry_port_get_current_time ()
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
if (gettimeofday (&tv, NULL) != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ((double) tv.tv_sec) * 1000.0 + ((double) tv.tv_usec) / 1000.0;
|
||||
} /* jerry_port_get_current_time */
|
||||
```
|
BIN
third_party/jerryscript/docs/img/CBC_layout.png
vendored
Normal file
After Width: | Height: | Size: 8.6 KiB |
BIN
third_party/jerryscript/docs/img/bytecode-layout.png
vendored
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
third_party/jerryscript/docs/img/ecma_compressed.png
vendored
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
third_party/jerryscript/docs/img/ecma_lcache.png
vendored
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
third_party/jerryscript/docs/img/ecma_object.png
vendored
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
third_party/jerryscript/docs/img/ecma_object_property.png
vendored
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
third_party/jerryscript/docs/img/ecma_value.png
vendored
Normal file
After Width: | Height: | Size: 7 KiB |
BIN
third_party/jerryscript/docs/img/engines_high_level_design.png
vendored
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
third_party/jerryscript/docs/img/number.png
vendored
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
third_party/jerryscript/docs/img/opcode_layout.png
vendored
Normal file
After Width: | Height: | Size: 9.3 KiB |
BIN
third_party/jerryscript/docs/img/parser_dependency.png
vendored
Normal file
After Width: | Height: | Size: 54 KiB |