Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(130)

Unified Diff: runtime/vm/dart_api_impl.cc

Issue 8501034: Deal with unhandled exceptions the same way in all Dart api functions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/dart_api_impl.h ('k') | runtime/vm/dart_api_impl_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/dart_api_impl.cc
===================================================================
--- runtime/vm/dart_api_impl.cc (revision 1469)
+++ runtime/vm/dart_api_impl.cc (working copy)
@@ -45,7 +45,7 @@
} else if (tmp.IsNull()) { \
return Api::Error("%s expects argument '%s' to be non-null.", \
CURRENT_FUNC, #dart_handle); \
- } else if (tmp.IsApiFailure()) { \
+ } else if (tmp.IsApiError()) { \
return dart_handle; \
} else { \
return Api::Error("%s expects argument '%s' to be of type %s.", \
@@ -54,43 +54,138 @@
} while (0)
-DART_EXPORT bool Dart_IsValid(const Dart_Handle& handle) {
+DART_EXPORT bool Dart_IsError(const Dart_Handle& handle) {
ASSERT(Isolate::Current() != NULL);
Zone zone; // Setup a VM zone as we are creating some handles.
HandleScope scope; // Setup a VM handle scope.
+ const Object& obj = Object::Handle(Api::UnwrapHandle(handle));
+ return obj.IsApiError();
+}
- // Make sure that the object isn't an ApiFailure.
+
+DART_EXPORT bool Dart_ErrorHasException(Dart_Handle handle) {
+ Zone zone; // Setup a VM zone as we are creating some handles.
+ HandleScope scope; // Setup a VM handle scope.
const Object& obj = Object::Handle(Api::UnwrapHandle(handle));
- return !obj.IsApiFailure();
+ if (obj.IsApiError()) {
+ const ApiError& error = ApiError::CheckedHandle(obj.raw());
+ const Object& data = Object::Handle(error.data());
+ return data.IsUnhandledException();
+ }
+ return false;
}
-DART_EXPORT void _Dart_ReportInvalidHandle(const char* file,
+DART_EXPORT Dart_Handle Dart_ErrorGetException(Dart_Handle handle) {
+ Zone zone; // Setup a VM zone as we are creating some handles.
+ HandleScope scope; // Setup a VM handle scope.
+ const Object& obj = Object::Handle(Api::UnwrapHandle(handle));
+ if (obj.IsApiError()) {
+ const ApiError& error = ApiError::CheckedHandle(obj.raw());
+ const Object& data = Object::Handle(error.data());
+ if (data.IsUnhandledException()) {
+ const UnhandledException& unhandled = UnhandledException::Handle(
+ reinterpret_cast<RawUnhandledException*>(data.raw()));
+ const Object& exception = Object::Handle(unhandled.exception());
+ return Api::NewLocalHandle(exception);
+ } else {
+ return Api::Error("This error is not an unhandled exception error.");
+ }
+ } else {
+ return Api::Error("Can only get exceptions from error handles.");
+ }
+}
+
+
+DART_EXPORT Dart_Handle Dart_ErrorGetStacktrace(Dart_Handle handle) {
+ Zone zone; // Setup a VM zone as we are creating some handles.
+ HandleScope scope; // Setup a VM handle scope.
+ const Object& obj = Object::Handle(Api::UnwrapHandle(handle));
+ if (obj.IsApiError()) {
+ ApiError& failure = ApiError::Handle();
+ failure ^= obj.raw();
+ const Object& data = Object::Handle(failure.data());
+ if (data.IsUnhandledException()) {
+ const UnhandledException& unhandled = UnhandledException::Handle(
+ reinterpret_cast<RawUnhandledException*>(data.raw()));
+ const Object& stacktrace = Object::Handle(unhandled.stacktrace());
+ return Api::NewLocalHandle(stacktrace);
+ } else {
+ return Api::Error("This error is not an unhandled exception error.");
+ }
+ } else {
+ return Api::Error("Can only get stacktraces from error handles.");
+ }
+}
+
+
+DART_EXPORT void _Dart_ReportErrorHandle(const char* file,
int line,
const char* handle,
const char* message) {
- fprintf(stderr, "%s:%d: invalid handle: '%s':\n '%s'\n",
+ fprintf(stderr, "%s:%d: error handle: '%s':\n '%s'\n",
file, line, handle, message);
OS::Abort();
}
+static const char* MakeUnhandledExceptionCString(
+ const UnhandledException& uhe) {
+ const Instance& exception = Instance::Handle(uhe.exception());
+ Object& strtmp = Object::Handle(DartLibraryCalls::ToString(exception));
+ const char* exc_str =
+ "<Received exception while converting exception to string>";
+ if (!strtmp.IsUnhandledException()) {
+ exc_str = strtmp.ToCString();
+ }
+
+ const Instance& stack = Instance::Handle(uhe.stacktrace());
+ strtmp = DartLibraryCalls::ToString(stack);
+ const char* stack_str =
+ "<Received exception while converting stack trace to string>";
+ if (!strtmp.IsUnhandledException()) {
+ stack_str = strtmp.ToCString();
+ }
+
+ const char* format = "Unhandled exception:\n%s\n%s";
+ int len = (strlen(exc_str) + strlen(stack_str) + strlen(format)
+ - 4 // Two '%s'
+ + 1); // '\0'
+ char* buffer = reinterpret_cast<char*>(Api::Allocate(len));
+ OS::SNPrint(buffer, len, format, exc_str, stack_str);
+ return buffer;
+}
+
+
DART_EXPORT const char* Dart_GetError(const Dart_Handle& handle) {
ASSERT(Isolate::Current() != NULL);
Zone zone; // Setup a VM zone as we are creating some handles.
HandleScope scope; // Setup a VM handle scope.
const Object& obj = Object::Handle(Api::UnwrapHandle(handle));
- if (!obj.IsApiFailure()) {
+ if (!obj.IsApiError()) {
return "";
}
- ApiFailure& failure = ApiFailure::Handle();
+ ApiError& failure = ApiError::Handle();
failure ^= obj.raw();
- const String& message = String::Handle(failure.message());
- const char* msg = message.ToCString();
- intptr_t len = strlen(msg) + 1;
- char* msg_copy = reinterpret_cast<char*>(Api::Allocate(len));
- OS::SNPrint(msg_copy, len, "%s", msg);
- return msg_copy;
+ const Object& data = Object::Handle(failure.data());
+ if (data.IsString()) {
+ // Simple error message.
+ String& message = String::Handle();
+ message ^= failure.data();
+ const char* msg = message.ToCString();
+ intptr_t len = strlen(msg) + 1;
+ char* msg_copy = reinterpret_cast<char*>(Api::Allocate(len));
+ strncpy(msg_copy, msg, len);
+ return msg_copy;
+
+ } else if (data.IsUnhandledException()) {
+ UnhandledException& uhe = UnhandledException::Handle();
+ uhe ^= data.raw();
+ return MakeUnhandledExceptionCString(uhe);
+
+ } else {
+ return "<Internal error in Dart_GetError: malformed error handle>";
+ }
}
@@ -112,7 +207,7 @@
va_end(args2);
const String& message = String::Handle(String::New(buffer));
- const Object& obj = Object::Handle(ApiFailure::New(message));
+ const Object& obj = Object::Handle(ApiError::New(message));
return Api::NewLocalHandle(obj);
}
@@ -182,7 +277,7 @@
// may get deallocated when we return back from the Dart API call.
const String& error = String::Handle(
Isolate::Current()->object_store()->sticky_error());
- const Object& obj = Object::Handle(ApiFailure::New(error));
+ const Object& obj = Object::Handle(ApiError::New(error));
*handle = Api::NewLocalHandle(obj);
}
@@ -213,22 +308,9 @@
}
-static void ProcessUnhandledException(const UnhandledException& uhe) {
- const Instance& exception = Instance::Handle(uhe.exception());
- Instance& strtmp = Instance::Handle(DartLibraryCalls::ToString(exception));
- const char* str = strtmp.ToCString();
- fprintf(stderr, "%s\n", str);
- const Instance& stack = Instance::Handle(uhe.stacktrace());
- strtmp = DartLibraryCalls::ToString(stack);
- str = strtmp.ToCString();
- fprintf(stderr, "%s\n", str);
- exit(255);
-}
-
-
-DART_EXPORT void Dart_HandleMessage(Dart_Port dest_port,
- Dart_Port reply_port,
- Dart_Message dart_message) {
+DART_EXPORT Dart_Handle Dart_HandleMessage(Dart_Port dest_port,
+ Dart_Port reply_port,
+ Dart_Message dart_message) {
Zone zone; // Setup a VM zone as we are creating some handles.
HandleScope scope; // Setup a VM handle scope.
const Instance& msg = Instance::Handle(DeserializeMessage(dart_message));
@@ -252,14 +334,10 @@
const Object& result = Object::Handle(
DartEntry::InvokeStatic(function, arguments, kNoArgumentNames));
if (result.IsUnhandledException()) {
- UnhandledException& uhe = UnhandledException::Handle();
- uhe ^= result.raw();
- // TODO(turnidge): Instead of exiting here, just return the
- // exception so that the embedder can choose how to handle this
- // case.
- ProcessUnhandledException(uhe);
+ return Api::ErrorFromException(result);
}
ASSERT(result.IsNull());
+ return Api::Success();
}
@@ -491,7 +569,7 @@
receiver ^= obj.raw();
result = DartLibraryCalls::ToString(receiver);
if (result.IsUnhandledException()) {
- return Api::Error("An exception occurred when converting to string");
+ return Api::ErrorFromException(result);
}
} else {
// This is a VM internal object. Call the C++ method of printing.
@@ -553,8 +631,10 @@
b ^= result.raw();
*value = b.value();
return Api::Success();
+ } else if (result.IsUnhandledException()) {
+ return Api::ErrorFromException(result);
} else {
- return Api::Error("An exception occured when calling '=='");
+ return Api::Error("Expected boolean result from ==");
}
}
@@ -1024,6 +1104,8 @@
result = Api::Error("Length of List object is greater than the "
"maximum value that 'len' parameter can hold");
}
+ } else if (retval.IsUnhandledException()) {
+ result = Api::ErrorFromException(retval);
} else {
result = Api::Error("Length of List object is not an integer");
}
@@ -1058,7 +1140,7 @@
args,
kNoArgumentNames);
if (retval.IsUnhandledException()) {
- *result = Api::Error("Unexpected exception in '[]'");
+ *result = Api::ErrorFromException(retval);
} else {
*result = Api::Success();
}
@@ -1111,7 +1193,7 @@
for (int i = 0; i < length; i++) {
intobj = Integer::New(offset + i);
element = GetListAt(isolate, instance, intobj, function, &result);
- if (!Dart_IsValid(result)) {
+ if (Dart_IsError(result)) {
return result; // Error condition.
}
intobj ^= element.raw();
@@ -1154,7 +1236,7 @@
Dart_Handle result;
indexobj = Integer::New(index);
element = GetListAt(isolate, instance, indexobj, function, &result);
- if (!Dart_IsValid(result)) {
+ if (Dart_IsError(result)) {
return result; // Error condition.
}
return Api::NewLocalHandle(element);
@@ -1186,7 +1268,7 @@
args,
kNoArgumentNames);
if (retval.IsUnhandledException()) {
- *result = Api::Error("Unexpected exception in '[]='");
+ *result = Api::ErrorFromException(retval);
} else {
*result = Api::Success();
}
@@ -1233,7 +1315,7 @@
indexobj = Integer::New(offset + i);
valueobj ^= Integer::New(native_array[i]);
SetListAt(isolate, instance, indexobj, valueobj, function, &result);
- if (!Dart_IsValid(result)) {
+ if (Dart_IsError(result)) {
return result; // Error condition.
}
}
@@ -1295,7 +1377,11 @@
const Array& kNoArgumentNames = Array::Handle();
const Instance& retval = Instance::Handle(
DartEntry::InvokeStatic(function, args, kNoArgumentNames));
- *result = Api::NewLocalHandle(retval);
+ if (retval.IsUnhandledException()) {
+ *result = Api::ErrorFromException(retval);
+ } else {
+ *result = Api::NewLocalHandle(retval);
+ }
} else {
SetupErrorResult(result);
}
@@ -1319,7 +1405,11 @@
const Array& kNoArgumentNames = Array::Handle();
const Instance& retval = Instance::Handle(
DartEntry::InvokeDynamic(receiver, function, args, kNoArgumentNames));
- *result = Api::NewLocalHandle(retval);
+ if (retval.IsUnhandledException()) {
+ *result = Api::ErrorFromException(retval);
+ } else {
+ *result = Api::NewLocalHandle(retval);
+ }
} else {
SetupErrorResult(result);
}
@@ -1342,7 +1432,11 @@
const Array& kNoArgumentNames = Array::Handle();
const Instance& retval = Instance::Handle(
DartEntry::InvokeClosure(closure, args, kNoArgumentNames));
- *result = Api::NewLocalHandle(retval);
+ if (retval.IsUnhandledException()) {
+ *result = Api::ErrorFromException(retval);
+ } else {
+ *result = Api::NewLocalHandle(retval);
+ }
} else {
SetupErrorResult(result);
}
@@ -1506,42 +1600,6 @@
}
-DART_EXPORT bool Dart_ExceptionOccurred(Dart_Handle result) {
- Zone zone; // Setup a VM zone as we are creating some handles.
- HandleScope scope; // Setup a VM handle scope.
- const Object& retval = Object::Handle(Api::UnwrapHandle(result));
- return retval.IsUnhandledException();
-}
-
-
-DART_EXPORT Dart_Handle Dart_GetException(Dart_Handle result) {
- Zone zone; // Setup a VM zone as we are creating some handles.
- HandleScope scope; // Setup a VM handle scope.
- const Object& retval = Object::Handle(Api::UnwrapHandle(result));
- if (retval.IsUnhandledException()) {
- const UnhandledException& unhandled = UnhandledException::Handle(
- reinterpret_cast<RawUnhandledException*>(retval.raw()));
- const Object& exception = Object::Handle(unhandled.exception());
- return Api::NewLocalHandle(exception);
- }
- return Api::Error("Object is not an unhandled exception object");
-}
-
-
-DART_EXPORT Dart_Handle Dart_GetStacktrace(Dart_Handle unhandled_excp) {
- Zone zone; // Setup a VM zone as we are creating some handles.
- HandleScope scope; // Setup a VM handle scope.
- const Object& retval = Object::Handle(Api::UnwrapHandle(unhandled_excp));
- if (retval.IsUnhandledException()) {
- const UnhandledException& unhandled = UnhandledException::Handle(
- reinterpret_cast<RawUnhandledException*>(retval.raw()));
- const Object& stacktrace = Object::Handle(unhandled.stacktrace());
- return Api::NewLocalHandle(stacktrace);
- }
- return Api::Error("Object is not an unhandled exception object");
-}
-
-
DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception) {
Isolate* isolate = Isolate::Current();
ASSERT(isolate != NULL);
@@ -1738,7 +1796,7 @@
Zone zone; // Setup a VM zone as we are creating some handles.
HandleScope scope; // Setup a VM handle scope.
Dart_Handle result = LookupStaticField(cls, name, kGetter);
- if (!::Dart_IsValid(result)) {
+ if (::Dart_IsError(result)) {
return result;
}
Object& retval = Object::Handle();
@@ -1753,25 +1811,20 @@
func ^= obj.raw();
GrowableArray<const Object*> args;
InvokeStatic(func, args, &result);
- if (::Dart_IsValid(result)) {
- if (Dart_ExceptionOccurred(result)) {
- return Api::Error(
- "An exception occurred when getting the static field");
- }
- }
return result;
}
}
// TODO(iposva): The value parameter should be documented as being an instance.
+// TODO(turnidge): Is this skipping the setter?
DART_EXPORT Dart_Handle Dart_SetStaticField(Dart_Handle cls,
Dart_Handle name,
Dart_Handle value) {
Zone zone; // Setup a VM zone as we are creating some handles.
HandleScope scope; // Setup a VM handle scope.
Dart_Handle result = LookupStaticField(cls, name, kSetter);
- if (!::Dart_IsValid(result)) {
+ if (::Dart_IsError(result)) {
return result;
}
Field& fld = Field::Handle();
@@ -1798,19 +1851,13 @@
Instance& object = Instance::Handle();
object ^= param.raw();
Dart_Handle result = LookupInstanceField(object, name, kGetter);
- if (!::Dart_IsValid(result)) {
+ if (::Dart_IsError(result)) {
return result;
}
Function& func = Function::Handle();
func ^= Api::UnwrapHandle(result);
GrowableArray<const Object*> arguments;
InvokeDynamic(object, func, arguments, &result);
- if (::Dart_IsValid(result)) {
- if (Dart_ExceptionOccurred(result)) {
- return Api::Error(
- "An exception occurred when accessing the instance field");
- }
- }
return result;
}
@@ -1827,7 +1874,7 @@
Instance& object = Instance::Handle();
object ^= param.raw();
Dart_Handle result = LookupInstanceField(object, name, kSetter);
- if (!::Dart_IsValid(result)) {
+ if (::Dart_IsError(result)) {
return result;
}
Function& func = Function::Handle();
@@ -1836,12 +1883,6 @@
const Object& arg = Object::Handle(Api::UnwrapHandle(value));
arguments.Add(&arg);
InvokeDynamic(object, func, arguments, &result);
- if (::Dart_IsValid(result)) {
- if (Dart_ExceptionOccurred(result)) {
- return Api::Error(
- "An exception occurred when setting the instance field");
- }
- }
return result;
}
@@ -2084,11 +2125,27 @@
va_end(args2);
const String& message = String::Handle(String::New(buffer));
- const Object& obj = Object::Handle(ApiFailure::New(message));
+ const Object& obj = Object::Handle(ApiError::New(message));
return Api::NewLocalHandle(obj);
}
+Dart_Handle Api::ErrorFromException(const Object& obj) {
+ Zone zone; // Setup a VM zone as we are creating some handles.
+ HandleScope scope; // Setup a VM handle scope.
+
+ ASSERT(obj.IsUnhandledException());
+ if (obj.IsUnhandledException()) {
+ UnhandledException& uhe = UnhandledException::Handle();
+ uhe ^= obj.raw();
+ const Object& error = Object::Handle(ApiError::New(uhe));
+ return Api::NewLocalHandle(error);
+ } else {
+ return Api::Error("Internal error: expected obj.IsUnhandledException().");
+ }
+}
+
+
Dart_Handle Api::Null() {
Isolate* isolate = Isolate::Current();
ASSERT(isolate != NULL);
« no previous file with comments | « runtime/vm/dart_api_impl.h ('k') | runtime/vm/dart_api_impl_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698