Update Jerry API

* Removed jerry_string_t and jerry_object_t
* Updated function names
* Updated return values
* Updated function descriptions
* Added new functions
* Added new unittests

JerryScript-DCO-1.0-Signed-off-by: László Langó llango.u-szeged@partner.samsung.com
This commit is contained in:
László Langó
2016-06-29 08:41:15 +02:00
parent cea3a142ac
commit 9bce5b09a9
19 changed files with 2077 additions and 2112 deletions
+108 -174
View File
@@ -6,7 +6,7 @@ This guide is intended to introduce you to JerryScript embedding API through cre
```c
#include <string.h>
#include "jerry.h"
#include "jerry-api.h"
int
main (int argc, char * argv[])
@@ -14,11 +14,9 @@ main (int argc, char * argv[])
const jerry_char_t script[] = "print ('Hello, World!');";
size_t script_size = strlen ((const char *) script);
jerry_completion_code_t return_code = jerry_run_simple (script,
script_size,
JERRY_FLAG_EMPTY);
bool ret_value = jerry_run_simple (script, script_size, JERRY_INIT_EMPTY);
return (int) return_code;
return (ret_value ? 1 : 0);
}
```
@@ -40,7 +38,7 @@ Here we perform the same actions, as `jerry_run_simple`, while splitting into se
```c
#include <string.h>
#include "jerry.h"
#include "jerry-api.h"
int
main (int argc, char * argv[])
@@ -49,28 +47,23 @@ main (int argc, char * argv[])
size_t script_size = strlen ((const char *) script);
/* Initialize engine */
jerry_init (JERRY_FLAG_EMPTY);
jerry_init (JERRY_INIT_EMPTY);
/* Setup Global scope code */
jerry_object_t *error_object_p = NULL;
if (!jerry_parse (script, script_size, &error_object_p))
{
/* Error object must be freed, if parsing failed */
jerry_release_object (error_object_p);
}
else
{
/* Execute Global scope code */
jerry_value_t error_value = jerry_create_undefined_value ();
jerry_completion_code_t return_code = jerry_run (&error_value);
jerry_value_t parsed_code = jerry_parse (script, script_size, false);
if (return_code == JERRY_COMPLETION_CODE_UNHANDLED_EXCEPTION)
{
/* Error value must be freed, if 'jerry_run' returns with an unhandled exception */
jerry_release_value (error_value);
}
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 ();
@@ -84,7 +77,7 @@ Our code is more complex now, but it introduces possibilities to interact with J
```c
#include <string.h>
#include "jerry.h"
#include "jerry-api.h"
int
main (int argc, char * argv[])
@@ -93,26 +86,22 @@ main (int argc, char * argv[])
const jerry_char_t script_2[] = "print (s);";
/* Initialize engine */
jerry_init (JERRY_FLAG_EMPTY);
jerry_init (JERRY_INIT_EMPTY);
jerry_value_t eval_ret;
/* Evaluate script1 */
jerry_eval (script_1,
strlen ((const char *) script_1),
false,
false,
&eval_ret);
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 */
jerry_eval (script_2,
strlen ((const char *) script_2),
false,
false,
&eval_ret);
eval_ret = jerry_eval (script_2,
strlen ((const char *) script_2),
false);
/* Free JavaScript value, returned by eval */
jerry_release_value (eval_ret);
@@ -130,43 +119,37 @@ This way, we execute two independent script parts in one execution environment.
```c
#include <string.h>
#include "jerry.h"
#include "jerry-api.h"
int
main (int argc, char * argv[]) {
const jerry_char_t str[] = "Hello, World!";
const jerry_char_t var_name[] = "s";
const jerry_char_t script[] = "print (s);";
/* Initializing JavaScript environment */
jerry_init (JERRY_FLAG_EMPTY);
jerry_init (JERRY_INIT_EMPTY);
/* Getting pointer to the Global object */
jerry_object_t *object_p = jerry_get_global ();
jerry_value_t global_object = jerry_get_global_object ();
/* Constructing string */
jerry_string_t *str_val_p = jerry_create_string (str);
/* Constructing strings */
jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "s");
jerry_value_t prop_value = jerry_create_string (str);
/* Constructing string value descriptor */
jerry_value_t value = jerry_create_string_value (str_val_p);
/* Setting the string value as a property of the Global object */
jerry_set_property (global_object, prop_name, prop_value);
/* Setting the string value to field of the Global object */
jerry_set_object_field_value (object_p, var_name, value);
/* Releasing string values, as it is no longer necessary outside of engine */
jerry_release_value (prop_name);
jerry_release_value (prop_value);
/* Releasing string value, as it is no longer necessary outside of engine */
jerry_release_string (str_val_p);
/* Same for pointer to the Global object */
jerry_release_object (object_p);
jerry_value_t eval_ret;
/* Releasing the Global object */
jerry_release_value (global_object);
/* Now starting script that would output value of just initialized field */
jerry_eval (script,
strlen ((const char *) script),
false,
false,
&eval_ret);
jerry_value_t eval_ret = jerry_eval (script,
strlen ((const char *) script),
false);
/* Free JavaScript value, returned by eval */
jerry_release_value (eval_ret);
@@ -180,36 +163,23 @@ main (int argc, char * argv[]) {
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
## Step 5. Description of JerryScript 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_VOID (void);
- JERRY_API_DATA_TYPE_UNDEFINED (undefined);
- JERRY_API_DATA_TYPE_NULL (null);
- JERRY_API_DATA_TYPE_BOOLEAN (true / false);
- JERRY_API_DATA_TYPE_FLOAT32 (number);
- JERRY_API_DATA_TYPE_FLOAT64 (number);
- JERRY_API_DATA_TYPE_UINT32 (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_float32` (if JERRY_API_DATA_TYPE_FLOAT32) - float value;
- `v_float64` (if JERRY_API_DATA_TYPE_FLOAT64) - double value;
- `v_uint32` (if JERRY_API_DATA_TYPE_UINT32) - 32 bit unsigned integer 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_release_string` or `jerry_release_object` and `jerry_release_value`, correspondingly.
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))
@@ -240,11 +210,10 @@ print_value (const jerry_value_t value)
else if (jerry_value_is_string (value))
{
/* Determining required buffer size */
jerry_string_t *str_p = jerry_get_string_value (value);
jerry_size_t req_sz = jerry_get_string_size (str_p);
jerry_size_t req_sz = jerry_get_string_size (value);
jerry_char_t str_buf_p[req_sz];
jerry_string_to_char_buffer (str_p, 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);
}
@@ -273,22 +242,21 @@ Shell operation can be described with the following loop:
- loop.
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerry.h"
#include "jerry-api.h"
#include "jerry-port.h"
static void print_value (const jerry_api_value_t);
int
main (int argc, char * argv[])
{
jerry_completion_code_t status = JERRY_COMPLETION_CODE_OK;
bool is_done = false;
/* Initialize engine */
jerry_init (JERRY_FLAG_EMPTY);
jerry_init (JERRY_INIT_EMPTY);
while (!is_done)
{
@@ -318,33 +286,26 @@ main (int argc, char * argv[])
jerry_value_t ret_val;
/* Evaluate entered command */
status = jerry_eval ((const jerry_char_t *) cmd,
len,
false,
false,
&ret_val);
ret_val = jerry_eval ((const jerry_char_t *) cmd,
len,
false);
/* If command evaluated successfully, print value, returned by eval */
if (status == JERRY_COMPLETION_CODE_OK)
{
/* 'eval' completed successfully */
print_value (ret_val);
}
else
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);
}
print_value (ret_val);
jerry_release_value (ret_val);
}
/* Cleanup engine */
jerry_cleanup ();
return (int) status;
return 0;
}
```
@@ -356,7 +317,7 @@ In this example we demonstrate how to use native function and structures in Java
```c
#include <string.h>
#include "jerry.h"
#include "jerry-api.h"
struct my_struct
{
@@ -366,53 +327,45 @@ struct my_struct
/**
* Get a string from a native object
*/
static bool
get_msg_handler (const jerry_object_t *function_obj_p, /**< function object */
const jerry_value_t this_p, /**< this arg */
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 */
jerry_value_t *ret_val_p) /**< [out] return argument */
const jerry_length_t args_cnt) /**< number of function arguments */
{
jerry_string_t *msg_str_p = jerry_create_string ((const jerry_char_t *) my_struct.msg);
*ret_val_p = jerry_create_string_value (msg_str_p);
return true;
return jerry_create_string ((const jerry_char_t *) my_struct.msg);
} /* get_msg_handler */
int
main (int argc, char * argv[])
{
jerry_completion_code_t status = JERRY_COMPLETION_CODE_OK;
/* Initialize engine */
jerry_init (JERRY_FLAG_EMPTY);
jerry_init (JERRY_INIT_EMPTY);
/* Do something with the native object */
my_struct.msg = "Hello World";
/* Create an empty JS object */
jerry_object_t *object_p = jerry_create_object ();
jerry_value_t object = jerry_create_object ();
/* Create a JS function object and wrap into a jerry value */
jerry_object_t *func_obj_p = jerry_create_external_function (get_msg_handler);
jerry_value_t object_value = jerry_create_object_value (func_obj_p);
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_set_object_field_value (object_p,
(const jerry_char_t *) "myFunc",
object_value);
jerry_release_value (object_value);
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 */
object_value = jerry_create_object_value (object_p);
jerry_object_t *global_obj_p = jerry_get_global ();
jerry_value_t global_object = jerry_get_global_object ();
/* Add the JS object to the global context */
jerry_set_object_field_value (global_obj_p,
(const jerry_char_t *) "MyObject",
object_value);
jerry_release_value (object_value);
jerry_release_object (global_obj_p);
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()
*
@@ -425,14 +378,8 @@ main (int argc, char * argv[])
";
size_t script_size = strlen ((const char *) script);
jerry_value_t eval_ret;
/* Evaluate script */
status = jerry_eval (script,
script_size,
false,
false,
&eval_ret);
jerry_value_t eval_ret = jerry_eval (script, script_size, false);
/* Free JavaScript value, returned by eval */
jerry_release_value (eval_ret);
@@ -440,7 +387,7 @@ main (int argc, char * argv[])
/* Cleanup engine */
jerry_cleanup ();
return (int) status;
return 0;
}
```
@@ -456,48 +403,46 @@ Here we create a JS Object with `jerry_eval`, then extend it with a native funct
```c
#include <string.h>
#include "jerry.h"
#include "jerry-api.h"
/**
* Add param to 'this.x'
*/
static bool
add_handler (const jerry_object_t *function_obj_p, /**< function object */
const jerry_value_t this_p, /**< this arg */
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 */
jerry_value_t *ret_val_p) /**< [out] return argument */
const jerry_length_t args_cnt) /**< number of function arguments */
{
/* Get 'this.x' */
jerry_value_t x_val = jerry_get_object_field_value (jerry_get_object_value (this_p),
(const jerry_char_t *) "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_is_error (x_val))
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_value (x + d);
jerry_value_t res_val = jerry_create_number (x + d);
/* Set the new value of 'this.x' */
jerry_set_object_field_value (jerry_get_object_value (this_p),
(const jerry_char_t *) "x",
res_val);
jerry_set_property (this_val, prop_name, res_val);
jerry_release_value (res_val);
}
return true;
jerry_release_value (x_val);
jerry_release_value (prop_name);
return jerry_create_undefined ();
} /* add_handler */
int
main (int argc, char * argv[])
{
jerry_completion_code_t status = JERRY_COMPLETION_CODE_OK;
/* Initialize engine */
jerry_init (JERRY_FLAG_EMPTY);
jerry_init (JERRY_INIT_EMPTY);
/* Create a JS object */
const jerry_char_t my_js_object[] = " \
@@ -514,23 +459,18 @@ main (int argc, char * argv[])
jerry_value_t my_js_obj_val;
/* Evaluate script */
status = jerry_eval (my_js_object,
strlen ((const char *) my_js_object),
false,
false,
&my_js_obj_val);
jerry_object_t *object_p = jerry_get_object_value (my_js_obj_val);
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_object_t *add_func_obj_p = jerry_create_external_function (add_handler);
jerry_value_t object_value = jerry_create_object_value (add_func_obj_p);
jerry_value_t add_func_obj = jerry_create_external_function (add_handler);
/* Set the native function as a property of previously created MyObject */
jerry_set_object_field_value (object_p,
(const jerry_char_t *) "add2x",
object_value);
jerry_release_value (object_value);
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);
@@ -543,14 +483,8 @@ main (int argc, char * argv[])
";
size_t script_size = strlen ((const char *) script);
jerry_value_t eval_ret;
/* Evaluate script */
status = jerry_eval (script,
script_size,
false,
false,
&eval_ret);
jerry_value_t eval_ret = jerry_eval (script, script_size, false);
/* Free JavaScript value, returned by eval */
jerry_release_value (eval_ret);
@@ -558,7 +492,7 @@ main (int argc, char * argv[])
/* Cleanup engine */
jerry_cleanup ();
return (int) status;
return 0;
}
```