Chromium Code Reviews| Index: runtime/vm/dart_api_impl.cc |
| =================================================================== |
| --- runtime/vm/dart_api_impl.cc (revision 3416) |
| +++ runtime/vm/dart_api_impl.cc (working copy) |
| @@ -14,7 +14,6 @@ |
| #include "vm/debuginfo.h" |
| #include "vm/exceptions.h" |
| #include "vm/growable_array.h" |
| -#include "vm/longjump.h" |
| #include "vm/native_entry.h" |
| #include "vm/object.h" |
| #include "vm/object_store.h" |
| @@ -85,53 +84,6 @@ |
| } |
| -// NOTE: Need to pass 'result' as a parameter here in order to avoid |
| -// warning: variable 'result' might be clobbered by 'longjmp' or 'vfork' |
| -// which shows up because of the use of setjmp. |
| -static void InvokeStatic(Isolate* isolate, |
| - const Function& function, |
| - GrowableArray<const Object*>& args, |
| - Dart_Handle* result) { |
| - ASSERT(isolate != NULL); |
| - LongJump* base = isolate->long_jump_base(); |
| - LongJump jump; |
| - isolate->set_long_jump_base(&jump); |
| - if (setjmp(*jump.Set()) == 0) { |
| - const Array& kNoArgumentNames = Array::Handle(); |
| - const Instance& retval = Instance::Handle( |
| - DartEntry::InvokeStatic(function, args, kNoArgumentNames)); |
| - *result = Api::NewLocalHandle(retval); |
| - } else { |
| - SetupErrorResult(result); |
| - } |
| - isolate->set_long_jump_base(base); |
| -} |
| - |
| - |
| -// NOTE: Need to pass 'result' as a parameter here in order to avoid |
| -// warning: variable 'result' might be clobbered by 'longjmp' or 'vfork' |
| -// which shows up because of the use of setjmp. |
| -static void InvokeDynamic(Isolate* isolate, |
| - const Instance& receiver, |
| - const Function& function, |
| - GrowableArray<const Object*>& args, |
| - Dart_Handle* result) { |
| - ASSERT(isolate != NULL); |
| - LongJump* base = isolate->long_jump_base(); |
| - LongJump jump; |
| - isolate->set_long_jump_base(&jump); |
| - if (setjmp(*jump.Set()) == 0) { |
| - const Array& kNoArgumentNames = Array::Handle(); |
| - const Instance& retval = Instance::Handle( |
| - DartEntry::InvokeDynamic(receiver, function, args, kNoArgumentNames)); |
| - *result = Api::NewLocalHandle(retval); |
| - } else { |
| - SetupErrorResult(result); |
| - } |
| - isolate->set_long_jump_base(base); |
| -} |
| - |
| - |
| Dart_Handle Api::NewLocalHandle(const Object& object) { |
| Isolate* isolate = Isolate::Current(); |
| ASSERT(isolate != NULL); |
| @@ -376,6 +328,36 @@ |
| } |
| +DART_EXPORT Dart_Handle Dart_PropagateError(Dart_Handle handle) { |
| + Isolate* isolate = Isolate::Current(); |
| + CHECK_ISOLATE(isolate); |
| + const Object& obj = Object::Handle(Api::UnwrapHandle(handle)); |
| + if (!obj.IsError()) { |
| + return Api::NewError( |
| + "%s expects argument 'handle' to be an error handle. " |
| + "Did you forget to check Dart_IsError first?", |
| + CURRENT_FUNC); |
| + } |
| + if (isolate->top_exit_frame_info() == 0) { |
| + // There are no dart frames on the stack so it would be illegal to |
| + // propagate an error here. |
| + return Api::NewError("No Dart frames on stack, cannot propagate error."); |
| + } |
| + |
| + // Unwind all the API scopes till the exit frame before propagating. |
| + ApiState* state = isolate->api_state(); |
| + ASSERT(state != NULL); |
| + state->UnwindScopes(isolate->top_exit_frame_info()); |
| + |
| + Error& error = Error::Handle(); |
| + error ^= obj.raw(); |
| + Exceptions::PropagateError(error); |
| + UNREACHABLE(); |
| + |
| + return Api::NewError("Cannot reach here. Internal error."); |
| +} |
| + |
| + |
| DART_EXPORT void _Dart_ReportErrorHandle(const char* file, |
| int line, |
| const char* handle, |
| @@ -503,24 +485,17 @@ |
| char** error) { |
| Isolate* isolate = Dart::CreateIsolate(name_prefix); |
| assert(isolate != NULL); |
| - LongJump* base = isolate->long_jump_base(); |
| - LongJump jump; |
| - isolate->set_long_jump_base(&jump); |
| - if (setjmp(*jump.Set()) == 0) { |
| - Dart::InitializeIsolate(snapshot, callback_data); |
| + DARTSCOPE_NOCHECKS(isolate); |
| + const Error& error_obj = |
| + Error::Handle(Dart::InitializeIsolate(snapshot, callback_data)); |
| + if (error_obj.IsNull()) { |
| START_TIMER(time_total_runtime); |
| - isolate->set_long_jump_base(base); |
| return reinterpret_cast<Dart_Isolate>(isolate); |
| } else { |
| - { |
| - DARTSCOPE_NOCHECKS(isolate); |
| - const Error& error_obj = |
| - Error::Handle(isolate->object_store()->sticky_error()); |
| - *error = strdup(error_obj.ToErrorCString()); |
| - } |
| + *error = strdup(error_obj.ToErrorCString()); |
| Dart::ShutdownIsolate(); |
| + return reinterpret_cast<Dart_Isolate>(NULL); |
| } |
| - return reinterpret_cast<Dart_Isolate>(NULL); |
| } |
| @@ -643,24 +618,12 @@ |
| DART_EXPORT Dart_Handle Dart_RunLoop() { |
| Isolate* isolate = Isolate::Current(); |
| DARTSCOPE(isolate); |
| - |
| - LongJump* base = isolate->long_jump_base(); |
| - LongJump jump; |
| - Dart_Handle result; |
| - isolate->set_long_jump_base(&jump); |
| - if (setjmp(*jump.Set()) == 0) { |
| - const Object& obj = Object::Handle(isolate->StandardRunLoop()); |
| - if (obj.IsError()) { |
| - result = Api::NewLocalHandle(obj); |
| - } else { |
| - ASSERT(obj.IsNull()); |
| - result = Api::Success(); |
| - } |
| - } else { |
| - SetupErrorResult(&result); |
| + const Object& obj = Object::Handle(isolate->StandardRunLoop()); |
| + if (obj.IsError()) { |
| + return Api::NewLocalHandle(obj); |
| } |
| - isolate->set_long_jump_base(base); |
| - return result; |
| + ASSERT(obj.IsNull()); |
| + return Api::Success(); |
| } |
| @@ -682,7 +645,6 @@ |
| Dart_Message dart_message) { |
| DARTSCOPE(Isolate::Current()); |
| const Instance& msg = Instance::Handle(DeserializeMessage(dart_message)); |
| - // TODO(turnidge): Should this call be wrapped in a longjmp? |
| const Object& result = |
| Object::Handle(DartLibraryCalls::HandleMessage(dest_port_id, |
| reply_port_id, |
| @@ -752,9 +714,9 @@ |
| Resolver::kIsQualified)); |
| GrowableArray<const Object*> arguments(kNumArguments); |
| arguments.Add(&Integer::Handle(Integer::New(port_id))); |
| - Dart_Handle result; |
| - InvokeStatic(isolate, function, arguments, &result); |
| - return result; |
| + const Object& result = Object::Handle( |
| + DartEntry::InvokeStatic(function, arguments, kNoArgumentNames)); |
| + return Api::NewLocalHandle(result); |
| } |
| @@ -776,9 +738,9 @@ |
| Resolver::kIsQualified)); |
| GrowableArray<const Object*> arguments(kNumArguments); |
| arguments.Add(&Integer::Handle(Integer::New(port_id))); |
| - Dart_Handle result; |
| - InvokeStatic(isolate, function, arguments, &result); |
| - return result; |
| + const Object& result = Object::Handle( |
| + DartEntry::InvokeStatic(function, arguments, kNoArgumentNames)); |
| + return Api::NewLocalHandle(result); |
| } |
| @@ -835,8 +797,8 @@ |
| DARTSCOPE(Isolate::Current()); |
| const Instance& expected = Instance::CheckedHandle(Api::UnwrapHandle(obj1)); |
| const Instance& actual = Instance::CheckedHandle(Api::UnwrapHandle(obj2)); |
| - const Instance& result = |
| - Instance::Handle(DartLibraryCalls::Equals(expected, actual)); |
| + const Object& result = |
| + Object::Handle(DartLibraryCalls::Equals(expected, actual)); |
| if (result.IsBool()) { |
| Bool& b = Bool::Handle(); |
| b ^= result.raw(); |
| @@ -1359,52 +1321,42 @@ |
| // TODO(5526318): Make access to GrowableObjectArray more efficient. |
| // Now check and handle a dart object that implements the List interface. |
| const Instance& instance = Instance::Handle(GetListInstance(isolate, obj)); |
| - if (!instance.IsNull()) { |
| - String& name = String::Handle(String::New("length")); |
| - name = Field::GetterName(name); |
| - const Function& function = Function::Handle( |
| - Resolver::ResolveDynamic(instance, name, 1, 0)); |
| - if (!function.IsNull()) { |
| - GrowableArray<const Object*> args(0); |
| - LongJump* base = isolate->long_jump_base(); |
| - LongJump jump; |
| - isolate->set_long_jump_base(&jump); |
| - Dart_Handle result; |
| - if (setjmp(*jump.Set()) == 0) { |
| - const Array& kNoArgumentNames = Array::Handle(); |
| - const Instance& retval = Instance::Handle( |
| - DartEntry::InvokeDynamic(instance, |
| - function, |
| - args, |
| - kNoArgumentNames)); |
| - result = Api::Success(); |
| - if (retval.IsSmi() || retval.IsMint()) { |
| - Integer& integer = Integer::Handle(); |
| - integer ^= retval.raw(); |
| - *len = integer.AsInt64Value(); |
| - } else if (retval.IsBigint()) { |
| - Bigint& bigint = Bigint::Handle(); |
| - bigint ^= retval.raw(); |
| - if (BigintOperations::FitsIntoInt64(bigint)) { |
| - *len = BigintOperations::ToInt64(bigint); |
| - } else { |
| - result = |
| - Api::NewError("Length of List object is greater than the " |
| - "maximum value that 'len' parameter can hold"); |
| - } |
| - } else if (retval.IsError()) { |
| - result = Api::NewLocalHandle(retval); |
| - } else { |
| - result = Api::NewError("Length of List object is not an integer"); |
| - } |
| - } else { |
| - SetupErrorResult(&result); |
| - } |
| - isolate->set_long_jump_base(base); |
| - return result; |
| + if (instance.IsNull()) { |
| + return Api::NewError("Object does not implement the List inteface"); |
| + } |
| + String& name = String::Handle(String::New("length")); |
| + name = Field::GetterName(name); |
| + const Function& function = Function::Handle( |
| + Resolver::ResolveDynamic(instance, name, 1, 0)); |
| + if (function.IsNull()) { |
| + return Api::NewError("List object does not have a 'length' field."); |
| + } |
| + |
| + GrowableArray<const Object*> args(0); |
| + Dart_Handle result; |
| + const Array& kNoArgumentNames = Array::Handle(); |
| + const Object& retval = Object::Handle( |
| + DartEntry::InvokeDynamic(instance, function, args, kNoArgumentNames)); |
| + if (retval.IsSmi() || retval.IsMint()) { |
| + Integer& integer = Integer::Handle(); |
| + integer ^= retval.raw(); |
| + *len = integer.AsInt64Value(); |
| + return Api::Success(); |
| + } else if (retval.IsBigint()) { |
| + Bigint& bigint = Bigint::Handle(); |
| + bigint ^= retval.raw(); |
| + if (BigintOperations::FitsIntoInt64(bigint)) { |
| + *len = BigintOperations::ToInt64(bigint); |
| + return Api::Success(); |
| + } else { |
| + return Api::NewError("Length of List object is greater than the " |
| + "maximum value that 'len' parameter can hold"); |
| } |
| + } else if (retval.IsError()) { |
| + return Api::NewLocalHandle(retval); |
| + } else { |
| + return Api::NewError("Length of List object is not an integer"); |
| } |
| - return Api::NewError("Object does not implement the list inteface"); |
| } |
| @@ -1415,29 +1367,18 @@ |
| Dart_Handle* result) { |
|
siva
2012/01/31 00:52:34
Why does this have to take the result as parameter
turnidge
2012/01/31 21:56:31
Got rid of GetListAt. It made more trouble than i
|
| ASSERT(isolate != NULL); |
| ASSERT(result != NULL); |
| - LongJump* base = isolate->long_jump_base(); |
| - LongJump jump; |
| - isolate->set_long_jump_base(&jump); |
| - if (setjmp(*jump.Set()) == 0) { |
| - Instance& retval = Instance::Handle(); |
| - GrowableArray<const Object*> args(0); |
| - args.Add(&index); |
| - const Array& kNoArgumentNames = Array::Handle(); |
| - retval = DartEntry::InvokeDynamic(instance, |
| - function, |
| - args, |
| - kNoArgumentNames); |
| - if (retval.IsError()) { |
| - *result = Api::NewLocalHandle(retval); |
| - } else { |
| - *result = Api::Success(); |
| - } |
| - isolate->set_long_jump_base(base); |
| + GrowableArray<const Object*> args(0); |
| + args.Add(&index); |
| + const Array& kNoArgumentNames = Array::Handle(); |
| + const Object& retval = Object::Handle(DartEntry::InvokeDynamic( |
| + instance, function, args, kNoArgumentNames)); |
| + if (retval.IsError()) { |
| + *result = Api::NewLocalHandle(retval); |
| + return Object::null(); |
| + } else { |
| + *result = Api::Success(); |
| return retval.raw(); |
| } |
| - SetupErrorResult(result); |
| - isolate->set_long_jump_base(base); |
| - return Object::null(); |
| } |
| @@ -1485,28 +1426,17 @@ |
| Dart_Handle* result) { |
|
siva
2012/01/31 00:52:34
Why does this need the isolate parameter?
Also co
turnidge
2012/01/31 21:56:31
Got rid of SetListAt as well.
|
| ASSERT(isolate != NULL); |
| ASSERT(result != NULL); |
| - LongJump* base = isolate->long_jump_base(); |
| - LongJump jump; |
| - isolate->set_long_jump_base(&jump); |
| - if (setjmp(*jump.Set()) == 0) { |
| - GrowableArray<const Object*> args(1); |
| - args.Add(&index); |
| - args.Add(&value); |
| - Instance& retval = Instance::Handle(); |
| - const Array& kNoArgumentNames = Array::Handle(); |
| - retval = DartEntry::InvokeDynamic(instance, |
| - function, |
| - args, |
| - kNoArgumentNames); |
| - if (retval.IsError()) { |
| - *result = Api::NewLocalHandle(retval); |
| - } else { |
| - *result = Api::Success(); |
| - } |
| + GrowableArray<const Object*> args(1); |
| + args.Add(&index); |
| + args.Add(&value); |
| + const Array& kNoArgumentNames = Array::Handle(); |
| + const Object& retval = Object::Handle( |
| + DartEntry::InvokeDynamic(instance, function, args, kNoArgumentNames)); |
| + if (retval.IsError()) { |
| + *result = Api::NewLocalHandle(retval); |
| } else { |
| - SetupErrorResult(result); |
| + *result = Api::Success(); |
| } |
| - isolate->set_long_jump_base(base); |
| } |
| @@ -1670,29 +1600,6 @@ |
| } |
| -// NOTE: Need to pass 'result' as a parameter here in order to avoid |
| -// warning: variable 'result' might be clobbered by 'longjmp' or 'vfork' |
| -// which shows up because of the use of setjmp. |
| -static void InvokeClosure(Isolate* isolate, |
| - const Closure& closure, |
| - GrowableArray<const Object*>& args, |
| - Dart_Handle* result) { |
| - ASSERT(isolate != NULL); |
| - LongJump* base = isolate->long_jump_base(); |
| - LongJump jump; |
| - isolate->set_long_jump_base(&jump); |
| - if (setjmp(*jump.Set()) == 0) { |
| - const Array& kNoArgumentNames = Array::Handle(); |
| - const Instance& retval = Instance::Handle( |
| - DartEntry::InvokeClosure(closure, args, kNoArgumentNames)); |
| - *result = Api::NewLocalHandle(retval); |
| - } else { |
| - SetupErrorResult(result); |
| - } |
| - isolate->set_long_jump_base(base); |
| -} |
| - |
| - |
| DART_EXPORT Dart_Handle Dart_InvokeClosure(Dart_Handle closure, |
| int number_of_arguments, |
| Dart_Handle* arguments) { |
| @@ -1710,14 +1617,15 @@ |
| // Now try to invoke the closure. |
| Closure& closure_obj = Closure::Handle(); |
| closure_obj ^= obj.raw(); |
| - Dart_Handle retval; |
| GrowableArray<const Object*> dart_arguments(number_of_arguments); |
| for (int i = 0; i < number_of_arguments; i++) { |
| const Object& arg = Object::Handle(Api::UnwrapHandle(arguments[i])); |
| dart_arguments.Add(&arg); |
| } |
| - InvokeClosure(isolate, closure_obj, dart_arguments, &retval); |
| - return retval; |
| + const Array& kNoArgumentNames = Array::Handle(); |
| + const Object& result = Object::Handle( |
| + DartEntry::InvokeClosure(closure_obj, dart_arguments, kNoArgumentNames)); |
| + return Api::NewLocalHandle(result); |
| } |
| @@ -1795,8 +1703,10 @@ |
| const Object& arg = Object::Handle(Api::UnwrapHandle(arguments[i])); |
| dart_arguments.Add(&arg); |
| } |
| - InvokeStatic(isolate, function, dart_arguments, &retval); |
| - return retval; |
| + const Array& kNoArgumentNames = Array::Handle(); |
| + const Object& result = Object::Handle( |
| + DartEntry::InvokeStatic(function, dart_arguments, kNoArgumentNames)); |
| + return Api::NewLocalHandle(result); |
| } |
| @@ -1838,8 +1748,11 @@ |
| const Object& arg = Object::Handle(Api::UnwrapHandle(arguments[i])); |
| dart_arguments.Add(&arg); |
| } |
| - InvokeDynamic(isolate, receiver, function, dart_arguments, &retval); |
| - return retval; |
| + const Array& kNoArgumentNames = Array::Handle(); |
| + const Object& result = Object::Handle( |
| + DartEntry::InvokeDynamic( |
| + receiver, function, dart_arguments, kNoArgumentNames)); |
| + return Api::NewLocalHandle(result); |
| } |
| @@ -1946,8 +1859,10 @@ |
| Function& func = Function::Handle(); |
| func ^= obj.raw(); |
| GrowableArray<const Object*> args; |
| - InvokeStatic(isolate, func, args, &result); |
| - return result; |
| + const Array& kNoArgumentNames = Array::Handle(); |
| + const Object& result = Object::Handle( |
| + DartEntry::InvokeStatic(func, args, kNoArgumentNames)); |
| + return Api::NewLocalHandle(result); |
| } |
| } |
| @@ -1993,8 +1908,10 @@ |
| Function& func = Function::Handle(); |
| func ^= Api::UnwrapHandle(result); |
| GrowableArray<const Object*> arguments; |
| - InvokeDynamic(isolate, object, func, arguments, &result); |
| - return result; |
| + const Array& kNoArgumentNames = Array::Handle(); |
| + const Object& retval = Object::Handle( |
| + DartEntry::InvokeDynamic(object, func, arguments, kNoArgumentNames)); |
| + return Api::NewLocalHandle(retval); |
| } |
| @@ -2018,8 +1935,10 @@ |
| GrowableArray<const Object*> arguments(1); |
| const Object& arg = Object::Handle(Api::UnwrapHandle(value)); |
| arguments.Add(&arg); |
| - InvokeDynamic(isolate, object, func, arguments, &result); |
| - return result; |
| + const Array& kNoArgumentNames = Array::Handle(); |
| + const Object& retval = Object::Handle( |
| + DartEntry::InvokeDynamic(object, func, arguments, kNoArgumentNames)); |
| + return Api::NewLocalHandle(retval); |
| } |
| @@ -2183,22 +2102,18 @@ |
| } |
| const Script& script = Script::Handle(Script::New(url, source, kind)); |
| ASSERT(isolate != NULL); |
| - LongJump* base = isolate->long_jump_base(); |
| - LongJump jump; |
| - isolate->set_long_jump_base(&jump); |
| - if (setjmp(*jump.Set()) == 0) { |
| - Compiler::Compile(lib, script); |
| + const Error& error = Error::Handle(Compiler::Compile(lib, script)); |
| + if (error.IsNull()) { |
| *result = Api::NewLocalHandle(lib); |
| if (update_lib_status) { |
| lib.SetLoaded(); |
| } |
| } else { |
| - SetupErrorResult(result); |
| + *result = Api::NewLocalHandle(error); |
| if (update_lib_status) { |
| lib.SetLoadError(); |
| } |
| } |
| - isolate->set_long_jump_base(base); |
| } |
| @@ -2270,17 +2185,13 @@ |
| static void CompileAll(Isolate* isolate, Dart_Handle* result) { |
| - *result = Api::Success(); |
| ASSERT(isolate != NULL); |
| - LongJump* base = isolate->long_jump_base(); |
| - LongJump jump; |
| - isolate->set_long_jump_base(&jump); |
| - if (setjmp(*jump.Set()) == 0) { |
| - Library::CompileAll(); |
| + const Error& error = Error::Handle(Library::CompileAll()); |
| + if (error.IsNull()) { |
| + *result = Api::Success(); |
| } else { |
| - SetupErrorResult(result); |
| + *result = Api::NewLocalHandle(error); |
| } |
| - isolate->set_long_jump_base(base); |
| } |