OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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" |
11 #include "vm/dart_api_impl.h" | 11 #include "vm/dart_api_impl.h" |
(...skipping 2011 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2023 args.SetAt(2, value_obj); | 2023 args.SetAt(2, value_obj); |
2024 return Api::NewHandle(isolate, DartEntry::InvokeDynamic(function, | 2024 return Api::NewHandle(isolate, DartEntry::InvokeDynamic(function, |
2025 args)); | 2025 args)); |
2026 } | 2026 } |
2027 } | 2027 } |
2028 return Api::NewError("Object does not implement the 'List' interface"); | 2028 return Api::NewError("Object does not implement the 'List' interface"); |
2029 } | 2029 } |
2030 } | 2030 } |
2031 | 2031 |
2032 | 2032 |
2033 // TODO(hpayer): value should always be smaller then 0xff. Add error handling. | 2033 static RawObject* ResolveConstructor(const char* current_func, |
| 2034 const Class& cls, |
| 2035 const String& class_name, |
| 2036 const String& dotted_name, |
| 2037 int num_args); |
| 2038 |
| 2039 |
| 2040 static RawObject* ThrowArgumentError(const char* exception_message) { |
| 2041 Isolate* isolate = Isolate::Current(); |
| 2042 // Lookup the class ArgumentError in dart:core. |
| 2043 const String& lib_url = String::Handle(String::New("dart:core")); |
| 2044 const String& class_name = |
| 2045 String::Handle(String::New("ArgumentError")); |
| 2046 const Library& lib = |
| 2047 Library::Handle(isolate, Library::LookupLibrary(lib_url)); |
| 2048 if (lib.IsNull()) { |
| 2049 const String& message = String::Handle( |
| 2050 String::NewFormatted("%s: library '%s' not found.", |
| 2051 CURRENT_FUNC, lib_url.ToCString())); |
| 2052 return ApiError::New(message); |
| 2053 } |
| 2054 const Class& cls = Class::Handle(isolate, |
| 2055 lib.LookupClassAllowPrivate(class_name)); |
| 2056 if (cls.IsNull()) { |
| 2057 const String& message = String::Handle( |
| 2058 String::NewFormatted("%s: class '%s' not found in library '%s'.", |
| 2059 CURRENT_FUNC, class_name.ToCString(), |
| 2060 lib_url.ToCString())); |
| 2061 return ApiError::New(message); |
| 2062 } |
| 2063 String& dot_name = String::Handle(String::New(".")); |
| 2064 Object& result = Object::Handle(isolate); |
| 2065 result = ResolveConstructor(CURRENT_FUNC, cls, class_name, dot_name, 1); |
| 2066 if (result.IsError()) return result.raw(); |
| 2067 ASSERT(result.IsFunction()); |
| 2068 Function& constructor = Function::Handle(isolate); |
| 2069 constructor ^= result.raw(); |
| 2070 if (!constructor.IsConstructor()) { |
| 2071 const String& message = String::Handle( |
| 2072 String::NewFormatted("%s: class '%s' is not a constructor.", |
| 2073 CURRENT_FUNC, class_name.ToCString())); |
| 2074 return ApiError::New(message); |
| 2075 } |
| 2076 Instance& exception = Instance::Handle(isolate); |
| 2077 exception = Instance::New(cls); |
| 2078 const Array& args = Array::Handle(isolate, Array::New(3)); |
| 2079 args.SetAt(0, exception); |
| 2080 args.SetAt(1, |
| 2081 Smi::Handle(isolate, Smi::New(Function::kCtorPhaseAll))); |
| 2082 args.SetAt(2, String::Handle(String::New(exception_message))); |
| 2083 result = DartEntry::InvokeStatic(constructor, args); |
| 2084 if (result.IsError()) return result.raw(); |
| 2085 ASSERT(result.IsNull()); |
| 2086 |
| 2087 if (isolate->top_exit_frame_info() == 0) { |
| 2088 // There are no dart frames on the stack so it would be illegal to |
| 2089 // throw an exception here. |
| 2090 const String& message = String::Handle( |
| 2091 String::New("No Dart frames on stack, cannot throw exception")); |
| 2092 return ApiError::New(message); |
| 2093 } |
| 2094 // Unwind all the API scopes till the exit frame before throwing an |
| 2095 // exception. |
| 2096 ApiState* state = isolate->api_state(); |
| 2097 ASSERT(state != NULL); |
| 2098 const Instance* saved_exception; |
| 2099 { |
| 2100 NoGCScope no_gc; |
| 2101 RawInstance* raw_exception = exception.raw(); |
| 2102 state->UnwindScopes(isolate->top_exit_frame_info()); |
| 2103 saved_exception = &Instance::Handle(raw_exception); |
| 2104 } |
| 2105 Exceptions::Throw(*saved_exception); |
| 2106 const String& message = String::Handle( |
| 2107 String::New("Exception was not thrown, internal error")); |
| 2108 return ApiError::New(message); |
| 2109 } |
| 2110 |
| 2111 // TODO(sgjesse): value should always be smaller then 0xff. Add error handling. |
2034 #define GET_LIST_ELEMENT_AS_BYTES(isolate, type, obj, native_array, offset, \ | 2112 #define GET_LIST_ELEMENT_AS_BYTES(isolate, type, obj, native_array, offset, \ |
2035 length) \ | 2113 length) \ |
2036 const type& array = type::Cast(obj); \ | 2114 const type& array = type::Cast(obj); \ |
2037 if (Utils::RangeCheck(offset, length, array.Length())) { \ | 2115 if (Utils::RangeCheck(offset, length, array.Length())) { \ |
2038 Object& element = Object::Handle(isolate); \ | 2116 Object& element = Object::Handle(isolate); \ |
2039 for (int i = 0; i < length; i++) { \ | 2117 for (int i = 0; i < length; i++) { \ |
2040 element = array.At(offset + i); \ | 2118 element = array.At(offset + i); \ |
2041 if (!element.IsInteger()) { \ | 2119 if (!element.IsInteger()) { \ |
2042 return Api::NewError("%s expects the argument 'list' to be " \ | 2120 return Api::NewHandle( \ |
2043 "a List of int", CURRENT_FUNC); \ | 2121 isolate, ThrowArgumentError("List contains non-int elements")); \ |
| 2122 \ |
2044 } \ | 2123 } \ |
2045 const Integer& integer = Integer::Cast(element); \ | 2124 const Integer& integer = Integer::Cast(element); \ |
2046 native_array[i] = static_cast<uint8_t>(integer.AsInt64Value() & 0xff); \ | 2125 native_array[i] = static_cast<uint8_t>(integer.AsInt64Value() & 0xff); \ |
2047 ASSERT(integer.AsInt64Value() <= 0xff); \ | 2126 ASSERT(integer.AsInt64Value() <= 0xff); \ |
2048 } \ | 2127 } \ |
2049 return Api::Success(isolate); \ | 2128 return Api::Success(isolate); \ |
2050 } \ | 2129 } \ |
2051 return Api::NewError("Invalid length passed in to access array elements"); \ | 2130 return Api::NewError("Invalid length passed in to access array elements"); \ |
2052 | 2131 |
2053 | 2132 |
(...skipping 2468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4522 } | 4601 } |
4523 { | 4602 { |
4524 NoGCScope no_gc; | 4603 NoGCScope no_gc; |
4525 RawObject* raw_obj = obj.raw(); | 4604 RawObject* raw_obj = obj.raw(); |
4526 isolate->heap()->SetPeer(raw_obj, peer); | 4605 isolate->heap()->SetPeer(raw_obj, peer); |
4527 } | 4606 } |
4528 return Api::Success(isolate); | 4607 return Api::Success(isolate); |
4529 } | 4608 } |
4530 | 4609 |
4531 } // namespace dart | 4610 } // namespace dart |
OLD | NEW |