Update Iot.js
[platform/upstream/iotjs.git] / docs / devs / Inside-IoT.js.md
1 Inside IoT.js
2 =============
3
4 * [Design](#design)
5 * [Javascript Binding](#javascript-binding)
6   * iotjs_jval_t
7   * iotjs_jobjectwrap_t
8   * Native handler
9   * Embedding API
10 * [libuv Binding](#libuv-binding)
11   * iotjs_handlewrap_t
12   * iotjs_reqwrap_t
13 * [IoT.js Core](#iotjscoe)
14   * Life cycle of IoT.js
15   * Builtin
16   * Native module
17   * Event loop
18
19 # Design
20
21 IoT.js is built on top of [JerryScript](http://jerryscript.net/) and [libuv](http://libuv.org). JerryScript is a lightweight Javascript engine intended to run on small devices for IoT and libuv is a library for supporting asynchronous I/O. There is a layer that binds JerryScript and libuv to IoT.js.
22 We will deals with the layer in [Javascript Binding](#javascript-binding) and [libuv Binding](#javascript-binding) section on this document respectively.
23
24 IoT.js core layer locates above these binding layer.
25 This core layer plays a central role in this project providing upper layer with fundamental functionality of running main event loop, interacting with Javascript engine, managing I/O resources via libuv, managing life cycle of objects, providing builtin modules, and so forth.
26 [IoT.js Core](#iotjs-core) section deals with the layer in detail.
27
28 IoT.js provides APIs for user applications to help creating IoT friendly services.
29 You can see the list of API from [IoT.js API Reference](../api/IoT.js-API-reference.md).
30
31 # Javascript Binding
32
33 Many modern Javascript Engines come with [embedding API](#embedding-api) to provide functionality for compiling and executing Javascript program, accessing Javascript object and its value, handling errors, managing lifecyles of objects and so on.
34
35 You can think of Javascript binding layer as an interface between upper layer (IoT.js core) and  underlying Javascript engine.
36 Although IoT.js only supports JerryScript for now, there will be a chance that we extend supporting Javascript engine (such as [Duktape](http://duktape.org/) or [V8](https://code.google.com/p/v8/)) in the future.
37 For this reason, we want to keep the layer independent from a specific Javascript engine.
38 You can see interface of the layer in [iotjs_binding.h](../../src/iotjs_binding.h).
39
40 ## iotjs_jval_t
41
42 `iotjs_jval_t` struct stands for a real Javascript object. Upper layers will access Javascript object via this struct.
43 This struct provides following functionalities:
44
45 * Creating a Javascript object using `iotjs_jval_create_*()` constructor.
46 * Creating a Javascript object by a value.
47 * Creating a Javascript function object where its body is implemented in C.
48 * Creating a Javascript Error object.
49 * Creating reference for a Javascript object increasing reference count.
50 * Increasing reference count.
51 * Decreasing reference count.
52 * Checking object type.
53 * Retrieving value.
54 * Calling a Javascript function.
55 * Evaluating a Javascript script.
56 * Set and Get corresponding native data to the Javascript object.
57
58 ## iotjs_jobjectwrap_t
59
60 You can refer Javascript object from C code side using `iotjs_jval_t` as saw above.
61 When a reference for a Javascript object was made using `iotjs_jval_t`, it will increase the reference count and will decrease the count when it goes out of scope.
62
63 ```c
64 {
65   // Create JavaScript object
66   // It increases reference count in JerryScript side.
67   iotjs_jval_t jobject = iotjs_jval_create();
68
69   // Use `jobject`
70   ...
71
72   // Before jobject goes out of scope, destroy it.
73   // It decreases reference count in JerryScript side so that it can be GC-ed.
74   iotjs_jval_destroy(&jobject)
75 }
76 ```
77
78 But the situation is different if you want to refer a Javascript object through out program execution until the object is live.
79 You may write code like this:
80
81 ```c
82   iotjs_jval_t* jobject = (iotjs_jval_t*)malloc(sizeof(iotjs_jval_t)); // Not allowed
83 ```
84
85 Unfortunately, we strongly do not recommend that kind of pattern. We treat pointer-types variables in special way. (See [Validated Struct](Inside-IoT.js-Validated-Struct.md) for more details.)
86
87 To achieve your wish, we recommend using `iotjs_jobjectwrap_t` for that purpose.
88 `iotjs_jobjectwrap_t` is kind of weak pointer to a Javascript Object.
89 It refers a Javascript object but never increase reference count so that Javascript engine can collect the object when it turns into garbage.
90 The `iotjs_jobjectwrap_t` instance will be released at the time the corresponding Javascript object is being reclaimed.
91
92 Do not hold pointer to the wrapper in native code side globally because even if you are holding a wrapper by pointer, Javascript engine probably releases the corresponding Javascript object resulting deallocation of wrapper. Consequentially your pointer will turned into dangling.
93
94 The only safe way to get wrapper is to get it from Javascript object. When a wrapper is being created, it links itself with corresponding Javascript object with `iotjs_jval_set_object_native_handle()` method of `iotjs_jval_t`. And you can get the wrapper from the object with `iotjs_jval_get_object_native_handle()` method of `iotjs_jval_t` later when you need it.
95
96
97 ## Native handler
98
99 Some operations - such as file I/O, networking, device control, multitasking, and etc - can not be performed by pure Javascript.
100 IoT.js uses a mechanism called "native handler" to enable such operations performed from Javascript.
101 You can regard native handler as Javascript function object with its body implemented in C.
102
103 You might think it is somewhat similar to [FFI](https://en.wikipedia.org/wiki/Foreign_function_interface).
104 In a wide sense, it's true for native handler is for calling C function from Javascript.
105 But in a narrow sense, it's not true.
106
107 Usually main purpose of [FFI](https://en.wikipedia.org/wiki/Foreign_function_interface) is to call a routine written in one language from a program written in another.
108 After a routine was invoked, it is common that the routine just do what it is supposed to do without knowing the surrounding context except arguments.
109 Whereas native handler does know that it is being called from Javascript (actually it is a Javascript function although not written in Javascript) and does access surrounding Javascript execution context using [embedding API](#embedding-api).
110
111 ## Embedding API
112
113 Many Javascript engines these days provide embedding API. IoT.js uses the API to create [builtin module](#builtin) and [native handler](#native-handler). See following link if you want further information about the API:
114  * [JerryScript API](http://jerryscript.net/api-reference)
115  * [Duktape API](http://duktape.org/api.html)
116  * [V8 embedder's guide](https://developers.google.com/v8/embed)
117  * [SpiderMonkey API](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference)
118
119 # libuv Binding
120
121 IoT.js is using [libuv](http://libuv.org/) to perform various asynchronous I/O and threading.
122 Because IoT.js adopts asynchronous programming model, libuv plays very important role in this project. Actually the [main loop](#event-loop) of IoT.js is libuv event loop waiting I/O event, picks the event, and dispatches it to corresponding event handler function.
123
124 You can read [libuv design document](http://docs.libuv.org/en/v1.x/design.html) to get detailed information about asynchronous programming model based on libuv.
125
126 ## iotjs_handlewrap_t
127
128 `iotjs_handlewrap_t` is to bind a Javascript object and a libuv handle (e.g. file descriptor) together.
129 `iotjs_handlewrap_t` inherits `iotjs_jobjectwrap_t` since it is linked with a Javascript object.
130
131 Unlike `iotjs_jobjectwrap_t`, `iotjs_jobjectwrap_t` increases RC for the Javascript object when an instance of it is created to prevent GC while the handle is alive. The reference counter will be decreased after the handle is closed, allowing GC.
132
133 ## iotjs_reqwrap_t
134
135 `iotjs_reqwrap_t` is for wrapping libuv request data and Javascript callback function. And make sure that the Javascript callback function is alive during the I/O operation.
136
137 Let's look at how asynchronous I/O are treated in IoT.js:
138
139 1. Javascript module calls builtin function to perform I/O applying arguments including callback.
140 2. Builtin creates `iotjs_reqwrap_t` to wrap `uv_req_s` and Javascript callback function.
141 3. Builtin calls libuv to perform the I/O.
142 4. After I/O finished, libuv calls builtin after handler.
143 5. Builtin after handler takes `iotjs_reqwrap_t` containing I/O result and Javascript callback function.
144 6. Builtin after handler calls Javascript callback.
145 7. Builtin after handler release `iotjs_reqwrap_t` by calling `iotjs_*reqwrap_dispatch()`
146
147 `iotjs_reqwrap_t` does not inherits `iotjs_handlewrap_t` for wrapping the callback function object.
148 Note that `HandleWrap` does not increase reference count of wrapping object. It does not guarantee guarantee liveness of the object even if the wrapper is alive.
149
150 On the other hand, `iotjs_reqwrap_t` increases the reference count for the callback function and decreases when it is being freed to guarantee the liveness of callback function during the request is ongoing.
151 After request is finished and `iotjs_reqwrap_t` released by calling `iotjs_*reqwrap_dispatch()`, the callback function could be collected by GC when it need to be.
152
153 # IoT.js Core
154
155 ## Life cycle of IoT.js
156
157 _Note:_
158 _We are currently focusing on implementing IoT.js upon JerryScript engine._
159 _Implementation of initializing process depends on JerryScript API._
160 _That could be changed when we adopt other Javascript engines._
161 _Anyway, in this chapter we will explain initialization process based on current implementation._
162
163 The process of IoT.js can be summarized as follow:
164
165 1. Initialize JerryScript engine.
166 2. Execute empty script
167  * Create initial Javascript context.
168 3. Initialize builtin modules.
169  * Create builin modules including ['process'](../api/IoT.js-API-Process.md).
170 4. Evaluate ['iotjs.js'](../../src/js/iotjs.js).
171  * Generate entry function.
172 5. Run the entry function passing 'process'.
173  1. Initialize 'process' module.
174  2. Load user application script.
175  3. Run user application.
176 6. Run [event loop](#event-loop) until there are no more events to be handled.
177 7. Clean up.
178
179 ## Builtin
180
181 "Builtin" is Javascript objects fully implemented in C using [embedding API](#embedding-api).
182 The list of builtin objects can be found at `MAP_MODULE_LIST` macro in ['iotjs_module.h'](../../src/iotjs_module.h).
183
184 Because methods of builtin modules are implemented as [native handler](#native-handler),
185 are able to access underlying system using libuv, C library, and system call.
186 Also, builtin modules could be used for optimizing performance of CPU bound routine or reduce binary size.
187
188 Builtin modules are initialized during [intializing step of IoT.js](#life-cycle-of-iotjs) and released just before program terminates.
189
190 ## Native module
191
192 The [basic modules and extended modules](../api/IoT.js-API-reference.md) provided by IoT.js are called 'native module' because it will be included IoT.js as binary format.(not as script).
193 There is a [tool](../../tools/js2c.py) that transfer Javascript script source file into C file.
194
195 Usually a native module needs help from couple of [builtin](#builtin) modules which are implemented in C thus able to access underlying system.
196
197 Some native modules are bound to global object while others are on demand.
198 On demand modules will be created at the moment when it is first required and will not released until the program terminates.
199
200 ## Event loop
201
202 _Note:_
203 _It would be helpful to read [libuv design overview](http://docs.libuv.org/en/v1.x/design.html) to understand asynchronous I/O programming model if you are not familiar with it._
204
205 _Note:_
206 _In this section we will see simple file open example and relevant code segment. You can find the source files at ['iotjs.c'](../../src/iotjs.c), [`iotjs_module_fs.c`](../../src/module/iotjs_module_fs.c) and ['fs.js'](../../src/js/fs.js)_
207
208
209 IoT.js follows asynchronous I/O programming model proposed by libuv to perform non-blocking, single-threaded, asynchronous I/O.
210
211 You can find main loop of the program at the file ['iotjs.c'](../../src/iotjs.c) in the source tree. It looks like this:
212
213 ```c
214   // Run event loop.
215   bool more;
216   do {
217     more = uv_run(iotjs_environment_loop(env), UV_RUN_ONCE);
218     more |= iotjs_process_next_tick();
219     if (more == false) {
220       more = uv_loop_alive(iotjs_environment_loop(env));
221     }
222   } while (more);
223 ```
224
225 While running a IoT.js application, it could make requests for I/O operations using [IoT.js API](../api/IoT.js-API-reference.md).
226 For example, You can write a code for opening 'hello.txt' file and printing file descriptor out like this:
227 ```js
228 fs.open('hello.txt', 'r', function(err, fd) {
229   console.log('fd:' + fd);
230 });
231 conosle.log('requested');
232 ```
233
234 To handle the request, IoT.js will wrapping the request and callback function using `iotjs_reqwrap_t`.
235 ```c
236   iotjs_fsreqwrap_t* req_wrap = iotjs_fsreqwrap_create(jcallback);
237 ```
238
239 libuv will take charge of actual I/O processing taking the request.
240 ```c
241   uv_fs_t* fs_req = iotjs_fsreqwrap_req(req_wrap);
242   int err = uv_fs_open(iotjs_environment_loop(env),
243                        fs_req,
244                        path, flags, mode,
245                        AfterAsync);
246 ```
247
248 Since all I/O are treated as non-blocking, calling for async I/O API returns immediately right after request was sent to libuv.
249 And then next line of javascript program will be executed immediately without waiting the I/O.
250 Thus in the above example 'requested' will be printed out right after file open request was made.
251
252 If there were I/O requests, `uv_run()` in the main loop waits by polling the requests until at least one of the request processing were finished.
253 When a result for a request was produced, internal part of libuv calls corresponding handler function (let it be after function) back.
254
255 Usually, the after function retrieves I/O result and `iotjs_reqwrap_t` object from request data.
256 And calling the javascript callback function with the result.
257
258 ```c
259   iotjs_fsreqwrap_t* req_wrap = (iotjs_fsreqwrap_t*)(req->data); // get request wrapper
260   const iotjs_jval_t* cb = iotjs_fsreqwrap_jcallback(req_wrap); // javascript callback function
261
262   iotjs_jargs_t jarg = iotjs_jargs_create(2);
263   iotjs_jargs_append_null(&jarg); // in case of success.
264   iotjs_jargs_append_number(req->result); // result - file descriptor for open syscall
265
266   // callback
267   iotjs_jhelper_make_callback(cb, iotjs_jval_get_null(), &jarg);
268
269   // cleanup
270   iotjs_jargs_destroy(&jarg);
271   iotjs_fsreqwrap_dispatched(req_wrap);
272 ```
273
274 For above file open example, calling javascript callback function would result execution of the handler.
275 ```js
276 function(err, fd) {
277   console.log('fd:' + fd);
278 }
279 ```
280
281 One iteration of event loop is finished and `uv_run()` finally returns after all results were handled.
282 Next, it calls next tick handler.
283 ```c
284     more |= iotjs_process_next_tick();
285 ```
286 And for next step, main event loop checks if there were no more request to be treated.
287 ```c
288     if (more == false) {
289       more = uv_loop_alive(iotjs_environment_loop(env));
290     }
291 ```
292 If there are another iteration of the loop executed. Otherwise, main event loop ends.