Update the webpage (#1421)
* Re-generate the files with `tools/update-webpage.sh` * Add the document about reference counting * Introduce a drop down list for documents JerryScript-DCO-1.0-Signed-off-by: Zsolt Borbély zsborbely.u-szeged@partner.samsung.com
This commit is contained in:
@@ -67,13 +67,13 @@ The default libc is jerry-libc, but you can use compiler-default libc or an exte
|
|||||||
- compiler-default libc:
|
- compiler-default libc:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python tools/build.py --jerry-libc=off --compiler-default-libc=on
|
python tools/build.py --jerry-libc=off
|
||||||
```
|
```
|
||||||
|
|
||||||
- external libc:
|
- external libc:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python tools/build.py --jerry-libc=off --compiler-default-libc=off --compile-flag="-I/path/to/libc/include"
|
python tools/build.py --jerry-libc=off --compile-flag="-nostdlib -I/path/to/ext-libc/include" --link-lib="-lext-c"
|
||||||
```
|
```
|
||||||
|
|
||||||
**Add toolchain file**
|
**Add toolchain file**
|
||||||
|
|||||||
+1
-1
@@ -521,4 +521,4 @@ Value of x is 17
|
|||||||
|
|
||||||
## Further steps
|
## Further steps
|
||||||
|
|
||||||
For further API description, please visit [API Reference page]({{ site.github.url }}/api-reference/) on [JerryScript home page]({{ site.github.url }}/).
|
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/).
|
||||||
|
|||||||
+1
-1
@@ -246,7 +246,7 @@ simple value is a pre-defined constant which can be:
|
|||||||
|
|
||||||
Compressed pointers were introduced to save heap space.
|
Compressed pointers were introduced to save heap space.
|
||||||
|
|
||||||
{: class="thumbnail center-block img-responsive" }
|
{: class="thumbnail center-block img-responsive" }
|
||||||
|
|
||||||
These pointers are 8 byte aligned 16 bit long pointers which can address 512 Kb of
|
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 which is also the maximum size of the JerryScript heap. To support even more
|
||||||
|
|||||||
@@ -0,0 +1,183 @@
|
|||||||
|
---
|
||||||
|
layout: page
|
||||||
|
title: Reference counting
|
||||||
|
permalink: /reference-counting/
|
||||||
|
---
|
||||||
|
|
||||||
|
* toc
|
||||||
|
{:toc}
|
||||||
|
|
||||||
|
## Reference counting in JerryScript
|
||||||
|
|
||||||
|
In JerryScript all `jerry_value_t` values are independent
|
||||||
|
references to internal objects. Values returned by JerryScript
|
||||||
|
API functions are always live references and must be released
|
||||||
|
by `jerry_release_value`.
|
||||||
|
|
||||||
|
```c
|
||||||
|
jerry_value_t global = jerry_get_global_object ();
|
||||||
|
|
||||||
|
/* The value stored in the 'global' variable contains a live
|
||||||
|
* reference to the global object. The system also keeps its
|
||||||
|
* own live reference to the global object. These two references
|
||||||
|
* are indepent, and both must be destroyed before the global
|
||||||
|
* object can be freed. */
|
||||||
|
|
||||||
|
jerry_release_value (global);
|
||||||
|
|
||||||
|
/* Without jerry_release_value() the global object will not
|
||||||
|
* be freed even by jerry_cleanup(). After the reference
|
||||||
|
* is released it becomes a dead reference and cannot be
|
||||||
|
* used anymore. */
|
||||||
|
```
|
||||||
|
|
||||||
|
Multiple references might refer to the same internal object
|
||||||
|
even though their `jerry_value_t` representation might be different.
|
||||||
|
|
||||||
|
```c
|
||||||
|
jerry_value_t pi_ref1 = jerry_create_number (3.14);
|
||||||
|
jerry_value_t pi_ref2 = jerry_acquire_value (pi_ref1);
|
||||||
|
|
||||||
|
/* Both pi_ref1 and pi_ref2 refer to the same 3.14 value
|
||||||
|
* although they might not be equal in C (pi_ref1 != pi_ref2). */
|
||||||
|
|
||||||
|
/* Both references must be released. */
|
||||||
|
jerry_release_value (pi_ref1);
|
||||||
|
jerry_release_value (pi_ref2);
|
||||||
|
```
|
||||||
|
|
||||||
|
Releasing the same `jerry_value_t` twice to release two live
|
||||||
|
references is not allowed and it might cause crashes. Hence the
|
||||||
|
following code is an **INCORRECT WAY** of releasing the 3.14 value.
|
||||||
|
|
||||||
|
```c
|
||||||
|
jerry_release_value (pi_ref1);
|
||||||
|
jerry_release_value (pi_ref1);
|
||||||
|
```
|
||||||
|
|
||||||
|
JerryScript API functions returning with a `jerry_value_t` always
|
||||||
|
return with a new live reference. Passing a `jerry_value_t` to
|
||||||
|
an API function never releases its reference. The next example
|
||||||
|
shows this behaviour through property getting and setting.
|
||||||
|
|
||||||
|
```c
|
||||||
|
jerry_value_t prop_value = jerry_get_property (...);
|
||||||
|
|
||||||
|
/* The prop_value must be released later because both the base
|
||||||
|
* object and the prop_value have an independent reference to
|
||||||
|
* the same JavaScript value. When the operation is failed
|
||||||
|
* the prop_value contains a live reference to an error object.
|
||||||
|
* This reference must be released as well. */
|
||||||
|
|
||||||
|
if (jerry_value_has_error_flag (prop_value))
|
||||||
|
{
|
||||||
|
/* Errors can be handled here. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The application has a live reference to the property
|
||||||
|
* value even if the base object is freed by the garbage
|
||||||
|
* collector. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The prop_value must be released. */
|
||||||
|
jerry_release_value (prop_value);
|
||||||
|
|
||||||
|
/* Property setting is the same. */
|
||||||
|
|
||||||
|
jerry_value_t result = jerry_set_property (..., new_prop_value);
|
||||||
|
|
||||||
|
/* If the property set is successful a new reference is created
|
||||||
|
* for the value referenced by new_prop_value. The new_prop_value
|
||||||
|
* reference must be released regardless the operation is
|
||||||
|
* successful. */
|
||||||
|
|
||||||
|
/* The new_prop_value can be passed to other JerryScript API
|
||||||
|
* functions before the jerry_release_value () call. */
|
||||||
|
|
||||||
|
jerry_release_value (new_prop_value);
|
||||||
|
|
||||||
|
/* The reference stored in 'result' variable contains whether
|
||||||
|
* the operation is successful and must also be freed. */
|
||||||
|
|
||||||
|
if (jerry_value_has_error_flag (result))
|
||||||
|
{
|
||||||
|
/* Errors can be handled here. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* A reference to a true primitive value is returned. */
|
||||||
|
}
|
||||||
|
|
||||||
|
jerry_release_value (result);
|
||||||
|
```
|
||||||
|
|
||||||
|
The simplest form of setting a property without error checking
|
||||||
|
is the following:
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* There are no 'ifs' in this snippet. */
|
||||||
|
jerry_release_value (jerry_set_property (..., new_prop_value));
|
||||||
|
jerry_release_value (new_prop_value);
|
||||||
|
```
|
||||||
|
|
||||||
|
The reference returned by a `jerry_external_handler_t` callback
|
||||||
|
transfers the ownership of the live reference. Otherwise the
|
||||||
|
referenced object could be freed by the garbage collector.
|
||||||
|
|
||||||
|
```c
|
||||||
|
jerry_value_t my_external_handler (const jerry_value_t function_obj,
|
||||||
|
const jerry_value_t this_val,
|
||||||
|
const jerry_value_t args_p[],
|
||||||
|
const jerry_length_t args_count
|
||||||
|
{
|
||||||
|
/* Do not release function_obj, this_val, and args_p because
|
||||||
|
* these references are automatically released after the handler
|
||||||
|
* is returned. This approach reduces code size which is useful
|
||||||
|
* on embedded systems. However you can create other references
|
||||||
|
* to them by calling jerry_acquire_value () if needed. */
|
||||||
|
|
||||||
|
/* Since the ownership of the reference is transferred to the
|
||||||
|
* caller the following snippet is valid. */
|
||||||
|
|
||||||
|
/* If the value to be returned is needed for other purposes the
|
||||||
|
* jerry_acquire_value () can be used to create new references. */
|
||||||
|
return jerry_create_string (...);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Duplicating a `jerry_value_t` in C does not create another live reference.
|
||||||
|
|
||||||
|
```c
|
||||||
|
jerry_value_t undef = jerry_create_undefined ();
|
||||||
|
jerry_value_t undef2 = undef;
|
||||||
|
|
||||||
|
/* Releasing either undef or undef2 is valid but not both.
|
||||||
|
* After the release both references become dead (invalid). */
|
||||||
|
jerry_release_value (undef2);
|
||||||
|
|
||||||
|
/* Dead references can be reassigned again. */
|
||||||
|
undef = jerry_create_boolean (true);
|
||||||
|
```
|
||||||
|
|
||||||
|
References can be duplicated in C as long as only one of them is freed.
|
||||||
|
|
||||||
|
```c
|
||||||
|
jerry_value_t a = jerry_create_boolean (true);
|
||||||
|
|
||||||
|
jerry_value_t b = a;
|
||||||
|
jerry_value_t c = a;
|
||||||
|
|
||||||
|
/* A new reference is assigned to 'a'. */
|
||||||
|
a = jerry_create_boolean (false);
|
||||||
|
|
||||||
|
[...]
|
||||||
|
|
||||||
|
jerry_release_value (a);
|
||||||
|
/* The 'a' (boolean false) reference becomes dead (invalid). */
|
||||||
|
|
||||||
|
jerry_release_value (c);
|
||||||
|
/* Both 'b' and 'c' (boolean true) references become dead. */
|
||||||
|
|
||||||
|
/* Since all references are released no memory leak is possible. */
|
||||||
|
```
|
||||||
@@ -22,13 +22,26 @@
|
|||||||
<ul class="nav navbar-nav navbar-right">
|
<ul class="nav navbar-nav navbar-right">
|
||||||
{% for p in site.pages %}
|
{% for p in site.pages %}
|
||||||
{% if p.title %}
|
{% if p.title %}
|
||||||
|
{% if p.url != "/internals/" and p.url != "/port-api/" and p.url != "/reference-counting/" %}
|
||||||
{% if page.url == p.url %}
|
{% if page.url == p.url %}
|
||||||
<li class="active"><a href="{{ p.url | prepend: site.github.url }}" >{{ p.title }}</a></li>
|
<li class="active"><a href="{{ p.url | prepend: site.github.url }}" >{{ p.title }}</a></li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li><a href="{{ p.url | prepend: site.github.url }}" >{{ p.title }}</a></li>
|
<li><a href="{{ p.url | prepend: site.github.url }}" >{{ p.title }}</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
<li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Documents <span class="caret"></span></a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
{% for p in site.pages %}
|
||||||
|
{% if p.title %}
|
||||||
|
{% if p.url == "/internals/" or p.url == "/port-api/" or p.url == "/reference-counting/" %}
|
||||||
|
<li><a href="{{ p.url | prepend: site.github.url }}" >{{ p.title }}</a></li>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div><!--/.nav-collapse -->
|
</div><!--/.nav-collapse -->
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user