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 1091 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1102 DARTSCOPE(isolate); | 1102 DARTSCOPE(isolate); |
1103 Library& isolate_lib = Library::Handle(isolate, Library::IsolateLibrary()); | 1103 Library& isolate_lib = Library::Handle(isolate, Library::IsolateLibrary()); |
1104 ASSERT(!isolate_lib.IsNull()); | 1104 ASSERT(!isolate_lib.IsNull()); |
1105 const String& public_class_name = | 1105 const String& public_class_name = |
1106 String::Handle(isolate, String::New("_ReceivePortImpl")); | 1106 String::Handle(isolate, String::New("_ReceivePortImpl")); |
1107 const String& class_name = | 1107 const String& class_name = |
1108 String::Handle(isolate, isolate_lib.PrivateName(public_class_name)); | 1108 String::Handle(isolate, isolate_lib.PrivateName(public_class_name)); |
1109 const String& function_name = | 1109 const String& function_name = |
1110 String::Handle(isolate, Symbols::New("_get_or_create")); | 1110 String::Handle(isolate, Symbols::New("_get_or_create")); |
1111 const int kNumArguments = 1; | 1111 const int kNumArguments = 1; |
1112 const Array& kNoArgumentNames = Array::Handle(isolate); | 1112 const Array& kNoArgNames = Array::Handle(isolate); |
1113 const Function& function = Function::Handle( | 1113 const Function& function = Function::Handle( |
1114 isolate, | 1114 isolate, |
1115 Resolver::ResolveStatic(isolate_lib, | 1115 Resolver::ResolveStatic(isolate_lib, |
1116 class_name, | 1116 class_name, |
1117 function_name, | 1117 function_name, |
1118 kNumArguments, | 1118 kNumArguments, |
1119 kNoArgumentNames, | 1119 kNoArgNames, |
1120 Resolver::kIsQualified)); | 1120 Resolver::kIsQualified)); |
1121 GrowableArray<const Object*> arguments(kNumArguments); | 1121 const Array& args = Array::Handle(isolate, Array::New(kNumArguments)); |
1122 arguments.Add(&Integer::Handle(isolate, Integer::New(port_id))); | 1122 args.SetAt(0, Integer::Handle(isolate, Integer::New(port_id))); |
1123 return Api::NewHandle( | 1123 return Api::NewHandle(isolate, DartEntry::InvokeStatic(function, args)); |
1124 isolate, DartEntry::InvokeStatic(function, arguments, kNoArgumentNames)); | |
1125 } | 1124 } |
1126 | 1125 |
1127 | 1126 |
1128 DART_EXPORT Dart_Port Dart_GetMainPortId() { | 1127 DART_EXPORT Dart_Port Dart_GetMainPortId() { |
1129 Isolate* isolate = Isolate::Current(); | 1128 Isolate* isolate = Isolate::Current(); |
1130 CHECK_ISOLATE(isolate); | 1129 CHECK_ISOLATE(isolate); |
1131 return isolate->main_port(); | 1130 return isolate->main_port(); |
1132 } | 1131 } |
1133 | 1132 |
1134 // --- Scopes ---- | 1133 // --- Scopes ---- |
(...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1890 return Api::NewError("Object does not implement the List interface"); | 1889 return Api::NewError("Object does not implement the List interface"); |
1891 } | 1890 } |
1892 String& name = String::Handle(isolate, Symbols::Length()); | 1891 String& name = String::Handle(isolate, Symbols::Length()); |
1893 name = Field::GetterName(name); | 1892 name = Field::GetterName(name); |
1894 const Function& function = | 1893 const Function& function = |
1895 Function::Handle(isolate, Resolver::ResolveDynamic(instance, name, 1, 0)); | 1894 Function::Handle(isolate, Resolver::ResolveDynamic(instance, name, 1, 0)); |
1896 if (function.IsNull()) { | 1895 if (function.IsNull()) { |
1897 return Api::NewError("List object does not have a 'length' field."); | 1896 return Api::NewError("List object does not have a 'length' field."); |
1898 } | 1897 } |
1899 | 1898 |
1900 GrowableArray<const Object*> args(0); | 1899 const int kNumArgs = 1; |
1901 const Array& kNoArgumentNames = Array::Handle(isolate); | 1900 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); |
1902 const Object& retval = Object::Handle( | 1901 args.SetAt(0, instance); // Set up the receiver as the first argument. |
1903 isolate, | 1902 const Object& retval = |
1904 DartEntry::InvokeDynamic(instance, function, args, kNoArgumentNames)); | 1903 Object::Handle(isolate, DartEntry::InvokeDynamic(function, args)); |
1905 if (retval.IsSmi()) { | 1904 if (retval.IsSmi()) { |
1906 *len = Smi::Cast(retval).Value(); | 1905 *len = Smi::Cast(retval).Value(); |
1907 return Api::Success(isolate); | 1906 return Api::Success(isolate); |
1908 } else if (retval.IsMint() || retval.IsBigint()) { | 1907 } else if (retval.IsMint() || retval.IsBigint()) { |
1909 if (retval.IsMint()) { | 1908 if (retval.IsMint()) { |
1910 int64_t mint_value = Mint::Cast(retval).value(); | 1909 int64_t mint_value = Mint::Cast(retval).value(); |
1911 if (mint_value >= kIntptrMin && mint_value <= kIntptrMax) { | 1910 if (mint_value >= kIntptrMin && mint_value <= kIntptrMax) { |
1912 *len = static_cast<intptr_t>(mint_value); | 1911 *len = static_cast<intptr_t>(mint_value); |
1913 } | 1912 } |
1914 } else { | 1913 } else { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1955 const Instance& instance = | 1954 const Instance& instance = |
1956 Instance::Handle(isolate, GetListInstance(isolate, obj)); | 1955 Instance::Handle(isolate, GetListInstance(isolate, obj)); |
1957 if (!instance.IsNull()) { | 1956 if (!instance.IsNull()) { |
1958 const Function& function = Function::Handle( | 1957 const Function& function = Function::Handle( |
1959 isolate, | 1958 isolate, |
1960 Resolver::ResolveDynamic(instance, | 1959 Resolver::ResolveDynamic(instance, |
1961 Symbols::IndexTokenHandle(), | 1960 Symbols::IndexTokenHandle(), |
1962 2, | 1961 2, |
1963 0)); | 1962 0)); |
1964 if (!function.IsNull()) { | 1963 if (!function.IsNull()) { |
1965 GrowableArray<const Object*> args(1); | 1964 const int kNumArgs = 2; |
1966 Integer& indexobj = Integer::Handle(isolate); | 1965 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); |
1967 indexobj = Integer::New(index); | 1966 const Integer& indexobj = Integer::Handle(isolate, Integer::New(index)); |
1968 args.Add(&indexobj); | 1967 args.SetAt(0, instance); |
1969 const Array& kNoArgumentNames = Array::Handle(isolate); | 1968 args.SetAt(1, indexobj); |
1970 return Api::NewHandle(isolate, DartEntry::InvokeDynamic( | 1969 return Api::NewHandle(isolate, DartEntry::InvokeDynamic(function, |
1971 instance, function, args, kNoArgumentNames)); | 1970 args)); |
1972 } | 1971 } |
1973 } | 1972 } |
1974 return Api::NewError("Object does not implement the 'List' interface"); | 1973 return Api::NewError("Object does not implement the 'List' interface"); |
1975 } | 1974 } |
1976 } | 1975 } |
1977 | 1976 |
1978 | 1977 |
1979 #define SET_LIST_ELEMENT(isolate, type, obj, index, value) \ | 1978 #define SET_LIST_ELEMENT(isolate, type, obj, index, value) \ |
1980 const type& array = type::Cast(obj); \ | 1979 const type& array = type::Cast(obj); \ |
1981 const Object& value_obj = Object::Handle(isolate, Api::UnwrapHandle(value)); \ | 1980 const Object& value_obj = Object::Handle(isolate, Api::UnwrapHandle(value)); \ |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2016 3, | 2015 3, |
2017 0)); | 2016 0)); |
2018 if (!function.IsNull()) { | 2017 if (!function.IsNull()) { |
2019 const Integer& index_obj = | 2018 const Integer& index_obj = |
2020 Integer::Handle(isolate, Integer::New(index)); | 2019 Integer::Handle(isolate, Integer::New(index)); |
2021 const Object& value_obj = | 2020 const Object& value_obj = |
2022 Object::Handle(isolate, Api::UnwrapHandle(value)); | 2021 Object::Handle(isolate, Api::UnwrapHandle(value)); |
2023 if (!value_obj.IsNull() && !value_obj.IsInstance()) { | 2022 if (!value_obj.IsNull() && !value_obj.IsInstance()) { |
2024 RETURN_TYPE_ERROR(isolate, value, Instance); | 2023 RETURN_TYPE_ERROR(isolate, value, Instance); |
2025 } | 2024 } |
2026 GrowableArray<const Object*> args(2); | 2025 const intptr_t kNumArgs = 3; |
2027 args.Add(&index_obj); | 2026 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); |
2028 args.Add(&value_obj); | 2027 args.SetAt(0, instance); |
2029 const Array& kNoArgumentNames = Array::Handle(isolate); | 2028 args.SetAt(1, index_obj); |
2030 return Api::NewHandle(isolate, DartEntry::InvokeDynamic( | 2029 args.SetAt(2, value_obj); |
2031 instance, function, args, kNoArgumentNames)); | 2030 return Api::NewHandle(isolate, DartEntry::InvokeDynamic(function, |
| 2031 args)); |
2032 } | 2032 } |
2033 } | 2033 } |
2034 return Api::NewError("Object does not implement the 'List' interface"); | 2034 return Api::NewError("Object does not implement the 'List' interface"); |
2035 } | 2035 } |
2036 } | 2036 } |
2037 | 2037 |
2038 | 2038 |
2039 // TODO(hpayer): value should always be smaller then 0xff. Add error handling. | 2039 // TODO(hpayer): value should always be smaller then 0xff. Add error handling. |
2040 #define GET_LIST_ELEMENT_AS_BYTES(isolate, type, obj, native_array, offset, \ | 2040 #define GET_LIST_ELEMENT_AS_BYTES(isolate, type, obj, native_array, offset, \ |
2041 length) \ | 2041 length) \ |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2096 if (!instance.IsNull()) { | 2096 if (!instance.IsNull()) { |
2097 const Function& function = Function::Handle( | 2097 const Function& function = Function::Handle( |
2098 isolate, | 2098 isolate, |
2099 Resolver::ResolveDynamic(instance, | 2099 Resolver::ResolveDynamic(instance, |
2100 Symbols::IndexTokenHandle(), | 2100 Symbols::IndexTokenHandle(), |
2101 2, | 2101 2, |
2102 0)); | 2102 0)); |
2103 if (!function.IsNull()) { | 2103 if (!function.IsNull()) { |
2104 Object& result = Object::Handle(isolate); | 2104 Object& result = Object::Handle(isolate); |
2105 Integer& intobj = Integer::Handle(isolate); | 2105 Integer& intobj = Integer::Handle(isolate); |
| 2106 const int kNumArgs = 2; |
| 2107 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); |
| 2108 args.SetAt(0, instance); // Set up the receiver as the first argument. |
2106 for (int i = 0; i < length; i++) { | 2109 for (int i = 0; i < length; i++) { |
2107 intobj = Integer::New(offset + i); | 2110 intobj = Integer::New(offset + i); |
2108 GrowableArray<const Object*> args(1); | 2111 args.SetAt(1, intobj); |
2109 args.Add(&intobj); | 2112 result = DartEntry::InvokeDynamic(function, args); |
2110 const Array& kNoArgumentNames = Array::Handle(isolate); | |
2111 result = DartEntry::InvokeDynamic( | |
2112 instance, function, args, kNoArgumentNames); | |
2113 if (result.IsError()) { | 2113 if (result.IsError()) { |
2114 return Api::NewHandle(isolate, result.raw()); | 2114 return Api::NewHandle(isolate, result.raw()); |
2115 } | 2115 } |
2116 if (!result.IsInteger()) { | 2116 if (!result.IsInteger()) { |
2117 return Api::NewError("%s expects the argument 'list' to be " | 2117 return Api::NewError("%s expects the argument 'list' to be " |
2118 "a List of int", CURRENT_FUNC); | 2118 "a List of int", CURRENT_FUNC); |
2119 } | 2119 } |
2120 const Integer& integer_result = Integer::Cast(result); | 2120 const Integer& integer_result = Integer::Cast(result); |
2121 ASSERT(integer_result.AsInt64Value() <= 0xff); | 2121 ASSERT(integer_result.AsInt64Value() <= 0xff); |
2122 // TODO(hpayer): value should always be smaller then 0xff. Add error | 2122 // TODO(hpayer): value should always be smaller then 0xff. Add error |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2187 if (!instance.IsNull()) { | 2187 if (!instance.IsNull()) { |
2188 const Function& function = Function::Handle( | 2188 const Function& function = Function::Handle( |
2189 isolate, | 2189 isolate, |
2190 Resolver::ResolveDynamic(instance, | 2190 Resolver::ResolveDynamic(instance, |
2191 Symbols::AssignIndexTokenHandle(), | 2191 Symbols::AssignIndexTokenHandle(), |
2192 3, | 2192 3, |
2193 0)); | 2193 0)); |
2194 if (!function.IsNull()) { | 2194 if (!function.IsNull()) { |
2195 Integer& indexobj = Integer::Handle(isolate); | 2195 Integer& indexobj = Integer::Handle(isolate); |
2196 Integer& valueobj = Integer::Handle(isolate); | 2196 Integer& valueobj = Integer::Handle(isolate); |
| 2197 const int kNumArgs = 3; |
| 2198 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); |
| 2199 args.SetAt(0, instance); // Set up the receiver as the first argument. |
2197 for (int i = 0; i < length; i++) { | 2200 for (int i = 0; i < length; i++) { |
2198 indexobj = Integer::New(offset + i); | 2201 indexobj = Integer::New(offset + i); |
2199 valueobj = Integer::New(native_array[i]); | 2202 valueobj = Integer::New(native_array[i]); |
2200 GrowableArray<const Object*> args(2); | 2203 args.SetAt(1, indexobj); |
2201 args.Add(&indexobj); | 2204 args.SetAt(2, valueobj); |
2202 args.Add(&valueobj); | |
2203 const Array& kNoArgumentNames = Array::Handle(isolate); | |
2204 const Object& result = Object::Handle( | 2205 const Object& result = Object::Handle( |
2205 isolate, | 2206 isolate, DartEntry::InvokeDynamic(function, args)); |
2206 DartEntry::InvokeDynamic( | |
2207 instance, function, args, kNoArgumentNames)); | |
2208 if (result.IsError()) { | 2207 if (result.IsError()) { |
2209 return Api::NewHandle(isolate, result.raw()); | 2208 return Api::NewHandle(isolate, result.raw()); |
2210 } | 2209 } |
2211 } | 2210 } |
2212 return Api::Success(isolate); | 2211 return Api::Success(isolate); |
2213 } | 2212 } |
2214 } | 2213 } |
2215 return Api::NewError("Object does not implement the 'List' interface"); | 2214 return Api::NewError("Object does not implement the 'List' interface"); |
2216 } | 2215 } |
2217 } | 2216 } |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2500 if (closure_obj.IsNull() || !closure_obj.IsCallable(NULL, NULL)) { | 2499 if (closure_obj.IsNull() || !closure_obj.IsCallable(NULL, NULL)) { |
2501 RETURN_TYPE_ERROR(isolate, closure, Instance); | 2500 RETURN_TYPE_ERROR(isolate, closure, Instance); |
2502 } | 2501 } |
2503 if (number_of_arguments < 0) { | 2502 if (number_of_arguments < 0) { |
2504 return Api::NewError( | 2503 return Api::NewError( |
2505 "%s expects argument 'number_of_arguments' to be non-negative.", | 2504 "%s expects argument 'number_of_arguments' to be non-negative.", |
2506 CURRENT_FUNC); | 2505 CURRENT_FUNC); |
2507 } | 2506 } |
2508 ASSERT(ClassFinalizer::AllClassesFinalized()); | 2507 ASSERT(ClassFinalizer::AllClassesFinalized()); |
2509 | 2508 |
2510 // Now try to invoke the closure. | 2509 // Set up arguments to include the closure as the first argument. |
2511 GrowableArray<const Object*> dart_arguments(number_of_arguments); | 2510 const Array& args = Array::Handle(isolate, |
| 2511 Array::New(number_of_arguments + 1)); |
| 2512 Object& obj = Object::Handle(isolate); |
| 2513 args.SetAt(0, closure_obj); |
2512 for (int i = 0; i < number_of_arguments; i++) { | 2514 for (int i = 0; i < number_of_arguments; i++) { |
2513 const Object& arg = | 2515 obj = Api::UnwrapHandle(arguments[i]); |
2514 Object::Handle(isolate, Api::UnwrapHandle(arguments[i])); | 2516 if (!obj.IsNull() && !obj.IsInstance()) { |
2515 if (!arg.IsNull() && !arg.IsInstance()) { | |
2516 RETURN_TYPE_ERROR(isolate, arguments[i], Instance); | 2517 RETURN_TYPE_ERROR(isolate, arguments[i], Instance); |
2517 } | 2518 } |
2518 dart_arguments.Add(&arg); | 2519 args.SetAt(i + 1, obj); |
2519 } | 2520 } |
2520 const Array& kNoArgumentNames = Array::Handle(isolate); | 2521 // Now try to invoke the closure. |
2521 return Api::NewHandle( | 2522 return Api::NewHandle(isolate, DartEntry::InvokeClosure(closure_obj, args)); |
2522 isolate, | |
2523 DartEntry::InvokeClosure(closure_obj, dart_arguments, kNoArgumentNames)); | |
2524 } | 2523 } |
2525 | 2524 |
2526 | 2525 |
2527 // --- Classes --- | 2526 // --- Classes --- |
2528 | 2527 |
2529 | 2528 |
2530 DART_EXPORT bool Dart_IsClass(Dart_Handle handle) { | 2529 DART_EXPORT bool Dart_IsClass(Dart_Handle handle) { |
2531 Isolate* isolate = Isolate::Current(); | 2530 Isolate* isolate = Isolate::Current(); |
2532 DARTSCOPE(isolate); | 2531 DARTSCOPE(isolate); |
2533 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle)); | 2532 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle)); |
(...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3387 Function& constructor = Function::Handle(isolate); | 3386 Function& constructor = Function::Handle(isolate); |
3388 constructor ^= result.raw(); | 3387 constructor ^= result.raw(); |
3389 | 3388 |
3390 Instance& new_object = Instance::Handle(isolate); | 3389 Instance& new_object = Instance::Handle(isolate); |
3391 if (constructor.IsConstructor()) { | 3390 if (constructor.IsConstructor()) { |
3392 // Create the new object. | 3391 // Create the new object. |
3393 new_object = Instance::New(cls); | 3392 new_object = Instance::New(cls); |
3394 } | 3393 } |
3395 | 3394 |
3396 // Create the argument list. | 3395 // Create the argument list. |
| 3396 intptr_t arg_index = 0; |
3397 int extra_args = (constructor.IsConstructor() ? 2 : 1); | 3397 int extra_args = (constructor.IsConstructor() ? 2 : 1); |
3398 GrowableArray<const Object*> args(number_of_arguments + extra_args); | 3398 const Array& args = |
| 3399 Array::Handle(isolate, Array::New(number_of_arguments + extra_args)); |
3399 if (constructor.IsConstructor()) { | 3400 if (constructor.IsConstructor()) { |
3400 // Constructors get the uninitialized object and a constructor phase. | 3401 // Constructors get the uninitialized object and a constructor phase. |
3401 args.Add(&new_object); | 3402 args.SetAt(arg_index++, new_object); |
3402 args.Add(&Smi::Handle(isolate, Smi::New(Function::kCtorPhaseAll))); | 3403 args.SetAt(arg_index++, |
| 3404 Smi::Handle(isolate, Smi::New(Function::kCtorPhaseAll))); |
3403 } else { | 3405 } else { |
3404 // Factories get type arguments. | 3406 // Factories get type arguments. |
3405 args.Add(&TypeArguments::Handle(isolate)); | 3407 args.SetAt(arg_index++, TypeArguments::Handle(isolate)); |
3406 } | 3408 } |
| 3409 Object& argument = Object::Handle(isolate); |
3407 for (int i = 0; i < number_of_arguments; i++) { | 3410 for (int i = 0; i < number_of_arguments; i++) { |
3408 const Object& arg = | 3411 argument = Api::UnwrapHandle(arguments[i]); |
3409 Object::Handle(isolate, Api::UnwrapHandle(arguments[i])); | 3412 if (!argument.IsNull() && !argument.IsInstance()) { |
3410 if (!arg.IsNull() && !arg.IsInstance()) { | 3413 if (argument.IsError()) { |
3411 if (arg.IsError()) { | 3414 return Api::NewHandle(isolate, argument.raw()); |
3412 return Api::NewHandle(isolate, arg.raw()); | |
3413 } else { | 3415 } else { |
3414 return Api::NewError( | 3416 return Api::NewError( |
3415 "%s expects arguments[%d] to be an Instance handle.", | 3417 "%s expects arguments[%d] to be an Instance handle.", |
3416 CURRENT_FUNC, i); | 3418 CURRENT_FUNC, i); |
3417 } | 3419 } |
3418 } | 3420 } |
3419 args.Add(&arg); | 3421 args.SetAt(arg_index++, argument); |
3420 } | 3422 } |
3421 | 3423 |
3422 // Invoke the constructor and return the new object. | 3424 // Invoke the constructor and return the new object. |
3423 const Array& kNoArgNames = Array::Handle(isolate); | 3425 result = DartEntry::InvokeStatic(constructor, args); |
3424 result = DartEntry::InvokeStatic(constructor, args, kNoArgNames); | |
3425 if (result.IsError()) { | 3426 if (result.IsError()) { |
3426 return Api::NewHandle(isolate, result.raw()); | 3427 return Api::NewHandle(isolate, result.raw()); |
3427 } | 3428 } |
3428 if (constructor.IsConstructor()) { | 3429 if (constructor.IsConstructor()) { |
3429 ASSERT(result.IsNull()); | 3430 ASSERT(result.IsNull()); |
3430 } else { | 3431 } else { |
3431 ASSERT(result.IsNull() || result.IsInstance()); | 3432 ASSERT(result.IsNull() || result.IsInstance()); |
3432 new_object ^= result.raw(); | 3433 new_object ^= result.raw(); |
3433 } | 3434 } |
3434 return Api::NewHandle(isolate, new_object.raw()); | 3435 return Api::NewHandle(isolate, new_object.raw()); |
3435 } | 3436 } |
3436 | 3437 |
3437 | 3438 |
3438 DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target, | 3439 DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target, |
3439 Dart_Handle name, | 3440 Dart_Handle name, |
3440 int number_of_arguments, | 3441 int number_of_arguments, |
3441 Dart_Handle* arguments) { | 3442 Dart_Handle* arguments) { |
3442 Isolate* isolate = Isolate::Current(); | 3443 Isolate* isolate = Isolate::Current(); |
3443 DARTSCOPE(isolate); | 3444 DARTSCOPE(isolate); |
3444 | 3445 |
3445 const String& function_name = Api::UnwrapStringHandle(isolate, name); | 3446 const String& function_name = Api::UnwrapStringHandle(isolate, name); |
3446 if (function_name.IsNull()) { | 3447 if (function_name.IsNull()) { |
3447 RETURN_TYPE_ERROR(isolate, name, String); | 3448 RETURN_TYPE_ERROR(isolate, name, String); |
3448 } | 3449 } |
3449 if (number_of_arguments < 0) { | 3450 if (number_of_arguments < 0) { |
3450 return Api::NewError( | 3451 return Api::NewError( |
3451 "%s expects argument 'number_of_arguments' to be non-negative.", | 3452 "%s expects argument 'number_of_arguments' to be non-negative.", |
3452 CURRENT_FUNC); | 3453 CURRENT_FUNC); |
3453 } | 3454 } |
| 3455 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); |
| 3456 if (obj.IsError()) { |
| 3457 return target; |
| 3458 } |
3454 | 3459 |
3455 // Check for malformed arguments in the arguments list. | 3460 // Check for malformed arguments in the arguments list. |
3456 GrowableArray<const Object*> args(number_of_arguments); | 3461 intptr_t num_receiver = (obj.IsNull() || obj.IsInstance()) ? 1 : 0; |
| 3462 const Array& args = |
| 3463 Array::Handle(isolate, Array::New(number_of_arguments + num_receiver)); |
| 3464 Object& arg = Object::Handle(isolate); |
3457 for (int i = 0; i < number_of_arguments; i++) { | 3465 for (int i = 0; i < number_of_arguments; i++) { |
3458 const Object& arg = | 3466 arg = Api::UnwrapHandle(arguments[i]); |
3459 Object::Handle(isolate, Api::UnwrapHandle(arguments[i])); | |
3460 if (!arg.IsNull() && !arg.IsInstance()) { | 3467 if (!arg.IsNull() && !arg.IsInstance()) { |
3461 if (arg.IsError()) { | 3468 if (arg.IsError()) { |
3462 return Api::NewHandle(isolate, arg.raw()); | 3469 return Api::NewHandle(isolate, arg.raw()); |
3463 } else { | 3470 } else { |
3464 return Api::NewError( | 3471 return Api::NewError( |
3465 "%s expects arguments[%d] to be an Instance handle.", | 3472 "%s expects arguments[%d] to be an Instance handle.", |
3466 CURRENT_FUNC, i); | 3473 CURRENT_FUNC, i); |
3467 } | 3474 } |
3468 } | 3475 } |
3469 args.Add(&arg); | 3476 args.SetAt((i + num_receiver), arg); |
3470 } | |
3471 | |
3472 const Array& kNoArgNames = Array::Handle(isolate); | |
3473 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); | |
3474 if (obj.IsError()) { | |
3475 return target; | |
3476 } | 3477 } |
3477 | 3478 |
3478 if (obj.IsNull() || obj.IsInstance()) { | 3479 if (obj.IsNull() || obj.IsInstance()) { |
3479 Instance& instance = Instance::Handle(isolate); | 3480 Instance& instance = Instance::Handle(isolate); |
3480 instance ^= obj.raw(); | 3481 instance ^= obj.raw(); |
3481 const Function& function = Function::Handle( | 3482 const Function& function = Function::Handle( |
3482 isolate, | 3483 isolate, |
3483 Resolver::ResolveDynamic(instance, | 3484 Resolver::ResolveDynamic(instance, |
3484 function_name, | 3485 function_name, |
3485 (number_of_arguments + 1), | 3486 (number_of_arguments + 1), |
3486 Resolver::kIsQualified)); | 3487 Resolver::kIsQualified)); |
3487 // TODO(5415268): Invoke noSuchMethod instead of failing. | 3488 // TODO(5415268): Invoke noSuchMethod instead of failing. |
3488 if (function.IsNull()) { | 3489 if (function.IsNull()) { |
3489 const Type& type = Type::Handle(isolate, instance.GetType()); | 3490 const Type& type = Type::Handle(isolate, instance.GetType()); |
3490 const String& cls_name = String::Handle(isolate, type.ClassName()); | 3491 const String& cls_name = String::Handle(isolate, type.ClassName()); |
3491 return Api::NewError("%s: did not find instance method '%s.%s'.", | 3492 return Api::NewError("%s: did not find instance method '%s.%s'.", |
3492 CURRENT_FUNC, | 3493 CURRENT_FUNC, |
3493 cls_name.ToCString(), | 3494 cls_name.ToCString(), |
3494 function_name.ToCString()); | 3495 function_name.ToCString()); |
3495 } | 3496 } |
3496 return Api::NewHandle( | 3497 args.SetAt(0, instance); |
3497 isolate, | 3498 return Api::NewHandle(isolate, DartEntry::InvokeDynamic(function, args)); |
3498 DartEntry::InvokeDynamic(instance, function, args, kNoArgNames)); | |
3499 | 3499 |
3500 } else if (obj.IsClass()) { | 3500 } else if (obj.IsClass()) { |
3501 // Finalize all classes. | 3501 // Finalize all classes. |
3502 const char* msg = CheckIsolateState(isolate); | 3502 const char* msg = CheckIsolateState(isolate); |
3503 if (msg != NULL) { | 3503 if (msg != NULL) { |
3504 return Api::NewError("%s", msg); | 3504 return Api::NewError("%s", msg); |
3505 } | 3505 } |
3506 | 3506 |
3507 const Class& cls = Class::Cast(obj); | 3507 const Class& cls = Class::Cast(obj); |
3508 const Function& function = Function::Handle( | 3508 const Function& function = Function::Handle( |
3509 isolate, | 3509 isolate, |
3510 Resolver::ResolveStatic(cls, | 3510 Resolver::ResolveStatic(cls, |
3511 function_name, | 3511 function_name, |
3512 number_of_arguments, | 3512 number_of_arguments, |
3513 Array::Handle(isolate), | 3513 Array::Handle(isolate), |
3514 Resolver::kIsQualified)); | 3514 Resolver::kIsQualified)); |
3515 if (function.IsNull()) { | 3515 if (function.IsNull()) { |
3516 const String& cls_name = String::Handle(isolate, cls.Name()); | 3516 const String& cls_name = String::Handle(isolate, cls.Name()); |
3517 return Api::NewError("%s: did not find static method '%s.%s'.", | 3517 return Api::NewError("%s: did not find static method '%s.%s'.", |
3518 CURRENT_FUNC, | 3518 CURRENT_FUNC, |
3519 cls_name.ToCString(), | 3519 cls_name.ToCString(), |
3520 function_name.ToCString()); | 3520 function_name.ToCString()); |
3521 } | 3521 } |
3522 return Api::NewHandle( | 3522 return Api::NewHandle(isolate, DartEntry::InvokeStatic(function, args)); |
3523 isolate, | |
3524 DartEntry::InvokeStatic(function, args, kNoArgNames)); | |
3525 | 3523 |
3526 } else if (obj.IsLibrary()) { | 3524 } else if (obj.IsLibrary()) { |
3527 // Check whether class finalization is needed. | 3525 // Check whether class finalization is needed. |
3528 bool finalize_classes = true; | 3526 bool finalize_classes = true; |
3529 const Library& lib = Library::Cast(obj); | 3527 const Library& lib = Library::Cast(obj); |
3530 | 3528 |
3531 // When calling functions in the dart:builtin library do not finalize as it | 3529 // When calling functions in the dart:builtin library do not finalize as it |
3532 // should have been prefinalized. | 3530 // should have been prefinalized. |
3533 Library& builtin = | 3531 Library& builtin = |
3534 Library::Handle(isolate, isolate->object_store()->builtin_library()); | 3532 Library::Handle(isolate, isolate->object_store()->builtin_library()); |
(...skipping 20 matching lines...) Expand all Loading... |
3555 // do it here. | 3553 // do it here. |
3556 String& error_message = String::Handle(); | 3554 String& error_message = String::Handle(); |
3557 if (!function.AreValidArgumentCounts(number_of_arguments, | 3555 if (!function.AreValidArgumentCounts(number_of_arguments, |
3558 0, | 3556 0, |
3559 &error_message)) { | 3557 &error_message)) { |
3560 return Api::NewError("%s: wrong argument count for function '%s': %s.", | 3558 return Api::NewError("%s: wrong argument count for function '%s': %s.", |
3561 CURRENT_FUNC, | 3559 CURRENT_FUNC, |
3562 function_name.ToCString(), | 3560 function_name.ToCString(), |
3563 error_message.ToCString()); | 3561 error_message.ToCString()); |
3564 } | 3562 } |
3565 return Api::NewHandle( | 3563 return Api::NewHandle(isolate, DartEntry::InvokeStatic(function, args)); |
3566 isolate, DartEntry::InvokeStatic(function, args, kNoArgNames)); | |
3567 | 3564 |
3568 } else { | 3565 } else { |
3569 return Api::NewError( | 3566 return Api::NewError( |
3570 "%s expects argument 'target' to be an object, class, or library.", | 3567 "%s expects argument 'target' to be an object, class, or library.", |
3571 CURRENT_FUNC); | 3568 CURRENT_FUNC); |
3572 } | 3569 } |
3573 } | 3570 } |
3574 | 3571 |
3575 | 3572 |
3576 static bool FieldIsUninitialized(Isolate* isolate, const Field& fld) { | 3573 static bool FieldIsUninitialized(Isolate* isolate, const Field& fld) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3616 } | 3613 } |
3617 cls = cls.SuperClass(); | 3614 cls = cls.SuperClass(); |
3618 } | 3615 } |
3619 | 3616 |
3620 if (getter.IsNull()) { | 3617 if (getter.IsNull()) { |
3621 return Api::NewError("%s: did not find instance field '%s'.", | 3618 return Api::NewError("%s: did not find instance field '%s'.", |
3622 CURRENT_FUNC, field_name.ToCString()); | 3619 CURRENT_FUNC, field_name.ToCString()); |
3623 } | 3620 } |
3624 | 3621 |
3625 // Invoke the getter and return the result. | 3622 // Invoke the getter and return the result. |
3626 GrowableArray<const Object*> args; | 3623 const int kNumArgs = 1; |
3627 const Array& kNoArgNames = Array::Handle(isolate); | 3624 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); |
3628 return Api::NewHandle( | 3625 args.SetAt(0, instance); |
3629 isolate, | 3626 return Api::NewHandle(isolate, DartEntry::InvokeDynamic(getter, args)); |
3630 DartEntry::InvokeDynamic(instance, getter, args, kNoArgNames)); | |
3631 | 3627 |
3632 } else if (obj.IsClass()) { | 3628 } else if (obj.IsClass()) { |
3633 // Finalize all classes. | 3629 // Finalize all classes. |
3634 const char* msg = CheckIsolateState(isolate); | 3630 const char* msg = CheckIsolateState(isolate); |
3635 if (msg != NULL) { | 3631 if (msg != NULL) { |
3636 return Api::NewError("%s", msg); | 3632 return Api::NewError("%s", msg); |
3637 } | 3633 } |
3638 // To access a static field we may need to use the Field or the | 3634 // To access a static field we may need to use the Field or the |
3639 // getter Function. | 3635 // getter Function. |
3640 const Class& cls = Class::Cast(obj); | 3636 const Class& cls = Class::Cast(obj); |
3641 field = cls.LookupStaticField(field_name); | 3637 field = cls.LookupStaticField(field_name); |
3642 if (field.IsNull() || FieldIsUninitialized(isolate, field)) { | 3638 if (field.IsNull() || FieldIsUninitialized(isolate, field)) { |
3643 const String& getter_name = | 3639 const String& getter_name = |
3644 String::Handle(isolate, Field::GetterName(field_name)); | 3640 String::Handle(isolate, Field::GetterName(field_name)); |
3645 getter = cls.LookupStaticFunction(getter_name); | 3641 getter = cls.LookupStaticFunction(getter_name); |
3646 } | 3642 } |
3647 | 3643 |
3648 if (!getter.IsNull()) { | 3644 if (!getter.IsNull()) { |
3649 // Invoke the getter and return the result. | 3645 // Invoke the getter and return the result. |
3650 GrowableArray<const Object*> args; | 3646 const Array& args = Array::Handle(isolate, Object::empty_array()); |
3651 const Array& kNoArgNames = Array::Handle(isolate); | 3647 return Api::NewHandle(isolate, DartEntry::InvokeStatic(getter, args)); |
3652 return Api::NewHandle( | |
3653 isolate, DartEntry::InvokeStatic(getter, args, kNoArgNames)); | |
3654 } else if (!field.IsNull()) { | 3648 } else if (!field.IsNull()) { |
3655 return Api::NewHandle(isolate, field.value()); | 3649 return Api::NewHandle(isolate, field.value()); |
3656 } else { | 3650 } else { |
3657 return Api::NewError("%s: did not find static field '%s'.", | 3651 return Api::NewError("%s: did not find static field '%s'.", |
3658 CURRENT_FUNC, field_name.ToCString()); | 3652 CURRENT_FUNC, field_name.ToCString()); |
3659 } | 3653 } |
3660 | 3654 |
3661 } else if (obj.IsLibrary()) { | 3655 } else if (obj.IsLibrary()) { |
3662 // TODO(turnidge): Do we need to call CheckIsolateState here? | 3656 // TODO(turnidge): Do we need to call CheckIsolateState here? |
3663 | 3657 |
(...skipping 10 matching lines...) Expand all Loading... |
3674 } else if (FieldIsUninitialized(isolate, field)) { | 3668 } else if (FieldIsUninitialized(isolate, field)) { |
3675 // A field was found. Check for a getter in the field's owner classs. | 3669 // A field was found. Check for a getter in the field's owner classs. |
3676 const Class& cls = Class::Handle(isolate, field.owner()); | 3670 const Class& cls = Class::Handle(isolate, field.owner()); |
3677 const String& getter_name = | 3671 const String& getter_name = |
3678 String::Handle(isolate, Field::GetterName(field_name)); | 3672 String::Handle(isolate, Field::GetterName(field_name)); |
3679 getter = cls.LookupStaticFunction(getter_name); | 3673 getter = cls.LookupStaticFunction(getter_name); |
3680 } | 3674 } |
3681 | 3675 |
3682 if (!getter.IsNull()) { | 3676 if (!getter.IsNull()) { |
3683 // Invoke the getter and return the result. | 3677 // Invoke the getter and return the result. |
3684 GrowableArray<const Object*> args; | 3678 const Array& args = Array::Handle(isolate, Object::empty_array()); |
3685 const Array& kNoArgNames = Array::Handle(isolate); | 3679 return Api::NewHandle(isolate, DartEntry::InvokeStatic(getter, args)); |
3686 return Api::NewHandle( | |
3687 isolate, DartEntry::InvokeStatic(getter, args, kNoArgNames)); | |
3688 } else if (!field.IsNull()) { | 3680 } else if (!field.IsNull()) { |
3689 return Api::NewHandle(isolate, field.value()); | 3681 return Api::NewHandle(isolate, field.value()); |
3690 } else { | 3682 } else { |
3691 return Api::NewError("%s: did not find top-level variable '%s'.", | 3683 return Api::NewError("%s: did not find top-level variable '%s'.", |
3692 CURRENT_FUNC, field_name.ToCString()); | 3684 CURRENT_FUNC, field_name.ToCString()); |
3693 } | 3685 } |
3694 | 3686 |
3695 } else if (obj.IsError()) { | 3687 } else if (obj.IsError()) { |
3696 return container; | 3688 return container; |
3697 } else { | 3689 } else { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3747 } | 3739 } |
3748 cls = cls.SuperClass(); | 3740 cls = cls.SuperClass(); |
3749 } | 3741 } |
3750 | 3742 |
3751 if (setter.IsNull()) { | 3743 if (setter.IsNull()) { |
3752 return Api::NewError("%s: did not find instance field '%s'.", | 3744 return Api::NewError("%s: did not find instance field '%s'.", |
3753 CURRENT_FUNC, field_name.ToCString()); | 3745 CURRENT_FUNC, field_name.ToCString()); |
3754 } | 3746 } |
3755 | 3747 |
3756 // Invoke the setter and return the result. | 3748 // Invoke the setter and return the result. |
3757 GrowableArray<const Object*> args(1); | 3749 const int kNumArgs = 2; |
3758 args.Add(&value_instance); | 3750 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); |
3759 const Array& kNoArgNames = Array::Handle(isolate); | 3751 args.SetAt(0, instance); |
3760 return Api::NewHandle( | 3752 args.SetAt(1, value_instance); |
3761 isolate, | 3753 return Api::NewHandle(isolate, DartEntry::InvokeDynamic(setter, args)); |
3762 DartEntry::InvokeDynamic(instance, setter, args, kNoArgNames)); | |
3763 | 3754 |
3764 } else if (obj.IsClass()) { | 3755 } else if (obj.IsClass()) { |
3765 // To access a static field we may need to use the Field or the | 3756 // To access a static field we may need to use the Field or the |
3766 // setter Function. | 3757 // setter Function. |
3767 const Class& cls = Class::Cast(obj); | 3758 const Class& cls = Class::Cast(obj); |
3768 field = cls.LookupStaticField(field_name); | 3759 field = cls.LookupStaticField(field_name); |
3769 if (field.IsNull()) { | 3760 if (field.IsNull()) { |
3770 String& setter_name = | 3761 String& setter_name = |
3771 String::Handle(isolate, Field::SetterName(field_name)); | 3762 String::Handle(isolate, Field::SetterName(field_name)); |
3772 setter = cls.LookupStaticFunction(setter_name); | 3763 setter = cls.LookupStaticFunction(setter_name); |
3773 } | 3764 } |
3774 | 3765 |
3775 if (!setter.IsNull()) { | 3766 if (!setter.IsNull()) { |
3776 // Invoke the setter and return the result. | 3767 // Invoke the setter and return the result. |
3777 GrowableArray<const Object*> args(1); | 3768 const int kNumArgs = 1; |
3778 args.Add(&value_instance); | 3769 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); |
3779 const Array& kNoArgNames = Array::Handle(isolate); | 3770 args.SetAt(0, value_instance); |
3780 const Object& result = Object::Handle( | 3771 const Object& result = |
3781 isolate, | 3772 Object::Handle(isolate, DartEntry::InvokeStatic(setter, args)); |
3782 DartEntry::InvokeStatic(setter, args, kNoArgNames)); | |
3783 if (result.IsError()) { | 3773 if (result.IsError()) { |
3784 return Api::NewHandle(isolate, result.raw()); | 3774 return Api::NewHandle(isolate, result.raw()); |
3785 } else { | 3775 } else { |
3786 return Api::Success(isolate); | 3776 return Api::Success(isolate); |
3787 } | 3777 } |
3788 } else if (!field.IsNull()) { | 3778 } else if (!field.IsNull()) { |
3789 if (field.is_final()) { | 3779 if (field.is_final()) { |
3790 return Api::NewError("%s: cannot set final field '%s'.", | 3780 return Api::NewError("%s: cannot set final field '%s'.", |
3791 CURRENT_FUNC, field_name.ToCString()); | 3781 CURRENT_FUNC, field_name.ToCString()); |
3792 } else { | 3782 } else { |
(...skipping 12 matching lines...) Expand all Loading... |
3805 const Library& lib = Library::Cast(obj); | 3795 const Library& lib = Library::Cast(obj); |
3806 field = lib.LookupFieldAllowPrivate(field_name); | 3796 field = lib.LookupFieldAllowPrivate(field_name); |
3807 if (field.IsNull()) { | 3797 if (field.IsNull()) { |
3808 const String& setter_name = | 3798 const String& setter_name = |
3809 String::Handle(isolate, Field::SetterName(field_name)); | 3799 String::Handle(isolate, Field::SetterName(field_name)); |
3810 setter ^= lib.LookupFunctionAllowPrivate(setter_name); | 3800 setter ^= lib.LookupFunctionAllowPrivate(setter_name); |
3811 } | 3801 } |
3812 | 3802 |
3813 if (!setter.IsNull()) { | 3803 if (!setter.IsNull()) { |
3814 // Invoke the setter and return the result. | 3804 // Invoke the setter and return the result. |
3815 GrowableArray<const Object*> args(1); | 3805 const int kNumArgs = 1; |
3816 args.Add(&value_instance); | 3806 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); |
3817 const Array& kNoArgNames = Array::Handle(isolate); | 3807 args.SetAt(0, value_instance); |
3818 const Object& result = Object::Handle( | 3808 const Object& result = |
3819 isolate, DartEntry::InvokeStatic(setter, args, kNoArgNames)); | 3809 Object::Handle(isolate, DartEntry::InvokeStatic(setter, args)); |
3820 if (result.IsError()) { | 3810 if (result.IsError()) { |
3821 return Api::NewHandle(isolate, result.raw()); | 3811 return Api::NewHandle(isolate, result.raw()); |
3822 } else { | 3812 } else { |
3823 return Api::Success(isolate); | 3813 return Api::Success(isolate); |
3824 } | 3814 } |
3825 } else if (!field.IsNull()) { | 3815 } else if (!field.IsNull()) { |
3826 if (field.is_final()) { | 3816 if (field.is_final()) { |
3827 return Api::NewError("%s: cannot set final top-level variable '%s'.", | 3817 return Api::NewError("%s: cannot set final top-level variable '%s'.", |
3828 CURRENT_FUNC, field_name.ToCString()); | 3818 CURRENT_FUNC, field_name.ToCString()); |
3829 } else { | 3819 } else { |
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4506 } | 4496 } |
4507 { | 4497 { |
4508 NoGCScope no_gc; | 4498 NoGCScope no_gc; |
4509 RawObject* raw_obj = obj.raw(); | 4499 RawObject* raw_obj = obj.raw(); |
4510 isolate->heap()->SetPeer(raw_obj, peer); | 4500 isolate->heap()->SetPeer(raw_obj, peer); |
4511 } | 4501 } |
4512 return Api::Success(isolate); | 4502 return Api::Success(isolate); |
4513 } | 4503 } |
4514 | 4504 |
4515 } // namespace dart | 4505 } // namespace dart |
OLD | NEW |