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 |