|
3 | 3 | #include <sstream> |
4 | 4 | #include <string> |
5 | 5 |
|
| 6 | +#include "ffi/NativeScriptException.h" |
6 | 7 | #include "js_native_api.h" |
7 | 8 | #include "native_api_util.h" |
8 | 9 | #include "runtime/RuntimeConfig.h" |
@@ -85,34 +86,34 @@ std::string buildStringFromArg(napi_env env, napi_value val) { |
85 | 86 | return napi_util::get_string_value(env, funcString); |
86 | 87 | } else if (napi_util::is_array(env, val)) { |
87 | 88 | napi_value cachedSelf = val; |
88 | | - |
| 89 | + |
89 | 90 | // Get array length |
90 | 91 | uint32_t arrayLength; |
91 | 92 | napi_get_array_length(env, val, &arrayLength); |
92 | | - |
| 93 | + |
93 | 94 | std::stringstream arrayStr; |
94 | 95 | arrayStr << "["; |
95 | | - |
| 96 | + |
96 | 97 | for (uint32_t i = 0; i < arrayLength; i++) { |
97 | 98 | napi_value propertyValue; |
98 | 99 | napi_get_element(env, val, i, &propertyValue); |
99 | | - |
| 100 | + |
100 | 101 | // Check for circular reference |
101 | 102 | bool isStrictEqual = false; |
102 | 103 | napi_strict_equals(env, propertyValue, cachedSelf, &isStrictEqual); |
103 | | - |
| 104 | + |
104 | 105 | if (isStrictEqual) { |
105 | 106 | arrayStr << "[Circular]"; |
106 | 107 | } else { |
107 | 108 | std::string elementString = buildStringFromArg(env, propertyValue); |
108 | 109 | arrayStr << elementString; |
109 | 110 | } |
110 | | - |
| 111 | + |
111 | 112 | if (i != arrayLength - 1) { |
112 | 113 | arrayStr << ", "; |
113 | 114 | } |
114 | 115 | } |
115 | | - |
| 116 | + |
116 | 117 | arrayStr << "]"; |
117 | 118 | return arrayStr.str(); |
118 | 119 | } else if (type == napi_object) { |
@@ -152,118 +153,122 @@ std::string buildLogString(napi_env env, napi_callback_info info, |
152 | 153 | } |
153 | 154 |
|
154 | 155 | JS_METHOD(Console::Log) { |
155 | | - if (!RuntimeConfig.LogToSystemConsole) { |
156 | | - return UNDEFINED; |
157 | | - } |
| 156 | + try { |
| 157 | + if (!RuntimeConfig.LogToSystemConsole) { |
| 158 | + return UNDEFINED; |
| 159 | + } |
158 | 160 |
|
159 | | - size_t argc = 0; |
160 | | - ConsoleLogType stream; |
161 | | - void* data = nullptr; |
| 161 | + size_t argc = 0; |
| 162 | + ConsoleLogType stream; |
| 163 | + void* data = nullptr; |
162 | 164 |
|
163 | | - napi_get_cb_info(env, cbinfo, &argc, nullptr, nullptr, &data); |
| 165 | + napi_get_cb_info(env, cbinfo, &argc, nullptr, nullptr, &data); |
164 | 166 |
|
165 | | - stream = ConsoleLogType((unsigned long)data); |
| 167 | + stream = ConsoleLogType((unsigned long)data); |
166 | 168 |
|
167 | | - size_t initialArg = 0; |
| 169 | + size_t initialArg = 0; |
168 | 170 |
|
169 | | - if (stream == kConsoleLogTypeAssert) { |
170 | | - bool passes = false; |
| 171 | + if (stream == kConsoleLogTypeAssert) { |
| 172 | + bool passes = false; |
171 | 173 |
|
172 | | - if (argc > 0) { |
173 | | - napi_value firstArg = nullptr; |
174 | | - napi_get_cb_info(env, cbinfo, &argc, &firstArg, nullptr, nullptr); |
175 | | - napi_coerce_to_bool(env, firstArg, &firstArg); |
176 | | - napi_get_value_bool(env, firstArg, &passes); |
177 | | - } |
| 174 | + if (argc > 0) { |
| 175 | + napi_value firstArg = nullptr; |
| 176 | + napi_get_cb_info(env, cbinfo, &argc, &firstArg, nullptr, nullptr); |
| 177 | + napi_coerce_to_bool(env, firstArg, &firstArg); |
| 178 | + napi_get_value_bool(env, firstArg, &passes); |
| 179 | + } |
178 | 180 |
|
179 | | - if (!passes) { |
180 | | - initialArg = 1; |
181 | | - } else { |
182 | | - return UNDEFINED; |
| 181 | + if (!passes) { |
| 182 | + initialArg = 1; |
| 183 | + } else { |
| 184 | + return UNDEFINED; |
| 185 | + } |
183 | 186 | } |
184 | | - } |
185 | 187 |
|
186 | | - napi_value argv[argc]; |
187 | | - napi_get_cb_info(env, cbinfo, &argc, argv, nullptr, nullptr); |
188 | | - |
189 | | - napi_value global, Symbol, SymbolFor, symbolDescription, symbol; |
190 | | - napi_get_global(env, &global); |
191 | | - napi_get_named_property(env, global, "Symbol", &Symbol); |
192 | | - napi_get_named_property(env, Symbol, "for", &SymbolFor); |
193 | | - napi_create_string_utf8(env, "nodejs.util.inspect.custom", NAPI_AUTO_LENGTH, |
194 | | - &symbolDescription); |
195 | | - napi_call_function(env, global, SymbolFor, 1, &symbolDescription, &symbol); |
196 | | - |
197 | | - std::stringstream log; |
198 | | - |
199 | | - // TODO(dj): what if we made this pretty? |
200 | | - |
201 | | - log << "CONSOLE"; |
202 | | - switch (stream) { |
203 | | - case kConsoleLogTypeLog: |
204 | | - log << " LOG"; |
205 | | - break; |
206 | | - case kConsoleLogTypeError: |
207 | | - log << " ERROR"; |
208 | | - break; |
209 | | - case kConsoleLogTypeWarn: |
210 | | - log << " WARN"; |
211 | | - break; |
212 | | - case kConsoleLogTypeInfo: |
213 | | - log << " INFO"; |
214 | | - break; |
215 | | - case kConsoleLogTypeAssert: |
216 | | - log << " ASSERT FAILED"; |
217 | | - break; |
218 | | - } |
219 | | - log << ": "; |
| 188 | + napi_value argv[argc]; |
| 189 | + napi_get_cb_info(env, cbinfo, &argc, argv, nullptr, nullptr); |
| 190 | + |
| 191 | + napi_value global, Symbol, SymbolFor, symbolDescription, symbol; |
| 192 | + napi_get_global(env, &global); |
| 193 | + napi_get_named_property(env, global, "Symbol", &Symbol); |
| 194 | + napi_get_named_property(env, Symbol, "for", &SymbolFor); |
| 195 | + napi_create_string_utf8(env, "nodejs.util.inspect.custom", NAPI_AUTO_LENGTH, |
| 196 | + &symbolDescription); |
| 197 | + napi_call_function(env, global, SymbolFor, 1, &symbolDescription, &symbol); |
| 198 | + |
| 199 | + std::stringstream log; |
| 200 | + |
| 201 | + // TODO(dj): what if we made this pretty? |
| 202 | + |
| 203 | + log << "CONSOLE"; |
| 204 | + switch (stream) { |
| 205 | + case kConsoleLogTypeLog: |
| 206 | + log << " LOG"; |
| 207 | + break; |
| 208 | + case kConsoleLogTypeError: |
| 209 | + log << " ERROR"; |
| 210 | + break; |
| 211 | + case kConsoleLogTypeWarn: |
| 212 | + log << " WARN"; |
| 213 | + break; |
| 214 | + case kConsoleLogTypeInfo: |
| 215 | + log << " INFO"; |
| 216 | + break; |
| 217 | + case kConsoleLogTypeAssert: |
| 218 | + log << " ASSERT FAILED"; |
| 219 | + break; |
| 220 | + } |
| 221 | + log << ": "; |
220 | 222 |
|
221 | | - log << buildLogString(env, cbinfo, initialArg); |
| 223 | + log << buildLogString(env, cbinfo, initialArg); |
222 | 224 |
|
223 | | - log << "\n"; |
| 225 | + log << "\n"; |
224 | 226 |
|
225 | | - std::string logString = log.str(); |
| 227 | + std::string logString = log.str(); |
226 | 228 |
|
227 | 229 | #ifdef __APPLE__ |
228 | | - NSLog(CFSTR("%s"), logString.c_str()); |
| 230 | + NSLog(CFSTR("%s"), logString.c_str()); |
229 | 231 | #else |
230 | | - switch (stream) { |
231 | | - case kConsoleLogTypeLog: |
232 | | - case kConsoleLogTypeInfo: |
233 | | - std::cout << logString; |
234 | | - break; |
235 | | - case kConsoleLogTypeError: |
236 | | - case kConsoleLogTypeWarn: |
237 | | - case kConsoleLogTypeAssert: |
238 | | - std::cerr << logString; |
239 | | - break; |
240 | | - } |
| 232 | + switch (stream) { |
| 233 | + case kConsoleLogTypeLog: |
| 234 | + case kConsoleLogTypeInfo: |
| 235 | + std::cout << logString; |
| 236 | + break; |
| 237 | + case kConsoleLogTypeError: |
| 238 | + case kConsoleLogTypeWarn: |
| 239 | + case kConsoleLogTypeAssert: |
| 240 | + std::cerr << logString; |
| 241 | + break; |
| 242 | + } |
241 | 243 | #endif |
242 | 244 |
|
243 | 245 | #ifdef TARGET_ENGINE_V8 |
244 | | - v8_inspector::ConsoleAPIType method; |
245 | | - switch (stream) { |
246 | | - case kConsoleLogTypeLog: |
247 | | - method = v8_inspector::ConsoleAPIType::kLog; |
248 | | - break; |
249 | | - case kConsoleLogTypeError: |
250 | | - method = v8_inspector::ConsoleAPIType::kError; |
251 | | - break; |
252 | | - case kConsoleLogTypeWarn: |
253 | | - method = v8_inspector::ConsoleAPIType::kWarning; |
254 | | - break; |
255 | | - case kConsoleLogTypeInfo: |
256 | | - method = v8_inspector::ConsoleAPIType::kInfo; |
257 | | - break; |
258 | | - case kConsoleLogTypeAssert: |
259 | | - method = v8_inspector::ConsoleAPIType::kAssert; |
260 | | - break; |
261 | | - default: |
262 | | - break; |
263 | | - } |
| 246 | + v8_inspector::ConsoleAPIType method; |
| 247 | + switch (stream) { |
| 248 | + case kConsoleLogTypeLog: |
| 249 | + method = v8_inspector::ConsoleAPIType::kLog; |
| 250 | + break; |
| 251 | + case kConsoleLogTypeError: |
| 252 | + method = v8_inspector::ConsoleAPIType::kError; |
| 253 | + break; |
| 254 | + case kConsoleLogTypeWarn: |
| 255 | + method = v8_inspector::ConsoleAPIType::kWarning; |
| 256 | + break; |
| 257 | + case kConsoleLogTypeInfo: |
| 258 | + method = v8_inspector::ConsoleAPIType::kInfo; |
| 259 | + break; |
| 260 | + case kConsoleLogTypeAssert: |
| 261 | + method = v8_inspector::ConsoleAPIType::kAssert; |
| 262 | + break; |
| 263 | + default: |
| 264 | + break; |
| 265 | + } |
264 | 266 |
|
265 | | - sendToDevToolsFrontEnd(env, method, logString); |
| 267 | + sendToDevToolsFrontEnd(env, method, logString); |
266 | 268 | #endif |
| 269 | + } catch (NativeScriptException& e) { |
| 270 | + e.ReThrowToJS(env); |
| 271 | + } |
267 | 272 |
|
268 | 273 | return UNDEFINED; |
269 | 274 | } |
|
0 commit comments