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

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
Index: runtime/vm/dart_api_impl.cc
===================================================================
--- runtime/vm/dart_api_impl.cc (revision 1328)
+++ runtime/vm/dart_api_impl.cc (working copy)
@@ -27,43 +27,138 @@
namespace dart {
-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_IsUnhandledException(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()) {
+ ApiError& failure = ApiError::Handle();
+ failure ^= obj.raw();
Anton Muhin 2011/11/09 12:34:03 may you used const ApiError& = ApiError::Handle(ob
turnidge 2011/11/09 19:53:41 Done.
Anton Muhin 2011/11/10 08:28:39 Thanks. There are ways more instance of the same
turnidge 2011/11/10 20:59:13 To get this to work I need to use CheckedHandle.
+ const Object& data = Object::Handle(failure.data());
+ return data.IsUnhandledException();
+ }
+ return false;
}
-DART_EXPORT void _Dart_ReportInvalidHandle(const char* file,
+DART_EXPORT Dart_Handle Dart_GetException(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& 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_GetStacktrace(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));
Anton Muhin 2011/11/09 12:34:03 this is a typical paranoia and DartLibraryCalls::T
turnidge 2011/11/09 19:53:41 Done.
+ const char* exc_str =
+ "<Received exception while converting exception to string>";
+ if (strtmp.IsString()) {
+ exc_str = strtmp.ToCString();
+ }
+
+ const Instance& stack = Instance::Handle(uhe.stacktrace());
+ strtmp = DartLibraryCalls::ToString(stack);
+ const char* stack_str =
+ "<Received exception while converting stacktrace to string>";
+ if (strtmp.IsString()) {
+ stack_str = strtmp.ToCString();
+ }
+
+ const char* format = "Unhandled exception:\n%s\n%s";
+ int len = strlen(exc_str) + strlen(stack_str) + strlen(format) - 2;
Anton Muhin 2011/11/09 12:34:03 why - 2, to account for %s? if yes, shouldn't it
Anton Muhin 2011/11/09 12:34:03 maybe add + 1 into len as well not to duplicate it
turnidge 2011/11/09 19:53:41 Sorry, brain spasm there. Reworked this to be mor
+ char* buffer = reinterpret_cast<char*>(Api::Allocate(len + 1));
+ OS::SNPrint(buffer, (len + 1), 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));
+ OS::SNPrint(msg_copy, len, "%s", msg);
Anton Muhin 2011/11/09 12:34:03 I see you're keeping old code, but strncpy (unless
turnidge 2011/11/09 19:53:41 Um, fixed.
+ 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>";
+ }
}
@@ -141,7 +236,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);
}
@@ -172,22 +267,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));
@@ -211,14 +293,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();
}
@@ -448,7 +526,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.
@@ -510,8 +588,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 ==");
}
}
@@ -981,6 +1061,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");
}
@@ -1015,7 +1097,7 @@
args,
kNoArgumentNames);
if (retval.IsUnhandledException()) {
- *result = Api::Error("Unexpected exception in '[]'");
+ *result = Api::ErrorFromException(retval);
} else {
*result = Api::Success();
}
@@ -1068,7 +1150,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();
@@ -1111,7 +1193,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);
@@ -1143,7 +1225,7 @@
args,
kNoArgumentNames);
if (retval.IsUnhandledException()) {
- *result = Api::Error("Unexpected exception in '[]='");
+ *result = Api::ErrorFromException(retval);
} else {
*result = Api::Success();
}
@@ -1190,7 +1272,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.
}
}
@@ -1252,7 +1334,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);
}
@@ -1276,7 +1362,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);
}
@@ -1299,7 +1389,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);
}
@@ -1463,42 +1557,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);
@@ -1695,7 +1753,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();
@@ -1710,25 +1768,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();
@@ -1755,19 +1808,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;
}
@@ -1784,7 +1831,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();
@@ -1793,12 +1840,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;
}
@@ -2034,7 +2075,7 @@
OS::VSNPrint(buffer, (len + 1), format, args);
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);
}
@@ -2048,6 +2089,22 @@
}
+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);

Powered by Google App Engine
This is Rietveld 408576698