| Index: runtime/include/dart_api.h
|
| diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
|
| index 4249382bd9bfa4493d8ebefb3fbc51cdb2694b86..2746d8d176ca98a178685f85b202169f3fb2ee20 100755
|
| --- a/runtime/include/dart_api.h
|
| +++ b/runtime/include/dart_api.h
|
| @@ -144,19 +144,27 @@ typedef struct _Dart_Isolate* Dart_Isolate;
|
| * by Dart_Error and exit the program.
|
| *
|
| * When an error is returned while in the body of a native function,
|
| - * it can be propagated by calling Dart_PropagateError. Errors should
|
| - * be propagated unless there is a specific reason not to. If an
|
| - * error is not propagated then it is ignored. For example, if an
|
| - * unhandled exception error is ignored, that effectively "catches"
|
| - * the unhandled exception. Fatal errors must always be propagated.
|
| - *
|
| - * Note that a call to Dart_PropagateError never returns. Instead it
|
| - * transfers control non-locally using a setjmp-like mechanism. This
|
| - * can be inconvenient if you have resources that you need to clean up
|
| - * before propagating the error. When an error is propagated, any
|
| - * current scopes created by Dart_EnterScope will be exited.
|
| - *
|
| - * To deal with this inconvenience, we often return error handles
|
| + * it can be propagated up the call stack by calling
|
| + * Dart_PropagateError, Dart_SetReturnValue, or Dart_ThrowException.
|
| + * Errors should be propagated unless there is a specific reason not
|
| + * to. If an error is not propagated then it is ignored. For
|
| + * example, if an unhandled exception error is ignored, that
|
| + * effectively "catches" the unhandled exception. Fatal errors must
|
| + * always be propagated.
|
| + *
|
| + * When an error is propagated, any current scopes created by
|
| + * Dart_EnterScope will be exited.
|
| + *
|
| + * Using Dart_SetReturnValue to propagate an exception is somewhat
|
| + * more convenient than using Dart_PropagateError, and should be
|
| + * preferred for reasons discussed below.
|
| + *
|
| + * Dart_PropagateError and Dart_ThrowException do not return. Instead
|
| + * they transfer control non-locally using a setjmp-like mechanism.
|
| + * This can be inconvenient if you have resources that you need to
|
| + * clean up before propagating the error.
|
| + *
|
| + * When relying on Dart_PropagateError, we often return error handles
|
| * rather than propagating them from helper functions. Consider the
|
| * following contrived example:
|
| *
|
| @@ -191,6 +199,38 @@ typedef struct _Dart_Isolate* Dart_Isolate;
|
| * helper function returns the error handle to the caller, giving the
|
| * caller a chance to clean up before propagating the error handle.
|
| *
|
| + * When an error is propagated by calling Dart_SetReturnValue, the
|
| + * native function will be allowed to complete normally and then the
|
| + * exception will be propagated only once the native call
|
| + * returns. This can be convenient, as it allows the C code to clean
|
| + * up normally.
|
| + *
|
| + * The example can be written more simply using Dart_SetReturnValue to
|
| + * propagate the error.
|
| + *
|
| + * 1 Dart_Handle isLongStringHelper(Dart_Handle arg) {
|
| + * 2 intptr_t* length = 0;
|
| + * 3 result = Dart_StringLength(arg, &length);
|
| + * 4 if (Dart_IsError(result)) {
|
| + * 5 return result
|
| + * 6 }
|
| + * 7 return Dart_NewBoolean(length > 100);
|
| + * 8 }
|
| + * 9
|
| + * 10 void NativeFunction_isLongString(Dart_NativeArguments args) {
|
| + * 11 Dart_EnterScope();
|
| + * 12 AllocateMyResource();
|
| + * 13 Dart_Handle arg = Dart_GetNativeArgument(args, 0);
|
| + * 14 Dart_SetReturnValue(isLongStringHelper(arg));
|
| + * 15 FreeMyResource();
|
| + * 16 Dart_ExitScope();
|
| + * 17 }
|
| + *
|
| + * In this example, the call to Dart_SetReturnValue on line 14 will
|
| + * either return the normal return value or the error (potentially
|
| + * generated on line 3). The call to FreeMyResource on line 15 will
|
| + * execute in either case.
|
| + *
|
| * --- Local and persistent handles ---
|
| *
|
| * Local handles are allocated within the current scope (see
|
| @@ -2143,6 +2183,10 @@ DART_EXPORT Dart_Handle Dart_SetField(Dart_Handle container,
|
| * appropriate 'catch' block is found, executing 'finally' blocks,
|
| * etc.
|
| *
|
| + * If an error handle is passed into this function, the error is
|
| + * propagated immediately. See Dart_PropagateError for a discussion
|
| + * of error propagation.
|
| + *
|
| * If successful, this function does not return. Note that this means
|
| * that the destructors of any stack-allocated C++ objects will not be
|
| * called. If there are no Dart frames on the stack, an error occurs.
|
| @@ -2380,6 +2424,10 @@ DART_EXPORT Dart_Handle Dart_GetNativeDoubleArgument(Dart_NativeArguments args,
|
|
|
| /**
|
| * Sets the return value for a native function.
|
| + *
|
| + * If retval is an Error handle, then error will be propagated once
|
| + * the native functions exits. See Dart_PropagateError for a
|
| + * discussion of how different types of errors are propagated.
|
| */
|
| DART_EXPORT void Dart_SetReturnValue(Dart_NativeArguments args,
|
| Dart_Handle retval);
|
|
|