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 2041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2053 args.SetAt(2, value_obj); | 2053 args.SetAt(2, value_obj); |
2054 return Api::NewHandle(isolate, DartEntry::InvokeDynamic(function, | 2054 return Api::NewHandle(isolate, DartEntry::InvokeDynamic(function, |
2055 args)); | 2055 args)); |
2056 } | 2056 } |
2057 } | 2057 } |
2058 return Api::NewError("Object does not implement the 'List' interface"); | 2058 return Api::NewError("Object does not implement the 'List' interface"); |
2059 } | 2059 } |
2060 } | 2060 } |
2061 | 2061 |
2062 | 2062 |
2063 // TODO(hpayer): value should always be smaller then 0xff. Add error handling. | 2063 static RawObject* ResolveConstructor(const char* current_func, |
| 2064 const Class& cls, |
| 2065 const String& class_name, |
| 2066 const String& dotted_name, |
| 2067 int num_args); |
| 2068 |
| 2069 |
| 2070 static RawObject* ThrowArgumentError(const char* exception_message) { |
| 2071 Isolate* isolate = Isolate::Current(); |
| 2072 // Lookup the class ArgumentError in dart:core. |
| 2073 const String& lib_url = String::Handle(String::New("dart:core")); |
| 2074 const String& class_name = |
| 2075 String::Handle(String::New("ArgumentError")); |
| 2076 const Library& lib = |
| 2077 Library::Handle(isolate, Library::LookupLibrary(lib_url)); |
| 2078 if (lib.IsNull()) { |
| 2079 const String& message = String::Handle( |
| 2080 String::NewFormatted("%s: library '%s' not found.", |
| 2081 CURRENT_FUNC, lib_url.ToCString())); |
| 2082 return ApiError::New(message); |
| 2083 } |
| 2084 const Class& cls = Class::Handle(isolate, |
| 2085 lib.LookupClassAllowPrivate(class_name)); |
| 2086 if (cls.IsNull()) { |
| 2087 const String& message = String::Handle( |
| 2088 String::NewFormatted("%s: class '%s' not found in library '%s'.", |
| 2089 CURRENT_FUNC, class_name.ToCString(), |
| 2090 lib_url.ToCString())); |
| 2091 return ApiError::New(message); |
| 2092 } |
| 2093 String& dot_name = String::Handle(String::New(".")); |
| 2094 Object& result = Object::Handle(isolate); |
| 2095 result = ResolveConstructor(CURRENT_FUNC, cls, class_name, dot_name, 1); |
| 2096 if (result.IsError()) return result.raw(); |
| 2097 ASSERT(result.IsFunction()); |
| 2098 Function& constructor = Function::Handle(isolate); |
| 2099 constructor ^= result.raw(); |
| 2100 if (!constructor.IsConstructor()) { |
| 2101 const String& message = String::Handle( |
| 2102 String::NewFormatted("%s: class '%s' is not a constructor.", |
| 2103 CURRENT_FUNC, class_name.ToCString())); |
| 2104 return ApiError::New(message); |
| 2105 } |
| 2106 Instance& exception = Instance::Handle(isolate); |
| 2107 exception = Instance::New(cls); |
| 2108 const Array& args = Array::Handle(isolate, Array::New(3)); |
| 2109 args.SetAt(0, exception); |
| 2110 args.SetAt(1, |
| 2111 Smi::Handle(isolate, Smi::New(Function::kCtorPhaseAll))); |
| 2112 args.SetAt(2, String::Handle(String::New(exception_message))); |
| 2113 result = DartEntry::InvokeStatic(constructor, args); |
| 2114 if (result.IsError()) return result.raw(); |
| 2115 ASSERT(result.IsNull()); |
| 2116 |
| 2117 if (isolate->top_exit_frame_info() == 0) { |
| 2118 // There are no dart frames on the stack so it would be illegal to |
| 2119 // throw an exception here. |
| 2120 const String& message = String::Handle( |
| 2121 String::New("No Dart frames on stack, cannot throw exception")); |
| 2122 return ApiError::New(message); |
| 2123 } |
| 2124 // Unwind all the API scopes till the exit frame before throwing an |
| 2125 // exception. |
| 2126 ApiState* state = isolate->api_state(); |
| 2127 ASSERT(state != NULL); |
| 2128 const Instance* saved_exception; |
| 2129 { |
| 2130 NoGCScope no_gc; |
| 2131 RawInstance* raw_exception = exception.raw(); |
| 2132 state->UnwindScopes(isolate->top_exit_frame_info()); |
| 2133 saved_exception = &Instance::Handle(raw_exception); |
| 2134 } |
| 2135 Exceptions::Throw(*saved_exception); |
| 2136 const String& message = String::Handle( |
| 2137 String::New("Exception was not thrown, internal error")); |
| 2138 return ApiError::New(message); |
| 2139 } |
| 2140 |
| 2141 // TODO(sgjesse): value should always be smaller then 0xff. Add error handling. |
2064 #define GET_LIST_ELEMENT_AS_BYTES(isolate, type, obj, native_array, offset, \ | 2142 #define GET_LIST_ELEMENT_AS_BYTES(isolate, type, obj, native_array, offset, \ |
2065 length) \ | 2143 length) \ |
2066 const type& array = type::Cast(obj); \ | 2144 const type& array = type::Cast(obj); \ |
2067 if (Utils::RangeCheck(offset, length, array.Length())) { \ | 2145 if (Utils::RangeCheck(offset, length, array.Length())) { \ |
2068 Object& element = Object::Handle(isolate); \ | 2146 Object& element = Object::Handle(isolate); \ |
2069 for (int i = 0; i < length; i++) { \ | 2147 for (int i = 0; i < length; i++) { \ |
2070 element = array.At(offset + i); \ | 2148 element = array.At(offset + i); \ |
2071 if (!element.IsInteger()) { \ | 2149 if (!element.IsInteger()) { \ |
2072 return Api::NewError("%s expects the argument 'list' to be " \ | 2150 return Api::NewHandle( \ |
2073 "a List of int", CURRENT_FUNC); \ | 2151 isolate, ThrowArgumentError("List contains non-int elements")); \ |
| 2152 \ |
2074 } \ | 2153 } \ |
2075 const Integer& integer = Integer::Cast(element); \ | 2154 const Integer& integer = Integer::Cast(element); \ |
2076 native_array[i] = static_cast<uint8_t>(integer.AsInt64Value() & 0xff); \ | 2155 native_array[i] = static_cast<uint8_t>(integer.AsInt64Value() & 0xff); \ |
2077 ASSERT(integer.AsInt64Value() <= 0xff); \ | 2156 ASSERT(integer.AsInt64Value() <= 0xff); \ |
2078 } \ | 2157 } \ |
2079 return Api::Success(isolate); \ | 2158 return Api::Success(isolate); \ |
2080 } \ | 2159 } \ |
2081 return Api::NewError("Invalid length passed in to access array elements"); \ | 2160 return Api::NewError("Invalid length passed in to access array elements"); \ |
2082 | 2161 |
2083 | 2162 |
(...skipping 2426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4510 } | 4589 } |
4511 { | 4590 { |
4512 NoGCScope no_gc; | 4591 NoGCScope no_gc; |
4513 RawObject* raw_obj = obj.raw(); | 4592 RawObject* raw_obj = obj.raw(); |
4514 isolate->heap()->SetPeer(raw_obj, peer); | 4593 isolate->heap()->SetPeer(raw_obj, peer); |
4515 } | 4594 } |
4516 return Api::Success(isolate); | 4595 return Api::Success(isolate); |
4517 } | 4596 } |
4518 | 4597 |
4519 } // namespace dart | 4598 } // namespace dart |
OLD | NEW |