Chromium Code Reviews| 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 "include/dart_api.h" | 5 #include "include/dart_api.h" |
| 6 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/dart.h" | 10 #include "vm/dart.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 51 CURRENT_FUNC, #dart_handle); \ | 51 CURRENT_FUNC, #dart_handle); \ |
| 52 } else if (tmp.IsError()) { \ | 52 } else if (tmp.IsError()) { \ |
| 53 return dart_handle; \ | 53 return dart_handle; \ |
| 54 } else { \ | 54 } else { \ |
| 55 return Api::NewError("%s expects argument '%s' to be of type %s.", \ | 55 return Api::NewError("%s expects argument '%s' to be of type %s.", \ |
| 56 CURRENT_FUNC, #dart_handle, #Type); \ | 56 CURRENT_FUNC, #dart_handle, #Type); \ |
| 57 } \ | 57 } \ |
| 58 } while (0) | 58 } while (0) |
| 59 | 59 |
| 60 | 60 |
| 61 // Removes internal vm prefixes and suffixes from an identifier. | |
| 62 static RawString* StripName(Isolate* isolate, const String& name) { | |
|
cshapiro
2012/06/28 23:57:47
IdentifierPrettyName? Better comment with example
turnidge
2012/07/09 23:45:17
Done.
| |
| 63 intptr_t len = name.Length(); | |
| 64 intptr_t start = 0; | |
| 65 intptr_t at_pos = len; // Position of '@' in the name. | |
| 66 intptr_t dot_pos = len; // Position of '.' in the name. | |
| 67 | |
| 68 for (int i = 0; i < name.Length(); i++) { | |
| 69 if (name.CharAt(i) == ':') { | |
| 70 ASSERT(start == 0); | |
| 71 start = i + 1; | |
| 72 } else if (name.CharAt(i) == '@') { | |
| 73 ASSERT(at_pos == len); | |
| 74 at_pos = i; | |
| 75 } else if (name.CharAt(i) == '.') { | |
| 76 dot_pos = i; | |
| 77 break; | |
| 78 } | |
| 79 } | |
| 80 intptr_t limit = (at_pos < dot_pos ? at_pos : dot_pos); | |
| 81 if (start == 0 && limit == len) { | |
| 82 // This name is fine as it is. | |
| 83 return name.raw(); | |
| 84 } | |
| 85 | |
| 86 String& result = String::Handle(isolate); | |
| 87 result = String::SubString(name, start, (limit - start)); | |
| 88 | |
| 89 // Look for a second '@' now to correctly handle names like | |
| 90 // "_ReceivePortImpl@6be832b._internal@6be832b". | |
| 91 at_pos = len; | |
| 92 for (int i = dot_pos; i < name.Length(); i++) { | |
| 93 if (name.CharAt(i) == '@') { | |
| 94 ASSERT(at_pos == len); | |
| 95 at_pos = i; | |
| 96 } | |
| 97 } | |
| 98 | |
| 99 intptr_t suffix_len = at_pos - dot_pos; | |
| 100 if (suffix_len <= 1) { | |
| 101 // The constructor name is of length 0 or 1. That means that | |
| 102 // either this isn't a constructor or that this is an unnamed | |
| 103 // constructor. In either case, we're done. | |
| 104 return result.raw(); | |
| 105 } | |
| 106 | |
| 107 const String& suffix = | |
| 108 String::Handle(isolate, String::SubString(name, dot_pos, suffix_len)); | |
| 109 return String::Concat(result, suffix); | |
| 110 } | |
| 111 | |
| 112 | |
| 61 // Return error if isolate is in an inconsistent state. | 113 // Return error if isolate is in an inconsistent state. |
| 62 // Return NULL when no error condition exists. | 114 // Return NULL when no error condition exists. |
| 63 // | 115 // |
| 64 // TODO(turnidge): Make this function return an error handle directly | 116 // TODO(turnidge): Make this function return an error handle directly |
| 65 // rather than returning an error string. The current behavior can | 117 // rather than returning an error string. The current behavior can |
| 66 // cause compilation errors to appear to be api errors. | 118 // cause compilation errors to appear to be api errors. |
| 67 const char* CheckIsolateState(Isolate* isolate, bool generating_snapshot) { | 119 const char* CheckIsolateState(Isolate* isolate, bool generating_snapshot) { |
| 68 bool success = true; | 120 bool success = true; |
| 69 if (!ClassFinalizer::AllClassesFinalized()) { | 121 if (!ClassFinalizer::AllClassesFinalized()) { |
| 70 success = (generating_snapshot) ? | 122 success = (generating_snapshot) ? |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 101 ApiLocalScope* scope = state->top_scope(); | 153 ApiLocalScope* scope = state->top_scope(); |
| 102 ASSERT(scope != NULL); | 154 ASSERT(scope != NULL); |
| 103 LocalHandles* local_handles = scope->local_handles(); | 155 LocalHandles* local_handles = scope->local_handles(); |
| 104 ASSERT(local_handles != NULL); | 156 ASSERT(local_handles != NULL); |
| 105 LocalHandle* ref = local_handles->AllocateHandle(); | 157 LocalHandle* ref = local_handles->AllocateHandle(); |
| 106 ref->set_raw(raw); | 158 ref->set_raw(raw); |
| 107 return reinterpret_cast<Dart_Handle>(ref); | 159 return reinterpret_cast<Dart_Handle>(ref); |
| 108 } | 160 } |
| 109 | 161 |
| 110 RawObject* Api::UnwrapHandle(Dart_Handle object) { | 162 RawObject* Api::UnwrapHandle(Dart_Handle object) { |
| 111 #ifdef DEBUG | 163 #if defined(DEBUG) |
| 112 Isolate* isolate = Isolate::Current(); | 164 Isolate* isolate = Isolate::Current(); |
| 113 ASSERT(isolate != NULL); | 165 ASSERT(isolate != NULL); |
| 114 ApiState* state = isolate->api_state(); | 166 ApiState* state = isolate->api_state(); |
| 115 ASSERT(state != NULL); | 167 ASSERT(state != NULL); |
| 116 ASSERT(state->IsValidPrologueWeakPersistentHandle(object) || | 168 ASSERT(state->IsValidPrologueWeakPersistentHandle(object) || |
| 117 state->IsValidWeakPersistentHandle(object) || | 169 state->IsValidWeakPersistentHandle(object) || |
| 118 state->IsValidPersistentHandle(object) || | 170 state->IsValidPersistentHandle(object) || |
| 119 state->IsValidLocalHandle(object)); | 171 state->IsValidLocalHandle(object)); |
| 120 ASSERT(FinalizablePersistentHandle::raw_offset() == 0 && | 172 ASSERT(FinalizablePersistentHandle::raw_offset() == 0 && |
| 121 PersistentHandle::raw_offset() == 0 && | 173 PersistentHandle::raw_offset() == 0 && |
| (...skipping 2303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2425 | 2477 |
| 2426 | 2478 |
| 2427 DART_EXPORT Dart_Handle Dart_ClassName(Dart_Handle clazz) { | 2479 DART_EXPORT Dart_Handle Dart_ClassName(Dart_Handle clazz) { |
| 2428 Isolate* isolate = Isolate::Current(); | 2480 Isolate* isolate = Isolate::Current(); |
| 2429 DARTSCOPE(isolate); | 2481 DARTSCOPE(isolate); |
| 2430 Class& cls = Class::Handle(isolate); | 2482 Class& cls = Class::Handle(isolate); |
| 2431 cls ^= Api::UnwrapClassHandle(isolate, clazz).raw(); | 2483 cls ^= Api::UnwrapClassHandle(isolate, clazz).raw(); |
| 2432 if (cls.IsNull()) { | 2484 if (cls.IsNull()) { |
| 2433 RETURN_TYPE_ERROR(isolate, clazz, Class); | 2485 RETURN_TYPE_ERROR(isolate, clazz, Class); |
| 2434 } | 2486 } |
| 2435 return Api::NewHandle(isolate, cls.Name()); | 2487 const String& cls_name = String::Handle(isolate, cls.Name()); |
| 2488 return Api::NewHandle(isolate, StripName(isolate, cls_name)); | |
| 2436 } | 2489 } |
| 2437 | 2490 |
| 2438 | 2491 |
| 2439 DART_EXPORT Dart_Handle Dart_ClassGetLibrary(Dart_Handle clazz) { | 2492 DART_EXPORT Dart_Handle Dart_ClassGetLibrary(Dart_Handle clazz) { |
| 2440 Isolate* isolate = Isolate::Current(); | 2493 Isolate* isolate = Isolate::Current(); |
| 2441 DARTSCOPE(isolate); | 2494 DARTSCOPE(isolate); |
| 2442 Class& cls = Class::Handle(isolate); | 2495 Class& cls = Class::Handle(isolate); |
| 2443 cls ^= Api::UnwrapClassHandle(isolate, clazz).raw(); | 2496 cls ^= Api::UnwrapClassHandle(isolate, clazz).raw(); |
| 2444 if (cls.IsNull()) { | 2497 if (cls.IsNull()) { |
| 2445 RETURN_TYPE_ERROR(isolate, clazz, Class); | 2498 RETURN_TYPE_ERROR(isolate, clazz, Class); |
| 2446 } | 2499 } |
| 2500 | |
| 2501 #if defined(DEBUG) | |
| 2502 const Library& lib = Library::Handle(cls.library()); | |
| 2503 if (lib.IsNull()) { | |
| 2504 ASSERT(cls.IsDynamicClass() || cls.IsVoidClass()); | |
| 2505 } | |
| 2506 #endif | |
| 2507 | |
| 2447 return Api::NewHandle(isolate, cls.library()); | 2508 return Api::NewHandle(isolate, cls.library()); |
| 2448 } | 2509 } |
| 2449 | 2510 |
| 2450 | 2511 |
| 2451 DART_EXPORT Dart_Handle Dart_ClassGetDefault(Dart_Handle clazz) { | 2512 DART_EXPORT Dart_Handle Dart_ClassGetDefault(Dart_Handle clazz) { |
| 2452 Isolate* isolate = Isolate::Current(); | 2513 Isolate* isolate = Isolate::Current(); |
| 2453 DARTSCOPE(isolate); | 2514 DARTSCOPE(isolate); |
| 2454 Class& cls = Class::Handle(isolate); | 2515 Class& cls = Class::Handle(isolate); |
| 2455 cls ^= Api::UnwrapClassHandle(isolate, clazz).raw(); | 2516 cls ^= Api::UnwrapClassHandle(isolate, clazz).raw(); |
| 2456 if (cls.IsNull()) { | 2517 if (cls.IsNull()) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2515 if (interface_type.HasResolvedTypeClass()) { | 2576 if (interface_type.HasResolvedTypeClass()) { |
| 2516 return Api::NewHandle(isolate, interface_type.type_class()); | 2577 return Api::NewHandle(isolate, interface_type.type_class()); |
| 2517 } | 2578 } |
| 2518 const String& type_name = | 2579 const String& type_name = |
| 2519 String::Handle(isolate, interface_type.TypeClassName()); | 2580 String::Handle(isolate, interface_type.TypeClassName()); |
| 2520 return Api::NewError("%s: internal error: found unresolved type class '%s'.", | 2581 return Api::NewError("%s: internal error: found unresolved type class '%s'.", |
| 2521 CURRENT_FUNC, type_name.ToCString()); | 2582 CURRENT_FUNC, type_name.ToCString()); |
| 2522 } | 2583 } |
| 2523 | 2584 |
| 2524 | 2585 |
| 2586 // --- Function and Variable Reflection --- | |
| 2587 | |
| 2588 | |
| 2589 // Outside of the vm, we expose setter names with a trailing '='. | |
| 2590 static bool HasExternalSetterSuffix(const String& name) { | |
| 2591 return name.CharAt(name.Length() - 1) == '='; | |
| 2592 } | |
| 2593 | |
| 2594 | |
| 2595 static RawString* AddExternalSetterSuffix(const String& name) { | |
| 2596 const String& equals = String::Handle(String::NewSymbol("=")); | |
| 2597 return String::Concat(name, equals); | |
| 2598 } | |
| 2599 | |
| 2600 | |
| 2601 static RawString* RemoveExternalSetterSuffix(const String& name) { | |
| 2602 ASSERT(HasExternalSetterSuffix(name)); | |
| 2603 return String::SubString(name, 0, name.Length() - 1); | |
| 2604 } | |
| 2605 | |
| 2606 | |
| 2607 DART_EXPORT Dart_Handle Dart_GetFunctionNames(Dart_Handle target) { | |
| 2608 Isolate* isolate = Isolate::Current(); | |
| 2609 DARTSCOPE(isolate); | |
| 2610 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); | |
| 2611 if (obj.IsError()) { | |
| 2612 return target; | |
| 2613 } | |
| 2614 | |
| 2615 const GrowableObjectArray& names = | |
| 2616 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); | |
| 2617 Function& func = Function::Handle(); | |
| 2618 String& name = String::Handle(); | |
| 2619 | |
| 2620 if (obj.IsClass()) { | |
| 2621 Class& cls = Class::Handle(isolate); | |
| 2622 cls ^= obj.raw(); | |
| 2623 const Array& func_array = Array::Handle(cls.functions()); | |
| 2624 | |
| 2625 // Some special types like 'Dynamic' have a null functions list. | |
| 2626 if (!func_array.IsNull()) { | |
| 2627 for (intptr_t i = 0; i < func_array.Length(); ++i) { | |
| 2628 func ^= func_array.At(i); | |
| 2629 | |
| 2630 // Skip implicit getters and setters. | |
| 2631 if (func.kind() == RawFunction::kImplicitGetter || | |
| 2632 func.kind() == RawFunction::kImplicitSetter || | |
| 2633 func.kind() == RawFunction::kConstImplicitGetter) { | |
| 2634 continue; | |
| 2635 } | |
| 2636 | |
| 2637 name = func.name(); | |
| 2638 bool is_setter = Field::IsSetterName(name); | |
| 2639 name = StripName(isolate, name); | |
| 2640 | |
| 2641 if (is_setter) { | |
| 2642 name = AddExternalSetterSuffix(name); | |
| 2643 } | |
| 2644 names.Add(name); | |
| 2645 } | |
| 2646 } | |
| 2647 } else if (obj.IsLibrary()) { | |
| 2648 Library& lib = Library::Handle(isolate); | |
| 2649 lib ^= obj.raw(); | |
| 2650 DictionaryIterator it(lib); | |
| 2651 Object& obj = Object::Handle(); | |
| 2652 while (it.HasNext()) { | |
| 2653 obj = it.GetNext(); | |
| 2654 if (obj.IsFunction()) { | |
| 2655 func ^= obj.raw(); | |
| 2656 name = func.name(); | |
| 2657 bool is_setter = Field::IsSetterName(name); | |
| 2658 name = StripName(isolate, name); | |
| 2659 if (is_setter) { | |
| 2660 name = AddExternalSetterSuffix(name); | |
| 2661 } | |
| 2662 names.Add(name); | |
| 2663 } | |
| 2664 } | |
| 2665 } else { | |
| 2666 return Api::NewError( | |
| 2667 "%s expects argument 'target' to be a class or library.", | |
| 2668 CURRENT_FUNC); | |
| 2669 } | |
| 2670 return Api::NewHandle(isolate, Array::MakeArray(names)); | |
| 2671 } | |
| 2672 | |
| 2673 | |
| 2674 DART_EXPORT Dart_Handle Dart_LookupFunction(Dart_Handle target, | |
| 2675 Dart_Handle function_name) { | |
| 2676 Isolate* isolate = Isolate::Current(); | |
| 2677 DARTSCOPE(isolate); | |
| 2678 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); | |
| 2679 if (obj.IsError()) { | |
| 2680 return target; | |
| 2681 } | |
| 2682 const String& func_name = Api::UnwrapStringHandle(isolate, function_name); | |
| 2683 if (func_name.IsNull()) { | |
| 2684 RETURN_TYPE_ERROR(isolate, function_name, String); | |
| 2685 } | |
| 2686 | |
| 2687 Function& func = Function::Handle(isolate); | |
| 2688 String& tmp_name = String::Handle(isolate); | |
| 2689 if (obj.IsClass()) { | |
| 2690 Class& cls = Class::Handle(isolate); | |
| 2691 cls ^= obj.raw(); | |
| 2692 func = cls.LookupFunction(func_name); | |
| 2693 | |
| 2694 // Check for functions with the external setter suffix '='. Make | |
|
cshapiro
2012/06/28 23:57:47
Totally optional, maybe make it clear that we are
turnidge
2012/07/09 23:45:17
Done.
turnidge
2012/07/09 23:45:17
Done.
| |
| 2695 // sure to do this check after the regular lookup, so that we | |
| 2696 // don't interfere with operator lookups (like ==). | |
| 2697 if (func.IsNull() && HasExternalSetterSuffix(func_name)) { | |
| 2698 tmp_name = RemoveExternalSetterSuffix(func_name); | |
| 2699 tmp_name = Field::SetterName(tmp_name); | |
| 2700 func = cls.LookupFunction(tmp_name); | |
| 2701 } | |
| 2702 | |
| 2703 // Try to look up the function as a getter. | |
| 2704 if (func.IsNull()) { | |
| 2705 tmp_name = Field::GetterName(func_name); | |
| 2706 func = cls.LookupFunction(tmp_name); | |
| 2707 } | |
| 2708 | |
| 2709 // Special case for the unnamed constructor. We need to add a dot | |
| 2710 // at the end of the name. | |
| 2711 if (func.IsNull()) { | |
| 2712 const String& dot = String::Handle(String::NewSymbol(".")); | |
| 2713 tmp_name = String::Concat(func_name, dot); | |
| 2714 func = cls.LookupFunction(tmp_name); | |
| 2715 } | |
| 2716 | |
| 2717 if (func.IsNull()) { | |
| 2718 const String& cls_name = String::Handle(cls.Name()); | |
| 2719 fprintf(stderr, "---> Couldn't find method '%s' in class '%s'\n", | |
|
cshapiro
2012/06/28 23:57:47
No arrows allowed!
turnidge
2012/07/09 23:45:17
Done.
| |
| 2720 func_name.ToCString(), cls_name.ToCString()); | |
| 2721 } | |
| 2722 } else if (obj.IsLibrary()) { | |
| 2723 Library& lib = Library::Handle(isolate); | |
| 2724 lib ^= obj.raw(); | |
| 2725 func = lib.LookupFunctionAllowPrivate(func_name); | |
| 2726 | |
| 2727 // Check for functions with the external setter suffix '='. Make | |
|
cshapiro
2012/06/28 23:57:47
Ditto.
turnidge
2012/07/09 23:45:17
Done.
| |
| 2728 // sure to do this check after the regular lookup, so that we | |
| 2729 // don't interfere with operator lookups (like ==). | |
| 2730 if (func.IsNull() && HasExternalSetterSuffix(func_name)) { | |
| 2731 tmp_name = RemoveExternalSetterSuffix(func_name); | |
| 2732 tmp_name = Field::SetterName(tmp_name); | |
| 2733 func = lib.LookupFunctionAllowPrivate(tmp_name); | |
| 2734 } | |
| 2735 | |
| 2736 // Try to look up the function as a getter. | |
| 2737 if (func.IsNull()) { | |
| 2738 tmp_name = Field::GetterName(func_name); | |
| 2739 func = lib.LookupFunctionAllowPrivate(tmp_name); | |
| 2740 } | |
| 2741 } else { | |
| 2742 return Api::NewError( | |
| 2743 "%s expects argument 'target' to be a class or library.", | |
| 2744 CURRENT_FUNC); | |
| 2745 } | |
| 2746 | |
| 2747 #if defined(DEBUG) | |
| 2748 if (!func.IsNull()) { | |
| 2749 // We only provide access to a subset of function kinds. | |
| 2750 RawFunction::Kind func_kind = func.kind(); | |
| 2751 ASSERT(func_kind == RawFunction::kFunction || | |
| 2752 func_kind == RawFunction::kGetterFunction || | |
| 2753 func_kind == RawFunction::kSetterFunction || | |
| 2754 func_kind == RawFunction::kConstructor || | |
| 2755 func_kind == RawFunction::kAbstract); | |
| 2756 } | |
| 2757 #endif | |
| 2758 return Api::NewHandle(isolate, func.raw()); | |
| 2759 } | |
| 2760 | |
| 2761 | |
| 2762 DART_EXPORT bool Dart_IsFunction(Dart_Handle handle) { | |
| 2763 return Api::ClassId(handle) == kFunction; | |
| 2764 } | |
| 2765 | |
| 2766 | |
| 2767 DART_EXPORT Dart_Handle Dart_FunctionName(Dart_Handle function) { | |
| 2768 Isolate* isolate = Isolate::Current(); | |
| 2769 DARTSCOPE(isolate); | |
| 2770 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
| 2771 if (func.IsNull()) { | |
| 2772 RETURN_TYPE_ERROR(isolate, function, Function); | |
| 2773 } | |
| 2774 String& func_name = String::Handle(isolate); | |
| 2775 func_name = func.name(); | |
| 2776 bool is_setter = Field::IsSetterName(func_name); | |
| 2777 func_name = StripName(isolate, func_name); | |
| 2778 if (is_setter) { | |
| 2779 func_name = AddExternalSetterSuffix(func_name); | |
| 2780 } | |
| 2781 return Api::NewHandle(isolate, func_name.raw()); | |
| 2782 } | |
| 2783 | |
| 2784 | |
| 2785 DART_EXPORT Dart_Handle Dart_FunctionIsAbstract(Dart_Handle function, | |
| 2786 bool* is_abstract) { | |
|
cshapiro
2012/06/28 23:57:47
Null check.
turnidge
2012/07/09 23:45:17
Done.
| |
| 2787 Isolate* isolate = Isolate::Current(); | |
| 2788 DARTSCOPE(isolate); | |
| 2789 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
| 2790 if (func.IsNull()) { | |
| 2791 RETURN_TYPE_ERROR(isolate, function, Function); | |
| 2792 } | |
| 2793 *is_abstract = func.kind() == RawFunction::kAbstract; | |
|
cshapiro
2012/06/28 23:57:47
Stick parens around the inner double equal.
turnidge
2012/07/09 23:45:17
Done.
| |
| 2794 return Api::Success(isolate); | |
| 2795 } | |
| 2796 | |
| 2797 | |
| 2798 DART_EXPORT Dart_Handle Dart_FunctionIsStatic(Dart_Handle function, | |
| 2799 bool* is_static) { | |
|
cshapiro
2012/06/28 23:57:47
Null check.
turnidge
2012/07/09 23:45:17
Done.
| |
| 2800 Isolate* isolate = Isolate::Current(); | |
| 2801 DARTSCOPE(isolate); | |
| 2802 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
| 2803 if (func.IsNull()) { | |
| 2804 RETURN_TYPE_ERROR(isolate, function, Function); | |
| 2805 } | |
| 2806 *is_static = func.is_static(); | |
| 2807 return Api::Success(isolate); | |
| 2808 } | |
| 2809 | |
| 2810 | |
| 2811 DART_EXPORT Dart_Handle Dart_FunctionIsConstructor(Dart_Handle function, | |
| 2812 bool* is_constructor) { | |
|
cshapiro
2012/06/28 23:57:47
Null check.
turnidge
2012/07/09 23:45:17
Done.
| |
| 2813 Isolate* isolate = Isolate::Current(); | |
| 2814 DARTSCOPE(isolate); | |
| 2815 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
| 2816 if (func.IsNull()) { | |
| 2817 RETURN_TYPE_ERROR(isolate, function, Function); | |
| 2818 } | |
| 2819 *is_constructor = func.kind() == RawFunction::kConstructor; | |
| 2820 return Api::Success(isolate); | |
| 2821 } | |
| 2822 | |
| 2823 | |
| 2824 DART_EXPORT Dart_Handle Dart_FunctionIsGetter(Dart_Handle function, | |
| 2825 bool* is_getter) { | |
|
cshapiro
2012/06/28 23:57:47
Null check.
turnidge
2012/07/09 23:45:17
Done.
| |
| 2826 Isolate* isolate = Isolate::Current(); | |
| 2827 DARTSCOPE(isolate); | |
| 2828 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
| 2829 if (func.IsNull()) { | |
| 2830 RETURN_TYPE_ERROR(isolate, function, Function); | |
| 2831 } | |
| 2832 // TODO(turnidge): It would be nice if I could just use func.kind() | |
| 2833 // to check for a getter function here, but unfortunately the only | |
| 2834 // way to distinguish abstract getter functions is to use the name | |
| 2835 // itself. Consider adding a RawFunction::kAbstractGetter type. | |
| 2836 const String& func_name = String::Handle(isolate, func.name()); | |
| 2837 *is_getter = Field::IsGetterName(func_name); | |
| 2838 | |
| 2839 return Api::Success(isolate); | |
| 2840 } | |
| 2841 | |
| 2842 | |
| 2843 DART_EXPORT Dart_Handle Dart_FunctionIsSetter(Dart_Handle function, | |
| 2844 bool* is_setter) { | |
|
cshapiro
2012/06/28 23:57:47
Null check.
turnidge
2012/07/09 23:45:17
Done.
| |
| 2845 Isolate* isolate = Isolate::Current(); | |
| 2846 DARTSCOPE(isolate); | |
| 2847 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
| 2848 if (func.IsNull()) { | |
| 2849 RETURN_TYPE_ERROR(isolate, function, Function); | |
| 2850 } | |
| 2851 // TODO(turnidge): It would be nice if I could just use func.kind() | |
| 2852 // to check for a setter function here, but unfortunately the only | |
| 2853 // way to distinguish abstract setter functions is to use the name | |
| 2854 // itself. Consider adding a RawFunction::kAbstractSetter type. | |
| 2855 const String& func_name = String::Handle(isolate, func.name()); | |
| 2856 *is_setter = Field::IsSetterName(func_name); | |
| 2857 | |
| 2858 return Api::Success(isolate); | |
| 2859 } | |
| 2860 | |
| 2861 | |
| 2862 DART_EXPORT Dart_Handle Dart_GetVariableNames(Dart_Handle target) { | |
| 2863 Isolate* isolate = Isolate::Current(); | |
| 2864 DARTSCOPE(isolate); | |
| 2865 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); | |
| 2866 if (obj.IsError()) { | |
| 2867 return target; | |
| 2868 } | |
| 2869 | |
| 2870 const GrowableObjectArray& names = | |
| 2871 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); | |
| 2872 Field& field = Field::Handle(isolate); | |
| 2873 String& name = String::Handle(isolate); | |
| 2874 | |
| 2875 if (obj.IsClass()) { | |
| 2876 Class& cls = Class::Handle(isolate); | |
| 2877 cls ^= obj.raw(); | |
| 2878 const Array& field_array = Array::Handle(cls.fields()); | |
| 2879 | |
| 2880 // Some special types like 'Dynamic' have a null fields list. | |
|
cshapiro
2012/06/28 23:57:47
Maybe fix this at the source if it is not too much
turnidge
2012/07/09 23:45:17
Investigated. Since Dynamic is allocated in the v
| |
| 2881 if (!field_array.IsNull()) { | |
| 2882 for (intptr_t i = 0; i < field_array.Length(); ++i) { | |
| 2883 field ^= field_array.At(i); | |
| 2884 name = field.name(); | |
| 2885 name = StripName(isolate, name); | |
| 2886 names.Add(name); | |
| 2887 } | |
| 2888 } | |
| 2889 } else if (obj.IsLibrary()) { | |
| 2890 Library& lib = Library::Handle(isolate); | |
| 2891 lib ^= obj.raw(); | |
| 2892 DictionaryIterator it(lib); | |
| 2893 Object& obj = Object::Handle(isolate); | |
| 2894 while (it.HasNext()) { | |
| 2895 obj = it.GetNext(); | |
| 2896 if (obj.IsField()) { | |
| 2897 field ^= obj.raw(); | |
| 2898 name = field.name(); | |
| 2899 name = StripName(isolate, name); | |
| 2900 names.Add(name); | |
| 2901 } | |
| 2902 } | |
| 2903 } else { | |
| 2904 return Api::NewError( | |
| 2905 "%s expects argument 'target' to be a class or library.", | |
| 2906 CURRENT_FUNC); | |
| 2907 } | |
| 2908 return Api::NewHandle(isolate, Array::MakeArray(names)); | |
| 2909 } | |
| 2910 | |
| 2911 | |
| 2912 DART_EXPORT Dart_Handle Dart_LookupVariable(Dart_Handle target, | |
| 2913 Dart_Handle variable_name) { | |
| 2914 Isolate* isolate = Isolate::Current(); | |
| 2915 DARTSCOPE(isolate); | |
| 2916 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); | |
| 2917 if (obj.IsError()) { | |
| 2918 return target; | |
| 2919 } | |
| 2920 const String& var_name = Api::UnwrapStringHandle(isolate, variable_name); | |
| 2921 if (var_name.IsNull()) { | |
| 2922 RETURN_TYPE_ERROR(isolate, variable_name, String); | |
| 2923 } | |
| 2924 if (obj.IsClass()) { | |
| 2925 Class& cls = Class::Handle(isolate); | |
| 2926 cls ^= obj.raw(); | |
| 2927 return Api::NewHandle(isolate, cls.LookupField(var_name)); | |
|
cshapiro
2012/06/28 23:57:47
If you have a return, why not get rid of the else
turnidge
2012/07/09 23:45:17
Done.
| |
| 2928 } else if (obj.IsLibrary()) { | |
| 2929 Library& lib = Library::Handle(isolate); | |
| 2930 lib ^= obj.raw(); | |
| 2931 return Api::NewHandle(isolate, lib.LookupFieldAllowPrivate(var_name)); | |
| 2932 } else { | |
| 2933 return Api::NewError( | |
| 2934 "%s expects argument 'target' to be a class or library.", | |
| 2935 CURRENT_FUNC); | |
| 2936 } | |
| 2937 } | |
| 2938 | |
| 2939 | |
| 2940 DART_EXPORT bool Dart_IsVariable(Dart_Handle handle) { | |
| 2941 return Api::ClassId(handle) == kField; | |
|
cshapiro
2012/06/28 23:57:47
Maybe make sure this is safe?
turnidge
2012/07/09 23:45:17
We do this a lot.
| |
| 2942 } | |
| 2943 | |
| 2944 | |
| 2945 DART_EXPORT Dart_Handle Dart_VariableName(Dart_Handle variable) { | |
| 2946 Isolate* isolate = Isolate::Current(); | |
| 2947 DARTSCOPE(isolate); | |
| 2948 const Field& var = Api::UnwrapFieldHandle(isolate, variable); | |
| 2949 if (var.IsNull()) { | |
| 2950 RETURN_TYPE_ERROR(isolate, variable, Field); | |
| 2951 } | |
| 2952 const String& var_name = String::Handle(var.name()); | |
| 2953 return Api::NewHandle(isolate, StripName(isolate, var_name)); | |
| 2954 } | |
| 2955 | |
| 2956 | |
| 2957 DART_EXPORT Dart_Handle Dart_VariableIsStatic(Dart_Handle variable, | |
| 2958 bool* is_static) { | |
|
cshapiro
2012/06/28 23:57:47
Do we normally do null check for out variables? A
turnidge
2012/07/09 23:45:17
Done.
| |
| 2959 Isolate* isolate = Isolate::Current(); | |
| 2960 DARTSCOPE(isolate); | |
| 2961 const Field& var = Api::UnwrapFieldHandle(isolate, variable); | |
| 2962 if (var.IsNull()) { | |
| 2963 RETURN_TYPE_ERROR(isolate, variable, Field); | |
| 2964 } | |
| 2965 *is_static = var.is_static(); | |
| 2966 return Api::Success(isolate); | |
| 2967 } | |
| 2968 | |
| 2969 | |
| 2970 DART_EXPORT Dart_Handle Dart_VariableIsFinal(Dart_Handle variable, | |
| 2971 bool* is_final) { | |
|
cshapiro
2012/06/28 23:57:47
Null check for is_final too.
turnidge
2012/07/09 23:45:17
Done.
| |
| 2972 Isolate* isolate = Isolate::Current(); | |
| 2973 DARTSCOPE(isolate); | |
| 2974 const Field& var = Api::UnwrapFieldHandle(isolate, variable); | |
| 2975 if (var.IsNull()) { | |
| 2976 RETURN_TYPE_ERROR(isolate, variable, Field); | |
| 2977 } | |
| 2978 *is_final = var.is_final(); | |
| 2979 return Api::Success(isolate); | |
| 2980 } | |
| 2981 | |
| 2525 // --- Constructors, Methods, and Fields --- | 2982 // --- Constructors, Methods, and Fields --- |
| 2526 | 2983 |
| 2527 | 2984 |
| 2528 static RawObject* ResolveConstructor(const char* current_func, | 2985 static RawObject* ResolveConstructor(const char* current_func, |
| 2529 const Class& cls, | 2986 const Class& cls, |
| 2530 const String& class_name, | 2987 const String& class_name, |
| 2531 const String& dotted_name, | 2988 const String& dotted_name, |
| 2532 int num_args) { | 2989 int num_args) { |
| 2533 // The constructor must be present in the interface. | 2990 // The constructor must be present in the interface. |
| 2534 String& constr_name = String::Handle(String::Concat(class_name, dotted_name)); | 2991 String& constr_name = String::Handle(String::Concat(class_name, dotted_name)); |
| (...skipping 957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3492 RETURN_TYPE_ERROR(isolate, library, Library); | 3949 RETURN_TYPE_ERROR(isolate, library, Library); |
| 3493 } | 3950 } |
| 3494 | 3951 |
| 3495 const GrowableObjectArray& names = | 3952 const GrowableObjectArray& names = |
| 3496 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); | 3953 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); |
| 3497 ClassDictionaryIterator it(lib); | 3954 ClassDictionaryIterator it(lib); |
| 3498 Class& cls = Class::Handle(); | 3955 Class& cls = Class::Handle(); |
| 3499 String& name = String::Handle(); | 3956 String& name = String::Handle(); |
| 3500 while (it.HasNext()) { | 3957 while (it.HasNext()) { |
| 3501 cls = it.GetNextClass(); | 3958 cls = it.GetNextClass(); |
| 3502 name = cls.Name(); | 3959 // For now we suppress the signature classes of closures. |
| 3503 names.Add(name); | 3960 // |
| 3961 // TODO(turnidge): Add this to the unit test. | |
| 3962 const Function& signature_func = Function::Handle(cls.signature_function()); | |
| 3963 if (signature_func.IsNull()) { | |
| 3964 name = cls.Name(); | |
| 3965 name = StripName(isolate, name); | |
| 3966 names.Add(name); | |
| 3967 } | |
| 3504 } | 3968 } |
| 3505 return Api::NewHandle(isolate, Array::MakeArray(names)); | 3969 return Api::NewHandle(isolate, Array::MakeArray(names)); |
| 3506 } | 3970 } |
| 3507 | 3971 |
| 3508 | 3972 |
| 3509 DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url) { | 3973 DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url) { |
| 3510 Isolate* isolate = Isolate::Current(); | 3974 Isolate* isolate = Isolate::Current(); |
| 3511 DARTSCOPE(isolate); | 3975 DARTSCOPE(isolate); |
| 3512 const String& url_str = Api::UnwrapStringHandle(isolate, url); | 3976 const String& url_str = Api::UnwrapStringHandle(isolate, url); |
| 3513 if (url_str.IsNull()) { | 3977 if (url_str.IsNull()) { |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3656 *buffer_size = 0; | 4120 *buffer_size = 0; |
| 3657 } | 4121 } |
| 3658 } | 4122 } |
| 3659 | 4123 |
| 3660 | 4124 |
| 3661 DART_EXPORT void Dart_InitFlowGraphPrinting(FileWriterFunction function) { | 4125 DART_EXPORT void Dart_InitFlowGraphPrinting(FileWriterFunction function) { |
| 3662 Dart::set_flow_graph_writer(function); | 4126 Dart::set_flow_graph_writer(function); |
| 3663 } | 4127 } |
| 3664 | 4128 |
| 3665 } // namespace dart | 4129 } // namespace dart |
| OLD | NEW |