@CesantaHQ
Name | Application | Technology |
---|---|---|
SpiderMonkey | Firefox browser | C/C++ |
V8 | Chrome browser | C/C++ |
Rhino | Firefox browser | Java |
Ducktape | embeddable | C/C++ |
V7 | embeddable | C/C++ |
(*) More complete list of engines at Wikipedia
JavaScript Engine
JS standard
library
Host program
Host Program API
JavaScript Application
JavaScript Engine
Object, Function, Date, String, Regex,
Browser (C/C++)
JavaScript Application
Error, Array, Math, eval(), parseInt(), ...
DOM API
STDLIB API
Document, Window, Event, Node, Element, URL, ...
WebSocket, document, window, location, ...
JavaScript Engine (V7, Rhino, ...)
Object, Function, Date, String, Regex,
Browser (C/C++)
document.write('hello world')
Error, Array, Math, eval(), parseInt(), ...
DOM API
STDLIB API
Document, Window, Event, Node, Element, URL, ...
document, window, location, ...
JavaScript Engine (V8)
Object, Function, Date, String, Regex,
node process
fs = require('fs'); fs.readFile('/etc/hosts', 'utf8', function (err,data) {
console.log(arguments);
});
Error, Array, Math, eval(), parseInt(), ...
Node.js API
STDLIB API
process, net, console, fs, http, os, ...
JavaScript Engine (V7)
Object, Function, Date, String, Regex,
Low-level SDK
GPIO.setmode(pin, 0, 0);
GPIO.write(pin, !level);
Error, Array, Math, eval(), parseInt(), ...
Smart.js API
STDLIB API
File, Websocket, Http, GPIO, I2C,
Documentation is at https://cesanta.com/developer/smartjs
Node.js (*)
ESP8266
Smart.js
180k
<1k
512k
Flash
RAM
RAM
Flash
Disk
RAM
50k
11M
7.6M
// Double-precision floating-point number, IEEE 754
//
// 64 bit (8 bytes) in total
// 1 bit sign
// 11 bits exponent
// 52 bits mantissa
//
// 7 6 5 4 3 2 1 0
// seeeeeee|eeeemmmm|mmmmmmmm|mmmmmmmm|mmmmmmmm|mmmmmmmm|mmmmmmmm|mmmmmmmm
//
// 11111111|11110000|00000000|00000000|00000000|00000000|00000000|00000001 NaN
// V7 NaN-packing:
// sign and exponent is 0xffff
// 4 bits specify type
// 48 bits specify value
//
// 11111111|1111xxxx|00000000|00000000|00000000|00000000|00000000|00000000 NaN
// NaN marker |type| 48-bit placeholder for values: pointers, strings
//
typedef uint64_t v7_val_t;
#define V7_TAG_BOOLEAN ((uint64_t) 0xFFFC << 48)
#define V7_TAG_FUNCTION ((uint64_t) 0xFFF5 << 48) /* JavaScript function */
#define V7_TAG_OBJECT ((uint64_t) 0xFFFF << 48) /* JavaScript object */
#define V7_TAG_REGEXP ((uint64_t) 0xFFF2 << 48) /* RegExp */
var x = 1 + (2 + (3 + (4 + (5 + (6 + (7))))));
var x = 1 + (2 + (3 + (4 + (5 + (6 + (7))))));
(lldb) bt
* thread #1: tid = 0x59fbd, 0x00000001000312c7 v7`get_tok [inlined] parse_number(s=<unavailable>, end=0x0000000100801560, num=0x00000001008015b0) at v7.c:3306, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x00000001000312c7 v7`get_tok [inlined] parse_number(s=<unavailable>, end=0x0000000100801560, num=0x00000001008015b0) at v7.c:3306
frame #1: 0x00000001000312c7 v7`get_tok(s=0x0000000100801560, n=0x00000001008015b0, prev_tok=<unavailable>) + 695 at v7.c:3470
frame #2: 0x000000010000a440 v7`parse_prefix [inlined] next_tok + 100 at v7.c:7485
frame #3: 0x000000010000a3dc v7`parse_prefix(v7=0x0000000100801200, a=0x0000000100200100) + 1068 at v7.c:7745
frame #4: 0x0000000100031ded v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=11, pos=63) + 45 at v7.c:7812
frame #5: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=10, pos=63) + 73 at v7.c:7814
frame #6: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=9, pos=63) + 73 at v7.c:7814
frame #7: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=8, pos=63) + 73 at v7.c:7814
frame #8: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=7, pos=63) + 73 at v7.c:7814
frame #9: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=6, pos=63) + 73 at v7.c:7814
frame #10: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=5, pos=63) + 73 at v7.c:7814
frame #11: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=4, pos=63) + 73 at v7.c:7814
frame #12: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=3, pos=63) + 73 at v7.c:7814
frame #13: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=2, pos=63) + 73 at v7.c:7814
frame #14: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=1, pos=63) + 73 at v7.c:7814
frame #15: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=0, pos=63) + 73 at v7.c:7814
frame #16: 0x0000000100030f13 v7`parse_var [inlined] parse_assign(v7=0x0000000100801200, a=0x0000000100200100) + 14 at v7.c:7855
frame #17: 0x0000000100030f05 v7`parse_var(v7=0x0000000100801200, a=0x0000000100200100) + 741 at v7.c:7888
frame #18: 0x000000010002e38e v7`parse_statement(v7=0x0000000100801200, a=0x0000000100200100) + 5614 at v7.c:8146
frame #19: 0x000000010002c66b v7`parse_body(v7=0x0000000100801200, a=0x0000000100200100, end=TOK_CLOSE_CURLY) + 571 at v7.c:8223
frame #20: 0x000000010002cc43 v7`parse_funcdecl(v7=0x0000000100801200, a=0x0000000100200100, require_named=<unavailable>, reserved_name=<unavailable>) + 1331 at v7.c:8190
frame #21: 0x00000001000327e5 v7`parse_newexpr(v7=0x0000000100801200, a=0x0000000100200100) + 485 at v7.c:7643
frame #22: 0x000000010000a6a3 v7`parse_prefix [inlined] parse_callexpr(v7=0x0000000100801200, a=0x0000000100200100) + 15 at v7.c:7695
frame #23: 0x000000010000a694 v7`parse_prefix [inlined] parse_postfix(a=0x0000000100200100) + 4 at v7.c:7717
frame #24: 0x000000010000a690 v7`parse_prefix(v7=0x0000000100801200, a=0x0000000100200100) + 1760 at v7.c:7777
frame #25: 0x0000000100031ded v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=11, pos=32) + 45 at v7.c:7812
frame #26: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=10, pos=32) + 73 at v7.c:7814
frame #27: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=9, pos=32) + 73 at v7.c:7814
frame #28: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=8, pos=32) + 73 at v7.c:7814
frame #29: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=7, pos=32) + 73 at v7.c:7814
frame #30: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=6, pos=32) + 73 at v7.c:7814
frame #31: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=5, pos=32) + 73 at v7.c:7814
frame #32: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=4, pos=32) + 73 at v7.c:7814
frame #33: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=3, pos=32) + 73 at v7.c:7814
frame #34: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=2, pos=32) + 73 at v7.c:7814
frame #35: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=1, pos=32) + 73 at v7.c:7814
frame #36: 0x0000000100031e09 v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=0, pos=32) + 73 at v7.c:7814
frame #37: 0x0000000100031f8f v7`parse_binary(v7=0x0000000100801200, a=0x0000000100200100, level=<unavailable>, pos=5) + 463 at v7.c:7842
frame #38: 0x000000010002d153 v7`parse_statement [inlined] parse_assign(v7=0x0000000100801200, a=0x0000000100200100) + 947 at v7.c:7855
frame #39: 0x000000010002d13c v7`parse_statement [inlined] parse_expression(a=0x0000000100200100) + 4 at v7.c:7862
frame #40: 0x000000010002d138 v7`parse_statement(v7=0x0000000100801200, a=0x0000000100200100) + 920 at v7.c:8157
frame #41: 0x000000010002c66b v7`parse_body(v7=0x0000000100801200, a=0x0000000100200100, end=TOK_END_OF_INPUT) + 571 at v7.c:8223
frame #42: 0x0000000100001a74 v7`parse [inlined] parse_script(v7=0x0000000100801200, a=0x0000000100200100) + 398 at v7.c:8249
frame #43: 0x00000001000018e6 v7`parse(verbose=<unavailable>, v7=<unavailable>, a=<unavailable>, src=<unavailable>) + 230 at v7.c:8275
frame #44: 0x000000010000bacd v7`v7_exec_with(v7=0x0000000100801200, res=0x00007fff5fbfefb0, src=0x0000000100035710, w=18445899648779419648) + 285 at v7.c:9909
frame #45: 0x0000000100009891 v7`init_stdlib [inlined] v7_exec(res=0x0000000000000366, src=<unavailable>) + 15745 at v7.c:9931
frame #46: 0x000000010000986e v7`init_stdlib [inlined] init_js_stdlib at v7.c:13545
frame #47: 0x000000010000986e v7`init_stdlib(v7=0x0000000100801200) + 15710 at v7.c:13532
frame #48: 0x00000001000017da v7`v7_create + 426 at v7.c:7022
frame #49: 0x0000000100012ec9 v7`v7_main(argc=3, argv=0x00007fff5fbff920, init_func=0x0000000000000000) + 57 at v7.c:12156
frame #50: 0x000000010001346b v7`main(argc=<unavailable>, argv=<unavailable>) + 11 at v7.c:12221
frame #51: 0x00007fff908615fd libdyld.dylib`start + 1
Ending up with C call stack like this:
co = coroutine.create(function(n)
for i = 1, n do
coroutine.yield(i)
end
coroutine.yield(-1)
end)
print(coroutine.resume(co, 3));
print(coroutine.resume(co));
print(coroutine.resume(co));
print(coroutine.resume(co));
$ lua co.lua
true 1
true 2
true 3
true -1
lsm@callisto ~/src/cesanta.com]$ lldb v7/v7
(lldb) target create "v7/v7"
Current executable set to 'v7/v7' (x86_64).
(lldb) b parse_number
Breakpoint 1: 2 locations.
(lldb) process launch -- -e 'var x = 1 + (2 + (3))'
Process 10349 launched: '/Users/lsm/src/cesanta.com/v7/v7' (x86_64)
Process 10349 stopped
* thread #1: tid = 0x5a2b8, 0x000000010000af64 v7`parse_number(s=0x0000000100037604, end=0x00000001008015c8, num=0x0000000100801618) + 20 at tokenizer.c:132, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x000000010000af64 v7`parse_number(s=0x0000000100037604, end=0x00000001008015c8, num=0x0000000100801618) + 20 at tokenizer.c:132
129 }
130
131 static void parse_number(const char *s, const char **end, double *num) {
-> 132 *num = strtod(s, (char **) end);
133 }
134
135 static enum v7_tok parse_str_literal(const char **p) {
(lldb) bt
* thread #1: tid = 0x5a2b8, 0x000000010000af64 v7`parse_number(s=0x0000000100037604, end=0x00000001008015c8, num=0x0000000100801618) + 20 at tokenizer.c:132, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x000000010000af64 v7`parse_number(s=0x0000000100037604, end=0x00000001008015c8, num=0x0000000100801618) + 20 at tokenizer.c:132
frame #1: 0x000000010000a4da v7`get_tok(s=0x00000001008015c8, n=0x0000000100801618, prev_tok=TOK_OPEN_PAREN) + 874 at tokenizer.c:296
frame #2: 0x00000001000194f4 v7`next_tok(v7=0x0000000100801200) + 196 at parser.c:1248
frame #3: 0x000000010001630d v7`parser_cr_exec(p_ctx=0x00007fff5fbfe9d8, v7=0x0000000100801200, a=0x0000000100200160) + 8157 at parser.c:1836
frame #4: 0x000000010001980f v7`parse(v7=0x0000000100801200, a=0x0000000100200160, src=0x0000000100037580, verbose=1, is_json=0) + 415 at parser.c:2454
frame #5: 0x000000010001b454 v7`i_exec(v7=0x0000000100801200, src=0x0000000100037580, src_len=0, res=0x00007fff5fbfed10, w=18445899648779419648, is_json=0, fr=0) + 612 at interpreter.c:1838
frame #6: 0x000000010001d4ad v7`v7_exec(v7=0x0000000100801200, src=0x0000000100037580, res=0x00007fff5fbfed10) + 93 at interpreter.c:1923
frame #7: 0x000000010002302c v7`init_js_stdlib(v7=0x0000000100801200) + 60 at js_stdlib.c:132
frame #8: 0x0000000100022fa6 v7`init_stdlib(v7=0x0000000100801200) + 710 at stdlib.c:199
frame #9: 0x0000000100012440 v7`v7_create_opt(opts=v7_create_opts at 0x00007fff5fbfedb0) + 480 at vm.c:1831
frame #10: 0x000000010003645d v7`v7_main(argc=3, argv=0x00007fff5fbff720, init_func=0x0000000000000000, fini_func=0x0000000000000000) + 1181 at main.c:126
frame #11: 0x0000000100036b92 v7`main(argc=3, argv=0x00
contact me at
sergey.lyubka@cesanta.com