| 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 "vm/bootstrap_natives.h" | 5 #include "vm/bootstrap_natives.h" |
| 6 | 6 |
| 7 #include "platform/json.h" | 7 #include "platform/json.h" |
| 8 #include "include/dart_api.h" | 8 #include "include/dart_api.h" |
| 9 #include "include/dart_debugger_api.h" | 9 #include "include/dart_debugger_api.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 } else { | 191 } else { |
| 192 // Simple value. | 192 // Simple value. |
| 193 ASSERT(IsSimpleValue(arg)); | 193 ASSERT(IsSimpleValue(arg)); |
| 194 arg_array->Add(arg); | 194 arg_array->Add(arg); |
| 195 } | 195 } |
| 196 } | 196 } |
| 197 return Dart_True(); | 197 return Dart_True(); |
| 198 } | 198 } |
| 199 | 199 |
| 200 | 200 |
| 201 static Dart_Handle CreateLazyLibraryMirror(Dart_Handle lib) { |
| 202 if (Dart_IsNull(lib)) { |
| 203 return lib; |
| 204 } |
| 205 Dart_Handle cls_name = Dart_NewString("_LazyLibraryMirror"); |
| 206 Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name); |
| 207 const int kNumArgs = 1; |
| 208 Dart_Handle args[kNumArgs]; |
| 209 args[0] = Dart_LibraryName(lib); |
| 210 return Dart_New(cls, Dart_Null(), kNumArgs, args); |
| 211 } |
| 212 |
| 213 |
| 214 static Dart_Handle CreateLazyInterfaceMirror(Dart_Handle intf) { |
| 215 if (Dart_IsNull(intf)) { |
| 216 return intf; |
| 217 } |
| 218 Dart_Handle cls_name = Dart_NewString("_LazyInterfaceMirror"); |
| 219 Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name); |
| 220 const int kNumArgs = 2; |
| 221 Dart_Handle args[kNumArgs]; |
| 222 args[0] = Dart_LibraryName(Dart_ClassGetLibrary(intf)); |
| 223 args[1] = Dart_ClassName(intf); |
| 224 return Dart_New(cls, Dart_Null(), kNumArgs, args); |
| 225 } |
| 226 |
| 227 |
| 228 static Dart_Handle CreateImplementsList(Dart_Handle intf) { |
| 229 intptr_t len = 0; |
| 230 Dart_Handle result = Dart_ClassGetInterfaceCount(intf, &len); |
| 231 if (Dart_IsError(result)) { |
| 232 return result; |
| 233 } |
| 234 |
| 235 Dart_Handle mirror_list = Dart_NewList(len); |
| 236 if (Dart_IsError(mirror_list)) { |
| 237 return mirror_list; |
| 238 } |
| 239 |
| 240 for (int i = 0; i < len; i++) { |
| 241 Dart_Handle interface = Dart_ClassGetInterfaceAt(intf, i); |
| 242 if (Dart_IsError(interface)) { |
| 243 return interface; |
| 244 } |
| 245 Dart_Handle mirror = CreateLazyInterfaceMirror(interface); |
| 246 if (Dart_IsError(mirror)) { |
| 247 return mirror; |
| 248 } |
| 249 Dart_Handle result = Dart_ListSetAt(mirror_list, i, mirror); |
| 250 if (Dart_IsError(result)) { |
| 251 return result; |
| 252 } |
| 253 } |
| 254 return mirror_list; |
| 255 } |
| 256 |
| 257 |
| 258 static Dart_Handle CreateInterfaceMirror(Dart_Handle intf, |
| 259 Dart_Handle intf_name, |
| 260 Dart_Handle lib) { |
| 261 ASSERT(Dart_IsClass(intf) || Dart_IsInterface(intf)); |
| 262 Dart_Handle cls_name = Dart_NewString("_LocalInterfaceMirrorImpl"); |
| 263 Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name); |
| 264 if (Dart_IsError(cls)) { |
| 265 return cls; |
| 266 } |
| 267 |
| 268 // TODO(turnidge): Why am I getting Null when I expect Object? |
| 269 Dart_Handle super_class = Dart_GetSuperclass(intf); |
| 270 if (Dart_IsNull(super_class)) { |
| 271 super_class = Dart_GetClass(CoreLib(), Dart_NewString("Object")); |
| 272 } |
| 273 Dart_Handle default_class = Dart_ClassGetDefault(intf); |
| 274 |
| 275 const int kNumArgs = 7; |
| 276 Dart_Handle args[kNumArgs]; |
| 277 args[0] = CreateVMReference(intf); |
| 278 args[1] = intf_name; |
| 279 args[2] = Dart_NewBoolean(Dart_IsClass(intf)); |
| 280 args[3] = CreateLazyLibraryMirror(lib); |
| 281 args[4] = CreateLazyInterfaceMirror(super_class); |
| 282 args[5] = CreateImplementsList(intf); |
| 283 args[6] = CreateLazyInterfaceMirror(default_class); |
| 284 Dart_Handle mirror = Dart_New(cls, Dart_Null(), kNumArgs, args); |
| 285 return mirror; |
| 286 } |
| 287 |
| 288 |
| 289 static Dart_Handle CreateLibraryMemberMap(Dart_Handle lib) { |
| 290 // TODO(turnidge): This should be an immutable map. |
| 291 Dart_Handle map = MapNew(); |
| 292 |
| 293 Dart_Handle intf_names = Dart_LibraryGetClassNames(lib); |
| 294 if (Dart_IsError(intf_names)) { |
| 295 return intf_names; |
| 296 } |
| 297 intptr_t len; |
| 298 Dart_Handle result = Dart_ListLength(intf_names, &len); |
| 299 if (Dart_IsError(result)) { |
| 300 return result; |
| 301 } |
| 302 for (int i = 0; i < len; i++) { |
| 303 Dart_Handle intf_name = Dart_ListGetAt(intf_names, i); |
| 304 Dart_Handle intf = Dart_GetClass(lib, intf_name); |
| 305 if (Dart_IsError(intf)) { |
| 306 return intf; |
| 307 } |
| 308 Dart_Handle intf_mirror = CreateInterfaceMirror(intf, intf_name, lib); |
| 309 if (Dart_IsError(intf_mirror)) { |
| 310 return intf_mirror; |
| 311 } |
| 312 result = MapAdd(map, intf_name, intf_mirror); |
| 313 } |
| 314 return map; |
| 315 } |
| 316 |
| 317 |
| 201 static Dart_Handle CreateLibraryMirror(Dart_Handle lib) { | 318 static Dart_Handle CreateLibraryMirror(Dart_Handle lib) { |
| 202 Dart_Handle cls_name = Dart_NewString("_LocalLibraryMirrorImpl"); | 319 Dart_Handle cls_name = Dart_NewString("_LocalLibraryMirrorImpl"); |
| 203 Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name); | 320 Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name); |
| 204 if (Dart_IsError(cls)) { | 321 if (Dart_IsError(cls)) { |
| 205 return cls; | 322 return cls; |
| 206 } | 323 } |
| 207 const int kNumArgs = 3; | 324 Dart_Handle member_map = CreateLibraryMemberMap(lib); |
| 325 if (Dart_IsError(member_map)) { |
| 326 return member_map; |
| 327 } |
| 328 const int kNumArgs = 4; |
| 208 Dart_Handle args[kNumArgs]; | 329 Dart_Handle args[kNumArgs]; |
| 209 args[0] = CreateVMReference(lib); | 330 args[0] = CreateVMReference(lib); |
| 210 args[1] = Dart_LibraryName(lib); | 331 args[1] = Dart_LibraryName(lib); |
| 211 args[2] = Dart_LibraryUrl(lib); | 332 args[2] = Dart_LibraryUrl(lib); |
| 212 return Dart_New(cls, Dart_Null(), kNumArgs, args); | 333 args[3] = member_map; |
| 334 Dart_Handle lib_mirror = Dart_New(cls, Dart_Null(), kNumArgs, args); |
| 335 if (Dart_IsError(lib_mirror)) { |
| 336 return lib_mirror; |
| 337 } |
| 338 |
| 339 return lib_mirror; |
| 213 } | 340 } |
| 214 | 341 |
| 215 | 342 |
| 216 static Dart_Handle CreateLibrariesMap() { | 343 static Dart_Handle CreateLibrariesMap() { |
| 217 // TODO(turnidge): This should be an immutable map. | 344 // TODO(turnidge): This should be an immutable map. |
| 218 Dart_Handle map = MapNew(); | 345 Dart_Handle map = MapNew(); |
| 219 | 346 |
| 220 Dart_Handle lib_urls = Dart_GetLibraryURLs(); | 347 Dart_Handle lib_urls = Dart_GetLibraryURLs(); |
| 221 if (Dart_IsError(lib_urls)) { | 348 if (Dart_IsError(lib_urls)) { |
| 222 return lib_urls; | 349 return lib_urls; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 237 if (Dart_IsError(lib_mirror)) { | 364 if (Dart_IsError(lib_mirror)) { |
| 238 return lib_mirror; | 365 return lib_mirror; |
| 239 } | 366 } |
| 240 // TODO(turnidge): Check for duplicate library names. | 367 // TODO(turnidge): Check for duplicate library names. |
| 241 result = MapAdd(map, lib_key, lib_mirror); | 368 result = MapAdd(map, lib_key, lib_mirror); |
| 242 } | 369 } |
| 243 return map; | 370 return map; |
| 244 } | 371 } |
| 245 | 372 |
| 246 | 373 |
| 247 static Dart_Handle CreateLocalIsolateMirror() { | 374 static Dart_Handle CreateIsolateMirror() { |
| 248 Dart_Handle cls_name = Dart_NewString("_LocalIsolateMirrorImpl"); | 375 Dart_Handle cls_name = Dart_NewString("_LocalIsolateMirrorImpl"); |
| 249 Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name); | 376 Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name); |
| 250 if (Dart_IsError(cls)) { | 377 if (Dart_IsError(cls)) { |
| 251 return cls; | 378 return cls; |
| 252 } | 379 } |
| 253 | 380 |
| 254 Dart_Handle libraries = CreateLibrariesMap(); | 381 Dart_Handle libraries = CreateLibrariesMap(); |
| 255 if (Dart_IsError(libraries)) { | 382 if (Dart_IsError(libraries)) { |
| 256 return libraries; | 383 return libraries; |
| 257 } | 384 } |
| 258 | 385 |
| 259 // Lookup the root_lib_mirror from the library list to canonicalize it. | 386 // Lookup the root_lib_mirror from the library list to canonicalize it. |
| 260 Dart_Handle root_lib_name = Dart_LibraryName(Dart_RootLibrary()); | 387 Dart_Handle root_lib_name = Dart_LibraryName(Dart_RootLibrary()); |
| 261 Dart_Handle root_lib_mirror = MapGet(libraries, root_lib_name); | 388 Dart_Handle root_lib_mirror = MapGet(libraries, root_lib_name); |
| 262 if (Dart_IsError(root_lib_mirror)) { | 389 if (Dart_IsError(root_lib_mirror)) { |
| 263 return root_lib_mirror; | 390 return root_lib_mirror; |
| 264 } | 391 } |
| 265 | 392 |
| 266 const int kNumArgs = 3; | 393 const int kNumArgs = 3; |
| 267 Dart_Handle args[kNumArgs]; | 394 Dart_Handle args[kNumArgs]; |
| 268 args[0] = Dart_DebugName(); | 395 args[0] = Dart_DebugName(); |
| 269 args[1] = root_lib_mirror; | 396 args[1] = root_lib_mirror; |
| 270 args[2] = libraries; | 397 args[2] = libraries; |
| 271 Dart_Handle mirror = Dart_New(cls, Dart_Null(), kNumArgs, args); | 398 Dart_Handle mirror = Dart_New(cls, Dart_Null(), kNumArgs, args); |
| 399 if (Dart_IsError(mirror)) { |
| 400 return mirror; |
| 401 } |
| 402 |
| 403 return mirror; |
| 404 } |
| 405 |
| 406 |
| 407 static Dart_Handle CreateNullMirror() { |
| 408 Dart_Handle cls_name = Dart_NewString("_LocalInstanceMirrorImpl"); |
| 409 Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name); |
| 410 if (Dart_IsError(cls)) { |
| 411 return cls; |
| 412 } |
| 413 |
| 414 // TODO(turnidge): This is wrong. The Null class is distinct from object. |
| 415 Dart_Handle object_class = Dart_GetClass(CoreLib(), Dart_NewString("Object")); |
| 416 |
| 417 const int kNumArgs = 4; |
| 418 Dart_Handle args[kNumArgs]; |
| 419 args[0] = CreateVMReference(Dart_Null()); |
| 420 args[1] = CreateLazyInterfaceMirror(object_class); |
| 421 args[2] = Dart_True(); |
| 422 args[3] = Dart_Null(); |
| 423 Dart_Handle mirror = Dart_New(cls, Dart_Null(), kNumArgs, args); |
| 272 return mirror; | 424 return mirror; |
| 273 } | 425 } |
| 274 | 426 |
| 275 | 427 |
| 276 static Dart_Handle CreateLocalInstanceMirror(Dart_Handle instance) { | 428 static Dart_Handle CreateInstanceMirror(Dart_Handle instance) { |
| 277 // ASSERT(Dart_IsInstance(instance)); | 429 if (Dart_IsNull(instance)) { |
| 430 return CreateNullMirror(); |
| 431 } |
| 432 ASSERT(Dart_IsInstance(instance)); |
| 278 Dart_Handle cls_name = Dart_NewString("_LocalInstanceMirrorImpl"); | 433 Dart_Handle cls_name = Dart_NewString("_LocalInstanceMirrorImpl"); |
| 279 Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name); | 434 Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name); |
| 280 if (Dart_IsError(cls)) { | 435 if (Dart_IsError(cls)) { |
| 281 return cls; | 436 return cls; |
| 282 } | 437 } |
| 283 const int kNumArgs = 2; | 438 Dart_Handle instance_cls = Dart_InstanceGetClass(instance); |
| 439 if (Dart_IsError(instance_cls)) { |
| 440 return instance_cls; |
| 441 } |
| 442 bool is_simple = IsSimpleValue(instance); |
| 443 const int kNumArgs = 4; |
| 284 Dart_Handle args[kNumArgs]; | 444 Dart_Handle args[kNumArgs]; |
| 285 args[0] = CreateVMReference(instance); | 445 args[0] = CreateVMReference(instance); |
| 286 if (IsSimpleValue(instance)) { | 446 args[1] = CreateLazyInterfaceMirror(instance_cls); |
| 287 args[1] = instance; | 447 args[2] = Dart_NewBoolean(is_simple); |
| 288 } else { | 448 args[3] = (is_simple ? instance : Dart_Null()); |
| 289 args[1] = Dart_Null(); | |
| 290 } | |
| 291 Dart_Handle mirror = Dart_New(cls, Dart_Null(), kNumArgs, args); | 449 Dart_Handle mirror = Dart_New(cls, Dart_Null(), kNumArgs, args); |
| 292 return mirror; | 450 return mirror; |
| 293 } | 451 } |
| 294 | 452 |
| 295 | 453 |
| 454 static Dart_Handle CreateMirroredError(Dart_Handle error) { |
| 455 ASSERT(Dart_IsError(error)); |
| 456 if (Dart_IsUnhandledExceptionError(error)) { |
| 457 Dart_Handle exc = Dart_ErrorGetException(error); |
| 458 if (Dart_IsError(exc)) { |
| 459 return exc; |
| 460 } |
| 461 Dart_Handle exc_string = Dart_ToString(exc); |
| 462 if (Dart_IsError(exc_string)) { |
| 463 // Only propagate fatal errors from exc.toString(). Ignore the rest. |
| 464 if (Dart_IsFatalError(exc_string)) { |
| 465 return exc_string; |
| 466 } |
| 467 exc_string = Dart_Null(); |
| 468 } |
| 469 |
| 470 Dart_Handle stack = Dart_ErrorGetStacktrace(error); |
| 471 if (Dart_IsError(stack)) { |
| 472 return stack; |
| 473 } |
| 474 Dart_Handle cls_name = Dart_NewString("MirroredUncaughtExceptionError"); |
| 475 Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name); |
| 476 const int kNumArgs = 3; |
| 477 Dart_Handle args[kNumArgs]; |
| 478 args[0] = CreateInstanceMirror(exc); |
| 479 args[1] = exc_string; |
| 480 args[2] = stack; |
| 481 Dart_Handle mirrored_exc = Dart_New(cls, Dart_Null(), kNumArgs, args); |
| 482 return Dart_NewUnhandledExceptionError(mirrored_exc); |
| 483 } else if (Dart_IsApiError(error) || |
| 484 Dart_IsCompilationError(error)) { |
| 485 Dart_Handle cls_name = Dart_NewString("MirroredCompilationError"); |
| 486 Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name); |
| 487 const int kNumArgs = 1; |
| 488 Dart_Handle args[kNumArgs]; |
| 489 args[0] = Dart_NewString(Dart_GetError(error)); |
| 490 Dart_Handle mirrored_exc = Dart_New(cls, Dart_Null(), kNumArgs, args); |
| 491 return Dart_NewUnhandledExceptionError(mirrored_exc); |
| 492 } else { |
| 493 ASSERT(Dart_IsFatalError(error)); |
| 494 return error; |
| 495 } |
| 496 } |
| 497 |
| 498 |
| 296 void NATIVE_ENTRY_FUNCTION(Mirrors_makeLocalIsolateMirror)( | 499 void NATIVE_ENTRY_FUNCTION(Mirrors_makeLocalIsolateMirror)( |
| 297 Dart_NativeArguments args) { | 500 Dart_NativeArguments args) { |
| 298 Dart_Handle mirror = CreateLocalIsolateMirror(); | 501 Dart_Handle mirror = CreateIsolateMirror(); |
| 502 if (Dart_IsError(mirror)) { |
| 503 Dart_PropagateError(mirror); |
| 504 } |
| 505 Dart_SetReturnValue(args, mirror); |
| 506 } |
| 507 |
| 508 void NATIVE_ENTRY_FUNCTION(Mirrors_makeLocalInstanceMirror)( |
| 509 Dart_NativeArguments args) { |
| 510 Dart_Handle reflectee = Dart_GetNativeArgument(args, 0); |
| 511 Dart_Handle mirror = CreateInstanceMirror(reflectee); |
| 299 if (Dart_IsError(mirror)) { | 512 if (Dart_IsError(mirror)) { |
| 300 Dart_PropagateError(mirror); | 513 Dart_PropagateError(mirror); |
| 301 } | 514 } |
| 302 Dart_SetReturnValue(args, mirror); | 515 Dart_SetReturnValue(args, mirror); |
| 303 } | 516 } |
| 304 | 517 |
| 305 void NATIVE_ENTRY_FUNCTION(LocalObjectMirrorImpl_invoke)( | 518 void NATIVE_ENTRY_FUNCTION(LocalObjectMirrorImpl_invoke)( |
| 306 Dart_NativeArguments args) { | 519 Dart_NativeArguments args) { |
| 307 Dart_Handle mirror = Dart_GetNativeArgument(args, 0); | 520 Dart_Handle mirror = Dart_GetNativeArgument(args, 0); |
| 308 Dart_Handle member = Dart_GetNativeArgument(args, 1); | 521 Dart_Handle member = Dart_GetNativeArgument(args, 1); |
| 309 Dart_Handle raw_invoke_args = Dart_GetNativeArgument(args, 2); | 522 Dart_Handle raw_invoke_args = Dart_GetNativeArgument(args, 2); |
| 310 | 523 |
| 311 Dart_Handle reflectee = UnwrapMirror(mirror); | 524 Dart_Handle reflectee = UnwrapMirror(mirror); |
| 312 GrowableArray<Dart_Handle> invoke_args; | 525 GrowableArray<Dart_Handle> invoke_args; |
| 313 Dart_Handle result = UnwrapArgList(raw_invoke_args, &invoke_args); | 526 Dart_Handle result = UnwrapArgList(raw_invoke_args, &invoke_args); |
| 314 if (Dart_IsError(result)) { | 527 if (Dart_IsError(result)) { |
| 315 Dart_PropagateError(result); | 528 Dart_PropagateError(result); |
| 316 } | 529 } |
| 317 result = | 530 result = |
| 318 Dart_Invoke(reflectee, member, invoke_args.length(), invoke_args.data()); | 531 Dart_Invoke(reflectee, member, invoke_args.length(), invoke_args.data()); |
| 319 if (Dart_IsError(result)) { | 532 if (Dart_IsError(result)) { |
| 320 Dart_PropagateError(result); | 533 // Instead of propagating the error from an invoke directly, we |
| 534 // provide reflective access to the error. |
| 535 Dart_PropagateError(CreateMirroredError(result)); |
| 321 } | 536 } |
| 322 Dart_Handle wrapped_result = CreateLocalInstanceMirror(result); | 537 |
| 538 Dart_Handle wrapped_result = CreateInstanceMirror(result); |
| 323 if (Dart_IsError(wrapped_result)) { | 539 if (Dart_IsError(wrapped_result)) { |
| 324 Dart_PropagateError(wrapped_result); | 540 Dart_PropagateError(wrapped_result); |
| 325 } | 541 } |
| 326 Dart_SetReturnValue(args, wrapped_result); | 542 Dart_SetReturnValue(args, wrapped_result); |
| 327 } | 543 } |
| 328 | 544 |
| 329 void HandleMirrorsMessage(Isolate* isolate, | 545 void HandleMirrorsMessage(Isolate* isolate, |
| 330 Dart_Port reply_port, | 546 Dart_Port reply_port, |
| 331 const Instance& message) { | 547 const Instance& message) { |
| 332 UNIMPLEMENTED(); | 548 UNIMPLEMENTED(); |
| 333 } | 549 } |
| 334 | 550 |
| 335 } // namespace dart | 551 } // namespace dart |
| OLD | NEW |