Upload packaging folder
[platform/upstream/iotjs.git] / src / iotjs.c
1 /* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include "iotjs_def.h"
17
18 #include "iotjs.h"
19 #include "iotjs_handlewrap.h"
20 #include "iotjs_js.h"
21 #include "iotjs_string_ext.h"
22
23 #include "jerry-port-default.h"
24 #include "jerry-port.h"
25 #include "jerryscript.h"
26
27 #include <stdio.h>
28 #include <string.h>
29
30
31 /**
32  * Initialize JerryScript.
33  */
34 static bool iotjs_jerry_initialize(const iotjs_environment_t* env) {
35   // Set jerry run flags.
36   uint32_t jerry_flag = JERRY_INIT_EMPTY;
37
38   if (iotjs_environment_config(env)->memstat) {
39     jerry_flag |= JERRY_INIT_MEM_STATS;
40     jerry_port_default_set_log_level(JERRY_LOG_LEVEL_DEBUG);
41   }
42
43   if (iotjs_environment_config(env)->show_opcode) {
44     jerry_flag |= JERRY_INIT_SHOW_OPCODES;
45     jerry_port_default_set_log_level(JERRY_LOG_LEVEL_DEBUG);
46   }
47
48   // Initialize jerry.
49   jerry_init((jerry_init_flag_t)jerry_flag);
50
51   // Set magic strings.
52   iotjs_register_jerry_magic_string();
53
54   // Do parse and run to generate initial javascript environment.
55   jerry_value_t parsed_code = jerry_parse((jerry_char_t*)"", 0, false);
56   if (jerry_value_has_error_flag(parsed_code)) {
57     DLOG("jerry_parse() failed");
58     jerry_release_value(parsed_code);
59     return false;
60   }
61
62   jerry_value_t ret_val = jerry_run(parsed_code);
63   if (jerry_value_has_error_flag(ret_val)) {
64     DLOG("jerry_run() failed");
65     jerry_release_value(parsed_code);
66     jerry_release_value(ret_val);
67     return false;
68   }
69
70   jerry_release_value(parsed_code);
71   jerry_release_value(ret_val);
72   return true;
73 }
74
75
76 static void iotjs_jerry_release() {
77   jerry_cleanup();
78 }
79
80
81 static bool iotjs_run(const iotjs_jval_t* process) {
82   // Evaluating 'iotjs.js' returns a function.
83   bool throws;
84 #ifndef ENABLE_SNAPSHOT
85   iotjs_jval_t jmain = iotjs_jhelper_eval(iotjs_s, iotjs_l, false, &throws);
86 #else
87   iotjs_jval_t jmain = iotjs_jhelper_exec_snapshot(iotjs_s, iotjs_l, &throws);
88 #endif
89   IOTJS_ASSERT(!throws);
90
91   // Run the entry function passing process builtin.
92   // The entry function will continue initializing process module, global, and
93   // other native modules, and finally load and run application.
94   iotjs_jargs_t args = iotjs_jargs_create(1);
95   iotjs_jargs_append_jval(&args, process);
96
97   const iotjs_jval_t* global = iotjs_jval_get_global_object();
98   iotjs_jval_t jmain_res = iotjs_jhelper_call(&jmain, global, &args, &throws);
99
100   iotjs_jargs_destroy(&args);
101   iotjs_jval_destroy(&jmain);
102
103   if (throws) {
104     iotjs_uncaught_exception(&jmain_res);
105   }
106   iotjs_jval_destroy(&jmain_res);
107
108   return !throws;
109 }
110
111
112 static bool iotjs_start(iotjs_environment_t* env) {
113   // Initialize commonly used jerry values
114   iotjs_binding_initialize();
115
116   // Bind environment to global object.
117   const iotjs_jval_t* global = iotjs_jval_get_global_object();
118   iotjs_jval_set_object_native_handle(global, (uintptr_t)(env), NULL);
119
120   // Initialize builtin modules.
121   iotjs_module_list_init();
122
123   // Initialize builtin process module.
124   const iotjs_jval_t* process =
125       iotjs_module_initialize_if_necessary(MODULE_PROCESS);
126
127   // Call the entry.
128   // load and call iotjs.js
129   iotjs_environment_go_state_running_main(env);
130
131   iotjs_run(process);
132
133   // Run event loop.
134   iotjs_environment_go_state_running_loop(env);
135
136   bool more;
137   do {
138     more = uv_run(iotjs_environment_loop(env), UV_RUN_ONCE);
139     more |= iotjs_process_next_tick();
140     if (more == false) {
141       more = uv_loop_alive(iotjs_environment_loop(env));
142     }
143   } while (more);
144
145   iotjs_environment_go_state_exiting(env);
146
147   // Emit 'exit' event.
148   iotjs_process_emit_exit(0);
149
150   // Release builtin modules.
151   iotjs_module_list_cleanup();
152
153   // Release commonly used jerry values.
154   iotjs_binding_finalize();
155
156   return true;
157 }
158
159
160 static void iotjs_uv_walk_to_close_callback(uv_handle_t* handle, void* arg) {
161   iotjs_handlewrap_t* handle_wrap = iotjs_handlewrap_from_handle(handle);
162   IOTJS_ASSERT(handle_wrap != NULL);
163
164   iotjs_handlewrap_close(handle_wrap, NULL);
165 }
166
167
168 int iotjs_entry(int argc, char** argv) {
169   // Initialize debug print.
170   init_debug_settings();
171
172   // Create environment.
173   iotjs_environment_t* env = (iotjs_environment_t*)iotjs_environment_get();
174
175   // Parse command line arguments.
176   if (!iotjs_environment_parse_command_line_arguments(env, argc, argv)) {
177     DLOG("iotjs_environment_parse_command_line_arguments failed");
178     return 1;
179   }
180
181   // Set event loop.
182   iotjs_environment_set_loop(env, uv_default_loop());
183
184   // Initialize JerryScript engine.
185   if (!iotjs_jerry_initialize(env)) {
186     DLOG("iotjs_jerry_initialize failed");
187     return 1;
188   }
189
190   // Start IoT.js
191   if (!iotjs_start(env)) {
192     DLOG("iotjs_start failed");
193     return 1;
194   }
195
196   // close uv loop.
197   // uv_stop(iotjs_environment_loop(env));
198   uv_walk(iotjs_environment_loop(env), iotjs_uv_walk_to_close_callback, NULL);
199   uv_run(iotjs_environment_loop(env), UV_RUN_DEFAULT);
200
201   int res = uv_loop_close(iotjs_environment_loop(env));
202   IOTJS_ASSERT(res == 0);
203
204   // Release JerryScript engine.
205   iotjs_jerry_release();
206
207   // Release environment.
208   iotjs_environment_release();
209
210   // Release debug print setting.
211   release_debug_settings();
212
213   return 0;
214 }