Description
TL;DR: print
is not part of the ES standard, JerryScript still supports it unconditionally in the core of the engine. Shall we keep it there or not?
JerryScript - or, the jerry-core library - aims to be a complete ES5.1 engine, but as small as possible. (Plus, ES2015 features start getting implemented, but that's a long road ahead. And I hope that resource awareness will be kept in mind during those implementation works, too.) The implementation follows the standard quite strictly (minus the unintentional bugs, of course), except for one built-in function: the global object's print
method, which is not mentioned anywhere in the standard.
Of course, having print
available is really useful for testing the engine. E.g., the command line tool jerry
, which is built around the library both as a testing tool and as an example for other embedders, would not be of big use if no output would be observable. print("Hello JerryScript!");
is really something that can be expected to work.
Still, the question is, shall the implementation of print
reside in jerry-core? There are two other JS utility functions now, which are also available from the global object in jerry
: assert
and gc
, but they are added as external functions by the tool, not provided by the core engine. So, there is a precedent for having non-standard functions registered from outside. To reformulate the question: is print
different enough from / more important than assert
and gc
that justifies its implementation in the core?
The issue with the JavaScript print
function is linked to another issue: the need for the jerry_port_console
port C function. This port function has only been introduced to ensure that the implementation of the print
built-in was not tied to the printf
libc function. But, if print
is not provided by the core engine then the ports don't have to provide the jerry_port_console
either (i.e., we can make the port API a bit leaner).
I've investigated the use cases of JS assert
(as an example) and JS print
(as the topic of this issue), and the implementation of C jerry_port_console
(because it is closely related to print
) in the default command line tool and in all targets found in the repository + in the external IoT.js project. (I've started writing all this up a while ago and gc
is a somewhat recent addition, so I've not compiled data on that.) The following table summarizes the findings:
availability of JS assert |
availability of JS print |
use of print and jerry_port_console |
|
---|---|---|---|
main-unix | external C (calls jerry_port_log , exit ) |
builtin + links default jerry_port_console |
C calls jerry_port_console directly & C calls JS print |
esp8266 | external C (calls printf , exit ) |
external C (calls printf ) & builtin + links default jerry_port_console |
JS examples call JS print |
mbed | external C (calls printf , exit ) |
builtin + implements jerry_port_console (calls vfprintf ) |
JS examples call JS print |
mbedos5 | external C (throws JS error) | builtin + implements jerry_port_console (calls vfprintf , printf ) |
JS examples call JS print |
curie_bsp | none | builtin + implements jerry_port_console (calls vsnprintf , printk ) |
C calls jerry_port_console directly & C calls JS print |
zephyr | none | builtin + implements jerry_port_console (calls vfprintf ) |
README example calls JS print & C calls JS print |
nuttx-stm32f4 | external C (calls jerry_port_log , exit ) |
builtin + implements jerry_port_console (calls vfprintf ) |
C calls jerry_port_console directly |
particle | none | builtin + links default jerry_port_console (should implement? Serial.println ) |
none |
riot-stm32f4 | none | builtin + links default jerry_port_console |
hardcoded JS script calls JS print |
iot.js | pure JS (throws JS error) | builtin + links default jerry_port_console & external C for JS console.log (calls fprintf ) |
none |
Summary:
- 5 targets (esp8266, curie_bsp, zephyr, particle, riot-stm32f4) don't implement
assert
at all. - 5 targets (mbed, mbedos5, curie_bsp, zephyr, nuttx-stm32f4) implement their own
jerry_port_console
. - esp8266 has the default
print
withjerry_port_console
implementation in its code base but then redefinesprint
with an external function. - iot.js has
print
andconsole.log
both, but should not exposeprint
IMHO. (It has no choice, however.) - particle uses the default port's
jerry_port_console
implementation but it is unclear whether that's OK (or it should have its own implementation based onSerial.println
). - 3 targets (main-unix, curie_bsp, zephyr) call the JS
print
function from the C code via the JerryScript API. - Several targets call
print
from JS example code, README descriptions, etc.
Moreover, JS print
is used all over in debugger tests (tests/debugger), in some conformance tests (tests/jerry-test-suite/es2015), and in some regression tests (tests/jerry). Thus, if print
is unavailable, testing cannot be performed on a target/port.
So, it seems that print
has infiltrated most of the platforms and most of the use cases. But! Note that assert
would also be needed for all tests to run, so would be gc
now. So, if it is "only" about testing, then we are already facing problems in several targets as these JS functions are unavailable.
If we drop the print
built-in, it has pros and cons (as I see it):
Pros:
- Only standard built-ins in jerry-core.
- Smaller jerry-core code base.
- Smaller port API.
Cons:
- Heavy refactoring needed (e.g., provide replacements for C
jerry_port_console
or JSprint
where directly used from C code). - All targets must provide their own external C implementation for JS
print
(if they really need it).
Ultimate question: what does the community think?