OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "platform/assert.h" | 5 #include "platform/assert.h" |
6 #include "vm/bootstrap_natives.h" | 6 #include "vm/bootstrap_natives.h" |
7 #include "vm/class_finalizer.h" | 7 #include "vm/class_finalizer.h" |
8 #include "vm/dart.h" | 8 #include "vm/dart.h" |
9 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
118 } | 118 } |
119 | 119 |
120 | 120 |
121 static void ThrowIsolateSpawnException(const String& message) { | 121 static void ThrowIsolateSpawnException(const String& message) { |
122 const Array& args = Array::Handle(Array::New(1)); | 122 const Array& args = Array::Handle(Array::New(1)); |
123 args.SetAt(0, message); | 123 args.SetAt(0, message); |
124 Exceptions::ThrowByType(Exceptions::kIsolateSpawn, args); | 124 Exceptions::ThrowByType(Exceptions::kIsolateSpawn, args); |
125 } | 125 } |
126 | 126 |
127 | 127 |
128 static bool CanonicalizeUri(Isolate* isolate, | |
129 const Library& library, | |
130 const String& uri, | |
131 char** canonical_uri, | |
132 char** error) { | |
133 Zone* zone = isolate->current_zone(); | |
134 bool retval = false; | |
135 Dart_LibraryTagHandler handler = isolate->library_tag_handler(); | |
136 if (handler != NULL) { | |
137 Dart_EnterScope(); | |
138 Dart_Handle result = handler(Dart_kCanonicalizeUrl, | |
139 Api::NewHandle(isolate, library.raw()), | |
140 Api::NewHandle(isolate, uri.raw())); | |
141 const Object& obj = Object::Handle(Api::UnwrapHandle(result)); | |
142 if (obj.IsString()) { | |
143 *canonical_uri = zone->MakeCopyOfString(String::Cast(obj).ToCString()); | |
144 retval = true; | |
145 } else if (obj.IsError()) { | |
146 Error& error_obj = Error::Handle(); | |
147 error_obj ^= obj.raw(); | |
148 *error = zone->PrintToString("Unable to canonicalize uri '%s': %s", | |
149 uri.ToCString(), error_obj.ToErrorCString()); | |
150 } else { | |
151 *error = zone->PrintToString("Unable to canonicalize uri '%s': " | |
152 "library tag handler returned wrong type", | |
153 uri.ToCString()); | |
154 } | |
155 Dart_ExitScope(); | |
156 } else { | |
157 *error = zone->PrintToString( | |
158 "Unable to canonicalize uri '%s': no library tag handler found.", | |
159 uri.ToCString()); | |
160 } | |
161 return retval; | |
162 } | |
163 | |
164 | |
165 static bool CreateIsolate(Isolate* parent_isolate, | 128 static bool CreateIsolate(Isolate* parent_isolate, |
166 IsolateSpawnState* state, | 129 IsolateSpawnState* state, |
167 char** error) { | 130 char** error) { |
168 Dart_IsolateCreateCallback callback = Isolate::CreateCallback(); | 131 Dart_IsolateCreateCallback callback = Isolate::CreateCallback(); |
169 if (callback == NULL) { | 132 if (callback == NULL) { |
170 *error = strdup("Null callback specified for isolate creation\n"); | 133 *error = strdup("Null callback specified for isolate creation\n"); |
171 return false; | 134 return false; |
172 } | 135 } |
173 | 136 |
174 Dart_IsolateFlags api_flags; | 137 Dart_IsolateFlags api_flags; |
175 state->isolate_flags()->CopyTo(&api_flags); | 138 state->isolate_flags()->CopyTo(&api_flags); |
176 | 139 |
177 void* init_data = parent_isolate->init_callback_data(); | 140 void* init_data = parent_isolate->init_callback_data(); |
178 Isolate* child_isolate = reinterpret_cast<Isolate*>( | 141 Isolate* child_isolate = reinterpret_cast<Isolate*>( |
179 (callback)(state->script_url(), | 142 (callback)(state->script_url(), |
180 state->function_name(), | 143 state->function_name(), |
181 state->package_root(), | 144 state->package_root(), |
145 state->package_map(), | |
182 &api_flags, | 146 &api_flags, |
183 init_data, | 147 init_data, |
184 error)); | 148 error)); |
185 if (child_isolate == NULL) { | 149 if (child_isolate == NULL) { |
186 return false; | 150 return false; |
187 } | 151 } |
188 if (!state->is_spawn_uri()) { | 152 if (!state->is_spawn_uri()) { |
189 // For isolates spawned using the spawn semantics we set | 153 // For isolates spawned using the spawn semantics we set |
190 // the origin_id to the origin_id of the parent isolate. | 154 // the origin_id to the origin_id of the parent isolate. |
191 child_isolate->set_origin_id(parent_isolate->origin_id()); | 155 child_isolate->set_origin_id(parent_isolate->origin_id()); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
252 return Object::null(); | 216 return Object::null(); |
253 } | 217 } |
254 } | 218 } |
255 const String& msg = String::Handle(String::New( | 219 const String& msg = String::Handle(String::New( |
256 "Isolate.spawn expects to be passed a static or top-level function")); | 220 "Isolate.spawn expects to be passed a static or top-level function")); |
257 Exceptions::ThrowArgumentError(msg); | 221 Exceptions::ThrowArgumentError(msg); |
258 return Object::null(); | 222 return Object::null(); |
259 } | 223 } |
260 | 224 |
261 | 225 |
226 static char* String2UTF8(const String& str) { | |
227 intptr_t len = Utf8::Length(str); | |
228 char* result = new char[len + 1]; | |
229 str.ToUTF8(reinterpret_cast<uint8_t*>(result), len); | |
230 result[len] = 0; | |
231 | |
232 return result; | |
233 } | |
234 | |
235 | |
236 static char* CanonicalizeUri(Isolate* isolate, | |
237 const Library& library, | |
Lasse Reichstein Nielsen
2015/10/12 09:34:44
Indentation is off-by-1.
Ivan Posva
2015/10/12 16:05:22
Done.
| |
238 const String& uri, | |
239 char** error) { | |
240 char* result = NULL; | |
241 Zone* zone = isolate->current_zone(); | |
242 Dart_LibraryTagHandler handler = isolate->library_tag_handler(); | |
243 if (handler != NULL) { | |
244 Dart_EnterScope(); | |
245 Dart_Handle handle = handler(Dart_kCanonicalizeUrl, | |
246 Api::NewHandle(isolate, library.raw()), | |
247 Api::NewHandle(isolate, uri.raw())); | |
248 const Object& obj = Object::Handle(Api::UnwrapHandle(handle)); | |
249 if (obj.IsString()) { | |
250 result = String2UTF8(String::Cast(obj)); | |
251 } else if (obj.IsError()) { | |
252 Error& error_obj = Error::Handle(); | |
253 error_obj ^= obj.raw(); | |
254 *error = zone->PrintToString("Unable to canonicalize uri '%s': %s", | |
255 uri.ToCString(), error_obj.ToErrorCString()); | |
256 } else { | |
257 *error = zone->PrintToString("Unable to canonicalize uri '%s': " | |
258 "library tag handler returned wrong type", | |
259 uri.ToCString()); | |
260 } | |
261 Dart_ExitScope(); | |
262 } else { | |
263 *error = zone->PrintToString( | |
264 "Unable to canonicalize uri '%s': no library tag handler found.", | |
265 uri.ToCString()); | |
266 } | |
267 return result; | |
268 } | |
269 | |
270 | |
262 DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 12) { | 271 DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 12) { |
263 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); | 272 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); |
264 GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(1)); | 273 GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(1)); |
265 | 274 |
266 GET_NON_NULL_NATIVE_ARGUMENT(Instance, args, arguments->NativeArgAt(2)); | 275 GET_NON_NULL_NATIVE_ARGUMENT(Instance, args, arguments->NativeArgAt(2)); |
267 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(3)); | 276 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(3)); |
268 | 277 |
269 GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4)); | 278 GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4)); |
270 GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(5)); | 279 GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(5)); |
271 GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(6)); | 280 GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(6)); |
272 | 281 |
273 GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(7)); | 282 GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(7)); |
274 GET_NATIVE_ARGUMENT(Bool, checked, arguments->NativeArgAt(8)); | 283 GET_NATIVE_ARGUMENT(Bool, checked, arguments->NativeArgAt(8)); |
275 | 284 |
276 GET_NATIVE_ARGUMENT(Array, environment, arguments->NativeArgAt(9)); | 285 GET_NATIVE_ARGUMENT(Array, environment, arguments->NativeArgAt(9)); |
277 | 286 |
278 GET_NATIVE_ARGUMENT(String, package_root, arguments->NativeArgAt(10)); | 287 GET_NATIVE_ARGUMENT(String, package_root, arguments->NativeArgAt(10)); |
279 GET_NATIVE_ARGUMENT(Array, packages, arguments->NativeArgAt(11)); | 288 GET_NATIVE_ARGUMENT(Array, packages, arguments->NativeArgAt(11)); |
280 | 289 |
281 | 290 |
282 // Canonicalize the uri with respect to the current isolate. | 291 // Canonicalize the uri with respect to the current isolate. |
283 char* error = NULL; | |
284 char* canonical_uri = NULL; | |
285 const Library& root_lib = | 292 const Library& root_lib = |
286 Library::Handle(isolate->object_store()->root_library()); | 293 Library::Handle(isolate->object_store()->root_library()); |
287 if (!CanonicalizeUri(isolate, root_lib, uri, | 294 char* error = NULL; |
288 &canonical_uri, &error)) { | 295 char* canonical_uri = CanonicalizeUri(isolate, root_lib, uri, &error); |
296 if (canonical_uri == NULL) { | |
289 const String& msg = String::Handle(String::New(error)); | 297 const String& msg = String::Handle(String::New(error)); |
290 ThrowIsolateSpawnException(msg); | 298 ThrowIsolateSpawnException(msg); |
291 } | 299 } |
292 | 300 |
293 char* utf8_package_root = NULL; | 301 char* utf8_package_root = |
294 if (!package_root.IsNull()) { | 302 package_root.IsNull() ? NULL : String2UTF8(package_root); |
295 const intptr_t len = Utf8::Length(package_root); | 303 |
296 utf8_package_root = zone->Alloc<char>(len + 1); | 304 char** utf8_package_map = NULL; |
297 package_root.ToUTF8(reinterpret_cast<uint8_t*>(utf8_package_root), len); | 305 if (!packages.IsNull()) { |
298 utf8_package_root[len] = '\0'; | 306 intptr_t len = packages.Length(); |
307 utf8_package_map = new char*[len + 1]; | |
308 | |
309 Object& entry = Object::Handle(); | |
310 for (intptr_t i = 0; i < len; i++) { | |
311 entry = packages.At(i); | |
312 if (!entry.IsString()) { | |
313 const String& msg = String::Handle(String::NewFormatted( | |
314 "Bad value in package map: %s", entry.ToCString())); | |
315 ThrowIsolateSpawnException(msg); | |
316 } | |
317 utf8_package_map[i] = String2UTF8(String::Cast(entry)); | |
318 } | |
319 // NULL terminated array. | |
320 utf8_package_map[len] = NULL; | |
299 } | 321 } |
300 | 322 |
301 bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value(); | 323 bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value(); |
302 Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id(); | 324 Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id(); |
303 Dart_Port on_error_port = onError.IsNull() ? ILLEGAL_PORT : onError.Id(); | 325 Dart_Port on_error_port = onError.IsNull() ? ILLEGAL_PORT : onError.Id(); |
304 | 326 |
305 IsolateSpawnState* state = new IsolateSpawnState(port.Id(), | 327 IsolateSpawnState* state = new IsolateSpawnState( |
306 canonical_uri, | 328 port.Id(), |
307 utf8_package_root, | 329 canonical_uri, |
308 args, | 330 utf8_package_root, |
309 message, | 331 const_cast<const char**>(utf8_package_map), |
310 paused.value(), | 332 args, |
311 fatal_errors, | 333 message, |
312 on_exit_port, | 334 paused.value(), |
313 on_error_port); | 335 fatal_errors, |
336 on_exit_port, | |
337 on_error_port); | |
314 // If we were passed a value then override the default flags state for | 338 // If we were passed a value then override the default flags state for |
315 // checked mode. | 339 // checked mode. |
316 if (!checked.IsNull()) { | 340 if (!checked.IsNull()) { |
317 state->isolate_flags()->set_checked(checked.value()); | 341 state->isolate_flags()->set_checked(checked.value()); |
318 } | 342 } |
319 | 343 |
320 Spawn(isolate, state); | 344 Spawn(isolate, state); |
321 return Object::null(); | 345 return Object::null(); |
322 } | 346 } |
323 | 347 |
(...skipping 20 matching lines...) Expand all Loading... | |
344 MessageWriter writer(&data, &allocator, false); | 368 MessageWriter writer(&data, &allocator, false); |
345 writer.WriteMessage(msg); | 369 writer.WriteMessage(msg); |
346 | 370 |
347 PortMap::PostMessage(new Message(port.Id(), | 371 PortMap::PostMessage(new Message(port.Id(), |
348 data, writer.BytesWritten(), | 372 data, writer.BytesWritten(), |
349 Message::kOOBPriority)); | 373 Message::kOOBPriority)); |
350 return Object::null(); | 374 return Object::null(); |
351 } | 375 } |
352 | 376 |
353 } // namespace dart | 377 } // namespace dart |
OLD | NEW |