| Index: runtime/vm/dart_api_impl.cc
|
| ===================================================================
|
| --- runtime/vm/dart_api_impl.cc (revision 1754)
|
| +++ runtime/vm/dart_api_impl.cc (working copy)
|
| @@ -52,76 +52,201 @@
|
| } while (0)
|
|
|
|
|
| -DART_EXPORT bool Dart_IsError(const Dart_Handle& handle) {
|
| - DARTSCOPE(Isolate::Current());
|
| - const Object& obj = Object::Handle(Api::UnwrapHandle(handle));
|
| - return obj.IsApiError();
|
| +// Return error if isolate is in an inconsistent state.
|
| +// Return NULL when no error condition exists.
|
| +static const char* CheckIsolateState(
|
| + Isolate* isolate,
|
| + bool generating_snapshot = ClassFinalizer::kNotGeneratingSnapshot) {
|
| + bool result = (generating_snapshot) ?
|
| + ClassFinalizer::FinalizePendingClassesForSnapshotCreation() :
|
| + ClassFinalizer::FinalizePendingClasses();
|
| + if (!result) {
|
| + // Make a copy of the error message as the original message string
|
| + // may get deallocated when we return back from the Dart API call.
|
| + const String& err =
|
| + String::Handle(isolate->object_store()->sticky_error());
|
| + const char* errmsg = err.ToCString();
|
| + intptr_t errlen = strlen(errmsg) + 1;
|
| + char* msg = reinterpret_cast<char*>(Api::Allocate(errlen));
|
| + OS::SNPrint(msg, errlen, "%s", errmsg);
|
| + return msg;
|
| + }
|
| + return NULL;
|
| }
|
|
|
|
|
| -DART_EXPORT bool Dart_ErrorHasException(Dart_Handle handle) {
|
| - DARTSCOPE(Isolate::Current());
|
| - 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());
|
| - return data.IsUnhandledException();
|
| +static void SetupErrorResult(Dart_Handle* handle) {
|
| + // Make a copy of the error message as the original message string
|
| + // 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(ApiError::New(error));
|
| + *handle = Api::NewLocalHandle(obj);
|
| +}
|
| +
|
| +
|
| +Dart_Handle Api::NewLocalHandle(const Object& object) {
|
| + Isolate* isolate = Isolate::Current();
|
| + ASSERT(isolate != NULL);
|
| + ApiState* state = isolate->api_state();
|
| + ASSERT(state != NULL);
|
| + ApiLocalScope* scope = state->top_scope();
|
| + ASSERT(scope != NULL);
|
| + LocalHandles* local_handles = scope->local_handles();
|
| + ASSERT(local_handles != NULL);
|
| + LocalHandle* ref = local_handles->AllocateHandle();
|
| + ref->set_raw(object);
|
| + return reinterpret_cast<Dart_Handle>(ref);
|
| +}
|
| +
|
| +RawObject* Api::UnwrapHandle(Dart_Handle object) {
|
| +#ifdef DEBUG
|
| + Isolate* isolate = Isolate::Current();
|
| + ASSERT(isolate != NULL);
|
| + ApiState* state = isolate->api_state();
|
| + ASSERT(state != NULL);
|
| + ASSERT(state->IsValidPersistentHandle(object) ||
|
| + state->IsValidLocalHandle(object));
|
| + ASSERT(PersistentHandle::raw_offset() == 0 &&
|
| + LocalHandle::raw_offset() == 0);
|
| +#endif
|
| + return *(reinterpret_cast<RawObject**>(object));
|
| +}
|
| +
|
| +#define DEFINE_UNWRAP(Type) \
|
| + const Type& Api::Unwrap##Type##Handle(Dart_Handle dart_handle) { \
|
| + const Object& tmp = Object::Handle(Api::UnwrapHandle(dart_handle)); \
|
| + Type& typed_handle = Type::Handle(); \
|
| + if (tmp.Is##Type()) { \
|
| + typed_handle ^= tmp.raw(); \
|
| + } \
|
| + return typed_handle; \
|
| }
|
| - return false;
|
| +CLASS_LIST_NO_OBJECT(DEFINE_UNWRAP)
|
| +#undef DEFINE_UNWRAP
|
| +
|
| +
|
| +LocalHandle* Api::UnwrapAsLocalHandle(const ApiState& state,
|
| + Dart_Handle object) {
|
| + ASSERT(state.IsValidLocalHandle(object));
|
| + return reinterpret_cast<LocalHandle*>(object);
|
| }
|
|
|
|
|
| -DART_EXPORT Dart_Handle Dart_ErrorGetException(Dart_Handle handle) {
|
| +PersistentHandle* Api::UnwrapAsPersistentHandle(const ApiState& state,
|
| + Dart_Handle object) {
|
| + ASSERT(state.IsValidPersistentHandle(object));
|
| + return reinterpret_cast<PersistentHandle*>(object);
|
| +}
|
| +
|
| +
|
| +Dart_Handle Api::Success() {
|
| + Isolate* isolate = Isolate::Current();
|
| + ASSERT(isolate != NULL);
|
| + ApiState* state = isolate->api_state();
|
| + ASSERT(state != NULL);
|
| + PersistentHandle* true_handle = state->True();
|
| + return reinterpret_cast<Dart_Handle>(true_handle);
|
| +}
|
| +
|
| +
|
| +Dart_Handle Api::Error(const char* format, ...) {
|
| DARTSCOPE(Isolate::Current());
|
| - 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.");
|
| - }
|
| +
|
| + va_list args;
|
| + va_start(args, format);
|
| + intptr_t len = OS::VSNPrint(NULL, 0, format, args);
|
| + va_end(args);
|
| +
|
| + char* buffer = reinterpret_cast<char*>(zone.Allocate(len + 1));
|
| + va_list args2;
|
| + va_start(args2, format);
|
| + OS::VSNPrint(buffer, (len + 1), format, args2);
|
| + va_end(args2);
|
| +
|
| + const String& message = String::Handle(String::New(buffer));
|
| + const Object& obj = Object::Handle(ApiError::New(message));
|
| + return Api::NewLocalHandle(obj);
|
| }
|
|
|
|
|
| -DART_EXPORT Dart_Handle Dart_ErrorGetStacktrace(Dart_Handle handle) {
|
| +Dart_Handle Api::ErrorFromException(const Object& obj) {
|
| DARTSCOPE(Isolate::Current());
|
| - 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.");
|
| - }
|
| +
|
| + 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("Can only get stacktraces from error handles.");
|
| + return Api::Error("Internal error: expected obj.IsUnhandledException().");
|
| }
|
| }
|
|
|
|
|
| -DART_EXPORT void _Dart_ReportErrorHandle(const char* file,
|
| - int line,
|
| - const char* handle,
|
| - const char* message) {
|
| - fprintf(stderr, "%s:%d: error handle: '%s':\n '%s'\n",
|
| - file, line, handle, message);
|
| - OS::Abort();
|
| +Dart_Handle Api::Null() {
|
| + Isolate* isolate = Isolate::Current();
|
| + ASSERT(isolate != NULL);
|
| + ApiState* state = isolate->api_state();
|
| + ASSERT(state != NULL);
|
| + PersistentHandle* null_handle = state->Null();
|
| + return reinterpret_cast<Dart_Handle>(null_handle);
|
| }
|
|
|
|
|
| +Dart_Handle Api::True() {
|
| + Isolate* isolate = Isolate::Current();
|
| + ASSERT(isolate != NULL);
|
| + ApiState* state = isolate->api_state();
|
| + ASSERT(state != NULL);
|
| + PersistentHandle* true_handle = state->True();
|
| + return reinterpret_cast<Dart_Handle>(true_handle);
|
| +}
|
| +
|
| +
|
| +Dart_Handle Api::False() {
|
| + Isolate* isolate = Isolate::Current();
|
| + ASSERT(isolate != NULL);
|
| + ApiState* state = isolate->api_state();
|
| + ASSERT(state != NULL);
|
| + PersistentHandle* false_handle = state->False();
|
| + return reinterpret_cast<Dart_Handle>(false_handle);
|
| +}
|
| +
|
| +
|
| +uword Api::Allocate(intptr_t size) {
|
| + Isolate* isolate = Isolate::Current();
|
| + ASSERT(isolate != NULL);
|
| + ApiState* state = isolate->api_state();
|
| + ASSERT(state != NULL);
|
| + ApiLocalScope* scope = state->top_scope();
|
| + ASSERT(scope != NULL);
|
| + return scope->zone().Allocate(size);
|
| +}
|
| +
|
| +
|
| +uword Api::Reallocate(uword ptr, intptr_t old_size, intptr_t new_size) {
|
| + Isolate* isolate = Isolate::Current();
|
| + ASSERT(isolate != NULL);
|
| + ApiState* state = isolate->api_state();
|
| + ASSERT(state != NULL);
|
| + ApiLocalScope* scope = state->top_scope();
|
| + ASSERT(scope != NULL);
|
| + return scope->zone().Reallocate(ptr, old_size, new_size);
|
| +}
|
| +
|
| +
|
| +// --- Handles ---
|
| +
|
| +
|
| +DART_EXPORT bool Dart_IsError(const Dart_Handle& handle) {
|
| + DARTSCOPE(Isolate::Current());
|
| + const Object& obj = Object::Handle(Api::UnwrapHandle(handle));
|
| + return obj.IsApiError();
|
| +}
|
| +
|
| +
|
| static const char* MakeUnhandledExceptionCString(
|
| const UnhandledException& uhe) {
|
| const Instance& exception = Instance::Handle(uhe.exception());
|
| @@ -181,6 +306,59 @@
|
| }
|
|
|
|
|
| +DART_EXPORT bool Dart_ErrorHasException(Dart_Handle handle) {
|
| + DARTSCOPE(Isolate::Current());
|
| + 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());
|
| + return data.IsUnhandledException();
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +
|
| +DART_EXPORT Dart_Handle Dart_ErrorGetException(Dart_Handle handle) {
|
| + DARTSCOPE(Isolate::Current());
|
| + 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) {
|
| + DARTSCOPE(Isolate::Current());
|
| + 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.");
|
| + }
|
| +}
|
| +
|
| +
|
| // TODO(turnidge): This clonse Api::Error. I need to use va_copy to
|
| // fix this but not sure if it available on all of our builds.
|
| DART_EXPORT Dart_Handle Dart_Error(const char* format, ...) {
|
| @@ -203,6 +381,87 @@
|
| }
|
|
|
|
|
| +DART_EXPORT void _Dart_ReportErrorHandle(const char* file,
|
| + int line,
|
| + const char* handle,
|
| + const char* message) {
|
| + fprintf(stderr, "%s:%d: error handle: '%s':\n '%s'\n",
|
| + file, line, handle, message);
|
| + OS::Abort();
|
| +}
|
| +
|
| +
|
| +DART_EXPORT Dart_Handle Dart_ToString(Dart_Handle object) {
|
| + DARTSCOPE(Isolate::Current());
|
| + const Object& obj = Object::Handle(Api::UnwrapHandle(object));
|
| + Object& result = Object::Handle();
|
| + if (obj.IsString()) {
|
| + result = obj.raw();
|
| + } else if (obj.IsInstance()) {
|
| + Instance& receiver = Instance::Handle();
|
| + receiver ^= obj.raw();
|
| + result = DartLibraryCalls::ToString(receiver);
|
| + if (result.IsUnhandledException()) {
|
| + return Api::ErrorFromException(result);
|
| + }
|
| + } else {
|
| + // This is a VM internal object. Call the C++ method of printing.
|
| + result = String::New(obj.ToCString());
|
| + }
|
| + return Api::NewLocalHandle(result);
|
| +}
|
| +
|
| +
|
| +DART_EXPORT Dart_Handle Dart_IsSame(Dart_Handle obj1, Dart_Handle obj2,
|
| + bool* value) {
|
| + DARTSCOPE(Isolate::Current());
|
| + const Object& expected = Object::Handle(Api::UnwrapHandle(obj1));
|
| + const Object& actual = Object::Handle(Api::UnwrapHandle(obj2));
|
| + *value = (expected.raw() == actual.raw());
|
| + return Api::Success();
|
| +}
|
| +
|
| +
|
| +DART_EXPORT Dart_Handle Dart_NewPersistentHandle(Dart_Handle object) {
|
| + Isolate* isolate = Isolate::Current();
|
| + DARTSCOPE(isolate);
|
| + ApiState* state = isolate->api_state();
|
| + ASSERT(state != NULL);
|
| + const Object& old_ref = Object::Handle(Api::UnwrapHandle(object));
|
| + PersistentHandle* new_ref = state->persistent_handles().AllocateHandle();
|
| + new_ref->set_raw(old_ref);
|
| + return reinterpret_cast<Dart_Handle>(new_ref);
|
| +}
|
| +
|
| +
|
| +DART_EXPORT void Dart_DeletePersistentHandle(Dart_Handle object) {
|
| + Isolate* isolate = Isolate::Current();
|
| + ASSERT(isolate != NULL);
|
| + ApiState* state = isolate->api_state();
|
| + ASSERT(state != NULL);
|
| + PersistentHandle* ref = Api::UnwrapAsPersistentHandle(*state, object);
|
| + ASSERT(!ref->IsProtected());
|
| + if (!ref->IsProtected()) {
|
| + state->persistent_handles().FreeHandle(ref);
|
| + }
|
| +}
|
| +
|
| +
|
| +DART_EXPORT Dart_Handle Dart_MakeWeakPersistentHandle(Dart_Handle object) {
|
| + UNIMPLEMENTED();
|
| + return NULL;
|
| +}
|
| +
|
| +
|
| +DART_EXPORT Dart_Handle Dart_MakePersistentHandle(Dart_Handle object) {
|
| + UNIMPLEMENTED();
|
| + return NULL;
|
| +}
|
| +
|
| +
|
| +// --- Initialization and Globals ---
|
| +
|
| +
|
| // TODO(iposva): This is a placeholder for the eventual external Dart API.
|
| DART_EXPORT bool Dart_Initialize(int argc,
|
| const char** argv,
|
| @@ -211,6 +470,17 @@
|
| }
|
|
|
|
|
| +DART_EXPORT bool Dart_IsVMFlagSet(const char* flag_name) {
|
| + if (Flags::Lookup(flag_name) != NULL) {
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +
|
| +// --- Isolates ---
|
| +
|
| +
|
| DART_EXPORT Dart_Isolate Dart_CreateIsolate(const Dart_Snapshot* snapshot,
|
| void* data) {
|
| Isolate* isolate = Dart::CreateIsolate();
|
| @@ -262,16 +532,40 @@
|
| }
|
|
|
|
|
| -static void SetupErrorResult(Dart_Handle* handle) {
|
| - // Make a copy of the error message as the original message string
|
| - // 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(ApiError::New(error));
|
| - *handle = Api::NewLocalHandle(obj);
|
| +static uint8_t* ApiAllocator(uint8_t* ptr,
|
| + intptr_t old_size,
|
| + intptr_t new_size) {
|
| + uword new_ptr = Api::Reallocate(reinterpret_cast<uword>(ptr),
|
| + old_size,
|
| + new_size);
|
| + return reinterpret_cast<uint8_t*>(new_ptr);
|
| }
|
|
|
|
|
| +DART_EXPORT Dart_Handle Dart_CreateSnapshot(uint8_t** snapshot_buffer,
|
| + intptr_t* snapshot_size) {
|
| + Isolate* isolate = Isolate::Current();
|
| + DARTSCOPE(isolate);
|
| + if (snapshot_buffer == NULL || snapshot_size == NULL) {
|
| + return Api::Error("Invalid input parameters to Dart_CreateSnapshot");
|
| + }
|
| + const char* msg = CheckIsolateState(isolate,
|
| + ClassFinalizer::kGeneratingSnapshot);
|
| + if (msg != NULL) {
|
| + return Api::Error(msg);
|
| + }
|
| + // Since this is only a snapshot the root library should not be set.
|
| + isolate->object_store()->set_root_library(Library::Handle());
|
| + SnapshotWriter writer(true, snapshot_buffer, ApiAllocator);
|
| + writer.WriteFullSnapshot();
|
| + *snapshot_size = writer.Size();
|
| + return Api::Success();
|
| +}
|
| +
|
| +
|
| +// --- Messages and Ports ---
|
| +
|
| +
|
| DART_EXPORT void Dart_SetMessageCallbacks(
|
| Dart_PostMessageCallback post_message_callback,
|
| Dart_ClosePortCallback close_port_callback) {
|
| @@ -350,271 +644,66 @@
|
| }
|
|
|
|
|
| -// 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 CompileSource(Isolate* isolate,
|
| - const Library& lib,
|
| - const String& url,
|
| - const String& source,
|
| - RawScript::Kind kind,
|
| - Dart_Handle* result) {
|
| - bool update_lib_status = (kind == RawScript::kScript ||
|
| - kind == RawScript::kLibrary);
|
| - if (update_lib_status) {
|
| - lib.SetLoadInProgress();
|
| - }
|
| - 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);
|
| - *result = Api::NewLocalHandle(lib);
|
| - if (update_lib_status) {
|
| - lib.SetLoaded();
|
| - }
|
| - } else {
|
| - SetupErrorResult(result);
|
| - if (update_lib_status) {
|
| - lib.SetLoadError();
|
| - }
|
| - }
|
| - isolate->set_long_jump_base(base);
|
| +static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
|
| + void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
|
| + return reinterpret_cast<uint8_t*>(new_ptr);
|
| }
|
|
|
|
|
| -DART_EXPORT Dart_Handle Dart_LoadScript(Dart_Handle url,
|
| - Dart_Handle source,
|
| - Dart_LibraryTagHandler handler) {
|
| - Isolate* isolate = Isolate::Current();
|
| - DARTSCOPE(isolate);
|
| - TIMERSCOPE(time_script_loading);
|
| - const String& url_str = Api::UnwrapStringHandle(url);
|
| - if (url_str.IsNull()) {
|
| - RETURN_TYPE_ERROR(url, String);
|
| - }
|
| - const String& source_str = Api::UnwrapStringHandle(source);
|
| - if (source_str.IsNull()) {
|
| - RETURN_TYPE_ERROR(source, String);
|
| - }
|
| - Library& library = Library::Handle(isolate->object_store()->root_library());
|
| - if (!library.IsNull()) {
|
| - const String& library_url = String::Handle(library.url());
|
| - return Api::Error("%s: A script has already been loaded from '%s'.",
|
| - CURRENT_FUNC, library_url.ToCString());
|
| - }
|
| - isolate->set_library_tag_handler(handler);
|
| - library = Library::New(url_str);
|
| - library.Register();
|
| - isolate->object_store()->set_root_library(library);
|
| - Dart_Handle result;
|
| - CompileSource(isolate,
|
| - library,
|
| - url_str,
|
| - source_str,
|
| - RawScript::kScript,
|
| - &result);
|
| - return result;
|
| -}
|
| +DART_EXPORT bool Dart_PostIntArray(Dart_Port port,
|
| + intptr_t len,
|
| + intptr_t* data) {
|
| + uint8_t* buffer = NULL;
|
| + MessageWriter writer(&buffer, &allocator);
|
|
|
| + writer.WriteMessage(len, data);
|
|
|
| -DEFINE_FLAG(bool, compile_all, false, "Eagerly compile all code.");
|
| -
|
| -static void CompileAll(Isolate* isolate, Dart_Handle* result) {
|
| - *result = Api::Success();
|
| - if (FLAG_compile_all) {
|
| - ASSERT(isolate != NULL);
|
| - LongJump* base = isolate->long_jump_base();
|
| - LongJump jump;
|
| - isolate->set_long_jump_base(&jump);
|
| - if (setjmp(*jump.Set()) == 0) {
|
| - Library::CompileAll();
|
| - } else {
|
| - SetupErrorResult(result);
|
| - }
|
| - isolate->set_long_jump_base(base);
|
| - }
|
| + // Post the message at the given port.
|
| + return PortMap::PostMessage(port, kNoReplyPort, buffer);
|
| }
|
|
|
|
|
| -// Return error if isolate is in an inconsistent state.
|
| -// Return NULL when no error condition exists.
|
| -static const char* CheckIsolateState(
|
| - Isolate* isolate,
|
| - bool generating_snapshot = ClassFinalizer::kNotGeneratingSnapshot) {
|
| - bool result = (generating_snapshot) ?
|
| - ClassFinalizer::FinalizePendingClassesForSnapshotCreation() :
|
| - ClassFinalizer::FinalizePendingClasses();
|
| - if (!result) {
|
| - // Make a copy of the error message as the original message string
|
| - // may get deallocated when we return back from the Dart API call.
|
| - const String& err =
|
| - String::Handle(isolate->object_store()->sticky_error());
|
| - const char* errmsg = err.ToCString();
|
| - intptr_t errlen = strlen(errmsg) + 1;
|
| - char* msg = reinterpret_cast<char*>(Api::Allocate(errlen));
|
| - OS::SNPrint(msg, errlen, "%s", errmsg);
|
| - return msg;
|
| - }
|
| - return NULL;
|
| -}
|
| -
|
| -
|
| -DART_EXPORT Dart_Handle Dart_CompileAll() {
|
| - Isolate* isolate = Isolate::Current();
|
| - DARTSCOPE(isolate);
|
| - Dart_Handle result;
|
| - const char* msg = CheckIsolateState(isolate);
|
| - if (msg != NULL) {
|
| - return Api::Error(msg);
|
| - }
|
| - CompileAll(isolate, &result);
|
| - return result;
|
| -}
|
| -
|
| -
|
| -DART_EXPORT bool Dart_IsLibrary(Dart_Handle object) {
|
| +DART_EXPORT bool Dart_Post(Dart_Port port, Dart_Handle handle) {
|
| DARTSCOPE(Isolate::Current());
|
| - const Object& obj = Object::Handle(Api::UnwrapHandle(object));
|
| - return obj.IsLibrary();
|
| + const Object& object = Object::Handle(Api::UnwrapHandle(handle));
|
| + uint8_t* data = NULL;
|
| + SnapshotWriter writer(false, &data, &allocator);
|
| + writer.WriteObject(object.raw());
|
| + writer.FinalizeBuffer();
|
| + return PortMap::PostMessage(port, kNoReplyPort, data);
|
| }
|
|
|
|
|
| -DART_EXPORT Dart_Handle Dart_LibraryUrl(Dart_Handle library) {
|
| - DARTSCOPE(Isolate::Current());
|
| - const Library& lib = Api::UnwrapLibraryHandle(library);
|
| - if (lib.IsNull()) {
|
| - RETURN_TYPE_ERROR(library, Library);
|
| - }
|
| - const String& url = String::Handle(lib.url());
|
| - ASSERT(!url.IsNull());
|
| - return Api::NewLocalHandle(url);
|
| -}
|
| +// --- Scopes ----
|
|
|
|
|
| -DART_EXPORT Dart_Handle Dart_LibraryImportLibrary(Dart_Handle library,
|
| - Dart_Handle import) {
|
| - DARTSCOPE(Isolate::Current());
|
| - const Library& library_vm = Api::UnwrapLibraryHandle(library);
|
| - if (library_vm.IsNull()) {
|
| - RETURN_TYPE_ERROR(library, Library);
|
| - }
|
| - const Library& import_vm = Api::UnwrapLibraryHandle(import);
|
| - if (import_vm.IsNull()) {
|
| - RETURN_TYPE_ERROR(import, Library);
|
| - }
|
| - library_vm.AddImport(import_vm);
|
| - return Api::Success();
|
| -}
|
| -
|
| -
|
| -DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url) {
|
| - DARTSCOPE(Isolate::Current());
|
| - const String& url_str = Api::UnwrapStringHandle(url);
|
| - if (url_str.IsNull()) {
|
| - RETURN_TYPE_ERROR(url, String);
|
| - }
|
| - const Library& library = Library::Handle(Library::LookupLibrary(url_str));
|
| - if (library.IsNull()) {
|
| - return Api::Error("%s: library '%s' not found.",
|
| - CURRENT_FUNC, url_str.ToCString());
|
| - } else {
|
| - return Api::NewLocalHandle(library);
|
| - }
|
| -}
|
| -
|
| -
|
| -DART_EXPORT Dart_Handle Dart_LoadLibrary(Dart_Handle url, Dart_Handle source) {
|
| +DART_EXPORT void Dart_EnterScope() {
|
| Isolate* isolate = Isolate::Current();
|
| - DARTSCOPE(isolate);
|
| - const String& url_str = Api::UnwrapStringHandle(url);
|
| - if (url_str.IsNull()) {
|
| - RETURN_TYPE_ERROR(url, String);
|
| - }
|
| - const String& source_str = Api::UnwrapStringHandle(source);
|
| - if (source_str.IsNull()) {
|
| - RETURN_TYPE_ERROR(source, String);
|
| - }
|
| - Library& library = Library::Handle(Library::LookupLibrary(url_str));
|
| - if (library.IsNull()) {
|
| - library = Library::New(url_str);
|
| - library.Register();
|
| - } else if (!library.LoadNotStarted()) {
|
| - // The source for this library has either been loaded or is in the
|
| - // process of loading. Return an error.
|
| - return Api::Error("%s: library '%s' has already been loaded.",
|
| - CURRENT_FUNC, url_str.ToCString());
|
| - }
|
| - Dart_Handle result;
|
| - CompileSource(isolate,
|
| - library,
|
| - url_str,
|
| - source_str,
|
| - RawScript::kLibrary,
|
| - &result);
|
| - return result;
|
| + ASSERT(isolate != NULL);
|
| + ApiState* state = isolate->api_state();
|
| + ASSERT(state != NULL);
|
| + ApiLocalScope* new_scope = new ApiLocalScope(state->top_scope(),
|
| + reinterpret_cast<uword>(&state));
|
| + ASSERT(new_scope != NULL);
|
| + state->set_top_scope(new_scope); // New scope is now the top scope.
|
| }
|
|
|
|
|
| -DART_EXPORT Dart_Handle Dart_LoadSource(Dart_Handle library,
|
| - Dart_Handle url,
|
| - Dart_Handle source) {
|
| +DART_EXPORT void Dart_ExitScope() {
|
| Isolate* isolate = Isolate::Current();
|
| - DARTSCOPE(isolate);
|
| - const Library& lib = Api::UnwrapLibraryHandle(library);
|
| - if (lib.IsNull()) {
|
| - RETURN_TYPE_ERROR(library, Library);
|
| - }
|
| - const String& url_str = Api::UnwrapStringHandle(url);
|
| - if (url_str.IsNull()) {
|
| - RETURN_TYPE_ERROR(url, String);
|
| - }
|
| - const String& source_str = Api::UnwrapStringHandle(source);
|
| - if (source_str.IsNull()) {
|
| - RETURN_TYPE_ERROR(source, String);
|
| - }
|
| - Dart_Handle result;
|
| - CompileSource(isolate, lib, url_str, source_str, RawScript::kSource, &result);
|
| - return result;
|
| + ASSERT(isolate != NULL);
|
| + ApiState* state = isolate->api_state();
|
| + ASSERT(state != NULL);
|
| + ApiLocalScope* scope = state->top_scope();
|
| + ASSERT(scope != NULL);
|
| + state->set_top_scope(scope->previous()); // Reset top scope to previous.
|
| + delete scope; // Free up the old scope which we have just exited.
|
| }
|
|
|
|
|
| -DART_EXPORT Dart_Handle Dart_SetNativeResolver(
|
| - Dart_Handle library,
|
| - Dart_NativeEntryResolver resolver) {
|
| - DARTSCOPE(Isolate::Current());
|
| - const Library& lib = Api::UnwrapLibraryHandle(library);
|
| - if (lib.IsNull()) {
|
| - RETURN_TYPE_ERROR(library, Library);
|
| - }
|
| - lib.set_native_entry_resolver(resolver);
|
| - return Api::Success();
|
| -}
|
| +// --- Objects ----
|
|
|
|
|
| -DART_EXPORT Dart_Handle Dart_ToString(Dart_Handle object) {
|
| - DARTSCOPE(Isolate::Current());
|
| - const Object& obj = Object::Handle(Api::UnwrapHandle(object));
|
| - Object& result = Object::Handle();
|
| - if (obj.IsString()) {
|
| - result = obj.raw();
|
| - } else if (obj.IsInstance()) {
|
| - Instance& receiver = Instance::Handle();
|
| - receiver ^= obj.raw();
|
| - result = DartLibraryCalls::ToString(receiver);
|
| - if (result.IsUnhandledException()) {
|
| - return Api::ErrorFromException(result);
|
| - }
|
| - } else {
|
| - // This is a VM internal object. Call the C++ method of printing.
|
| - result = String::New(obj.ToCString());
|
| - }
|
| - return Api::NewLocalHandle(result);
|
| -}
|
| -
|
| -
|
| DART_EXPORT Dart_Handle Dart_Null() {
|
| return Api::Null();
|
| }
|
| @@ -627,29 +716,6 @@
|
| }
|
|
|
|
|
| -DART_EXPORT bool Dart_IsClosure(Dart_Handle object) {
|
| - DARTSCOPE(Isolate::Current());
|
| - const Object& obj = Object::Handle(Api::UnwrapHandle(object));
|
| - return obj.IsClosure();
|
| -}
|
| -
|
| -
|
| -DART_EXPORT int64_t Dart_ClosureSmrck(Dart_Handle object) {
|
| - DARTSCOPE(Isolate::Current());
|
| - const Closure& obj = Closure::CheckedHandle(Api::UnwrapHandle(object));
|
| - const Integer& smrck = Integer::Handle(obj.smrck());
|
| - return smrck.IsNull() ? 0 : smrck.AsInt64Value();
|
| -}
|
| -
|
| -
|
| -DART_EXPORT void Dart_ClosureSetSmrck(Dart_Handle object, int64_t value) {
|
| - DARTSCOPE(Isolate::Current());
|
| - const Closure& obj = Closure::CheckedHandle(Api::UnwrapHandle(object));
|
| - const Integer& smrck = Integer::Handle(Integer::New(value));
|
| - obj.set_smrck(smrck);
|
| -}
|
| -
|
| -
|
| DART_EXPORT Dart_Handle Dart_ObjectEquals(Dart_Handle obj1, Dart_Handle obj2,
|
| bool* value) {
|
| DARTSCOPE(Isolate::Current());
|
| @@ -670,38 +736,6 @@
|
| }
|
|
|
|
|
| -DART_EXPORT Dart_Handle Dart_IsSame(Dart_Handle obj1, Dart_Handle obj2,
|
| - bool* value) {
|
| - DARTSCOPE(Isolate::Current());
|
| - const Object& expected = Object::Handle(Api::UnwrapHandle(obj1));
|
| - const Object& actual = Object::Handle(Api::UnwrapHandle(obj2));
|
| - *value = (expected.raw() == actual.raw());
|
| - return Api::Success();
|
| -}
|
| -
|
| -
|
| -DART_EXPORT Dart_Handle Dart_GetClass(Dart_Handle library, Dart_Handle name) {
|
| - DARTSCOPE(Isolate::Current());
|
| - const Object& param = Object::Handle(Api::UnwrapHandle(name));
|
| - if (param.IsNull() || !param.IsString()) {
|
| - return Api::Error("Invalid class name specified");
|
| - }
|
| - const Library& lib = Library::CheckedHandle(Api::UnwrapHandle(library));
|
| - if (lib.IsNull()) {
|
| - return Api::Error("Invalid parameter, Unknown library specified");
|
| - }
|
| - String& cls_name = String::Handle();
|
| - cls_name ^= param.raw();
|
| - const Class& cls = Class::Handle(lib.LookupClass(cls_name));
|
| - if (cls.IsNull()) {
|
| - const String& lib_name = String::Handle(lib.name());
|
| - return Api::Error("Class '%s' not found in library '%s'.",
|
| - cls_name.ToCString(), lib_name.ToCString());
|
| - }
|
| - return Api::NewLocalHandle(cls);
|
| -}
|
| -
|
| -
|
| // TODO(iposva): This call actually implements IsInstanceOfClass.
|
| // Do we also need a real Dart_IsInstanceOf, which should take an instance
|
| // rather than an object and a type rather than a class?
|
| @@ -728,6 +762,9 @@
|
| }
|
|
|
|
|
| +// --- Numbers ----
|
| +
|
| +
|
| // TODO(iposva): The argument should be an instance.
|
| DART_EXPORT bool Dart_IsNumber(Dart_Handle object) {
|
| DARTSCOPE(Isolate::Current());
|
| @@ -736,6 +773,9 @@
|
| }
|
|
|
|
|
| +// --- Integers ----
|
| +
|
| +
|
| DART_EXPORT bool Dart_IsInteger(Dart_Handle object) {
|
| DARTSCOPE(Isolate::Current());
|
| const Object& obj = Object::Handle(Api::UnwrapHandle(object));
|
| @@ -743,6 +783,26 @@
|
| }
|
|
|
|
|
| +DART_EXPORT Dart_Handle Dart_IntegerFitsIntoInt64(Dart_Handle integer,
|
| + bool* fits) {
|
| + DARTSCOPE(Isolate::Current());
|
| + const Object& obj = Object::Handle(Api::UnwrapHandle(integer));
|
| + if (obj.IsSmi() || obj.IsMint()) {
|
| + *fits = true;
|
| + return Api::Success();
|
| + } else if (obj.IsBigint()) {
|
| +#if defined(DEBUG)
|
| + Bigint& bigint = Bigint::Handle();
|
| + bigint ^= obj.raw();
|
| + ASSERT(!BigintOperations::FitsIntoInt64(bigint));
|
| +#endif
|
| + *fits = false;
|
| + return Api::Success();
|
| + }
|
| + return Api::Error("Object is not a Integer");
|
| +}
|
| +
|
| +
|
| DART_EXPORT Dart_Handle Dart_NewInteger(int64_t value) {
|
| DARTSCOPE(Isolate::Current());
|
| const Integer& obj = Integer::Handle(Integer::New(value));
|
| @@ -802,24 +862,7 @@
|
| }
|
|
|
|
|
| -DART_EXPORT Dart_Handle Dart_IntegerFitsIntoInt64(Dart_Handle integer,
|
| - bool* fits) {
|
| - DARTSCOPE(Isolate::Current());
|
| - const Object& obj = Object::Handle(Api::UnwrapHandle(integer));
|
| - if (obj.IsSmi() || obj.IsMint()) {
|
| - *fits = true;
|
| - return Api::Success();
|
| - } else if (obj.IsBigint()) {
|
| -#if defined(DEBUG)
|
| - Bigint& bigint = Bigint::Handle();
|
| - bigint ^= obj.raw();
|
| - ASSERT(!BigintOperations::FitsIntoInt64(bigint));
|
| -#endif
|
| - *fits = false;
|
| - return Api::Success();
|
| - }
|
| - return Api::Error("Object is not a Integer");
|
| -}
|
| +// --- Booleans ----
|
|
|
|
|
| DART_EXPORT Dart_Handle Dart_True() {
|
| @@ -858,6 +901,9 @@
|
| }
|
|
|
|
|
| +// --- Doubles ---
|
| +
|
| +
|
| DART_EXPORT bool Dart_IsDouble(Dart_Handle object) {
|
| DARTSCOPE(Isolate::Current());
|
| const Object& obj = Object::Handle(Api::UnwrapHandle(object));
|
| @@ -885,6 +931,9 @@
|
| }
|
|
|
|
|
| +// --- Strings ---
|
| +
|
| +
|
| DART_EXPORT bool Dart_IsString(Dart_Handle object) {
|
| DARTSCOPE(Isolate::Current());
|
| const Object& obj = Object::Handle(Api::UnwrapHandle(object));
|
| @@ -892,6 +941,21 @@
|
| }
|
|
|
|
|
| +DART_EXPORT bool Dart_IsString8(Dart_Handle object) {
|
| + DARTSCOPE(Isolate::Current());
|
| + const Object& obj = Object::Handle(Api::UnwrapHandle(object));
|
| + return obj.IsOneByteString() || obj.IsExternalOneByteString();
|
| +}
|
| +
|
| +
|
| +DART_EXPORT bool Dart_IsString16(Dart_Handle object) {
|
| + DARTSCOPE(Isolate::Current());
|
| + const Object& obj = Object::Handle(Api::UnwrapHandle(object));
|
| + return (obj.IsOneByteString() || obj.IsExternalOneByteString() ||
|
| + obj.IsTwoByteString() || obj.IsExternalTwoByteString());
|
| +}
|
| +
|
| +
|
| DART_EXPORT Dart_Handle Dart_StringLength(Dart_Handle str, intptr_t* len) {
|
| DARTSCOPE(Isolate::Current());
|
| const Object& obj = Object::Handle(Api::UnwrapHandle(str));
|
| @@ -969,21 +1033,6 @@
|
| }
|
|
|
|
|
| -DART_EXPORT bool Dart_IsString8(Dart_Handle object) {
|
| - DARTSCOPE(Isolate::Current());
|
| - const Object& obj = Object::Handle(Api::UnwrapHandle(object));
|
| - return obj.IsOneByteString() || obj.IsExternalOneByteString();
|
| -}
|
| -
|
| -
|
| -DART_EXPORT bool Dart_IsString16(Dart_Handle object) {
|
| - DARTSCOPE(Isolate::Current());
|
| - const Object& obj = Object::Handle(Api::UnwrapHandle(object));
|
| - return (obj.IsOneByteString() || obj.IsExternalOneByteString() ||
|
| - obj.IsTwoByteString() || obj.IsExternalTwoByteString());
|
| -}
|
| -
|
| -
|
| DART_EXPORT Dart_Handle Dart_StringGet8(Dart_Handle str,
|
| uint8_t* codepoints,
|
| intptr_t* length) {
|
| @@ -1072,6 +1121,9 @@
|
| }
|
|
|
|
|
| +// --- Lists ---
|
| +
|
| +
|
| static RawInstance* GetListInstance(Isolate* isolate, const Object& obj) {
|
| if (obj.IsInstance()) {
|
| Instance& instance = Instance::Handle();
|
| @@ -1194,69 +1246,6 @@
|
| }
|
|
|
|
|
| -DART_EXPORT Dart_Handle Dart_ListGetAsBytes(Dart_Handle list,
|
| - intptr_t offset,
|
| - uint8_t* native_array,
|
| - intptr_t length) {
|
| - Isolate* isolate = Isolate::Current();
|
| - DARTSCOPE(isolate);
|
| - const Object& obj = Object::Handle(Api::UnwrapHandle(list));
|
| - if (obj.IsArray()) {
|
| - Array& array_obj = Array::Handle();
|
| - array_obj ^= obj.raw();
|
| - if ((offset + length) <= array_obj.Length()) {
|
| - Object& element = Object::Handle();
|
| - Integer& integer = Integer::Handle();
|
| - for (int i = 0; i < length; i++) {
|
| - element = array_obj.At(offset + i);
|
| - if (!element.IsInteger()) {
|
| - return Api::Error("%s expects the argument 'list' to be "
|
| - "a List of int", CURRENT_FUNC);
|
| - }
|
| - integer ^= element.raw();
|
| - native_array[i] = static_cast<uint8_t>(integer.AsInt64Value() & 0xff);
|
| - ASSERT(integer.AsInt64Value() <= 0xff);
|
| - // TODO(hpayer): value should always be smaller then 0xff. Add error
|
| - // handling.
|
| - }
|
| - return Api::Success();
|
| - }
|
| - return Api::Error("Invalid length passed in to access array elements");
|
| - }
|
| - // 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("[]"));
|
| - const Function& function = Function::Handle(
|
| - Resolver::ResolveDynamic(instance, name, 2, 0));
|
| - if (!function.IsNull()) {
|
| - Object& element = Object::Handle();
|
| - Integer& intobj = Integer::Handle();
|
| - Dart_Handle result;
|
| - for (int i = 0; i < length; i++) {
|
| - intobj = Integer::New(offset + i);
|
| - element = GetListAt(isolate, instance, intobj, function, &result);
|
| - if (Dart_IsError(result)) {
|
| - return result; // Error condition.
|
| - }
|
| - if (!element.IsInteger()) {
|
| - return Api::Error("%s expects the argument 'list' to be "
|
| - "a List of int", CURRENT_FUNC);
|
| - }
|
| - intobj ^= element.raw();
|
| - ASSERT(intobj.AsInt64Value() <= 0xff);
|
| - // TODO(hpayer): value should always be smaller then 0xff. Add error
|
| - // handling.
|
| - native_array[i] = static_cast<uint8_t>(intobj.AsInt64Value() & 0xff);
|
| - }
|
| - return Api::Success();
|
| - }
|
| - }
|
| - return Api::Error("Object does not implement the 'List' interface");
|
| -}
|
| -
|
| -
|
| DART_EXPORT Dart_Handle Dart_ListGetAt(Dart_Handle list, intptr_t index) {
|
| Isolate* isolate = Isolate::Current();
|
| DARTSCOPE(isolate);
|
| @@ -1326,10 +1315,9 @@
|
| }
|
|
|
|
|
| -DART_EXPORT Dart_Handle Dart_ListSetAsBytes(Dart_Handle list,
|
| - intptr_t offset,
|
| - uint8_t* native_array,
|
| - intptr_t length) {
|
| +DART_EXPORT Dart_Handle Dart_ListSetAt(Dart_Handle list,
|
| + intptr_t index,
|
| + Dart_Handle value) {
|
| Isolate* isolate = Isolate::Current();
|
| DARTSCOPE(isolate);
|
| const Object& obj = Object::Handle(Api::UnwrapHandle(list));
|
| @@ -1339,34 +1327,87 @@
|
| }
|
| Array& array_obj = Array::Handle();
|
| array_obj ^= obj.raw();
|
| - Integer& integer = Integer::Handle();
|
| + const Object& value_obj = Object::Handle(Api::UnwrapHandle(value));
|
| + if ((index >= 0) && (index < array_obj.Length())) {
|
| + array_obj.SetAt(index, value_obj);
|
| + return Api::Success();
|
| + }
|
| + return Api::Error("Invalid index passed in to set array element");
|
| + }
|
| + // 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("[]="));
|
| + const Function& function = Function::Handle(
|
| + Resolver::ResolveDynamic(instance, name, 3, 0));
|
| + if (!function.IsNull()) {
|
| + Dart_Handle result;
|
| + const Integer& index_obj = Integer::Handle(Integer::New(index));
|
| + const Object& value_obj = Object::Handle(Api::UnwrapHandle(value));
|
| + SetListAt(isolate, instance, index_obj, value_obj, function, &result);
|
| + return result;
|
| + }
|
| + }
|
| + return Api::Error("Object does not implement the 'List' interface");
|
| +}
|
| +
|
| +
|
| +DART_EXPORT Dart_Handle Dart_ListGetAsBytes(Dart_Handle list,
|
| + intptr_t offset,
|
| + uint8_t* native_array,
|
| + intptr_t length) {
|
| + Isolate* isolate = Isolate::Current();
|
| + DARTSCOPE(isolate);
|
| + const Object& obj = Object::Handle(Api::UnwrapHandle(list));
|
| + if (obj.IsArray()) {
|
| + Array& array_obj = Array::Handle();
|
| + array_obj ^= obj.raw();
|
| if ((offset + length) <= array_obj.Length()) {
|
| + Object& element = Object::Handle();
|
| + Integer& integer = Integer::Handle();
|
| for (int i = 0; i < length; i++) {
|
| - integer = Integer::New(native_array[i]);
|
| - array_obj.SetAt(offset + i, integer);
|
| + element = array_obj.At(offset + i);
|
| + if (!element.IsInteger()) {
|
| + return Api::Error("%s expects the argument 'list' to be "
|
| + "a List of int", CURRENT_FUNC);
|
| + }
|
| + integer ^= element.raw();
|
| + native_array[i] = static_cast<uint8_t>(integer.AsInt64Value() & 0xff);
|
| + ASSERT(integer.AsInt64Value() <= 0xff);
|
| + // TODO(hpayer): value should always be smaller then 0xff. Add error
|
| + // handling.
|
| }
|
| return Api::Success();
|
| }
|
| - return Api::Error("Invalid length passed in to set array elements");
|
| + return Api::Error("Invalid length passed in to access array elements");
|
| }
|
| // 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("[]="));
|
| + String& name = String::Handle(String::New("[]"));
|
| const Function& function = Function::Handle(
|
| - Resolver::ResolveDynamic(instance, name, 3, 0));
|
| + Resolver::ResolveDynamic(instance, name, 2, 0));
|
| if (!function.IsNull()) {
|
| - Integer& indexobj = Integer::Handle();
|
| - Integer& valueobj = Integer::Handle();
|
| + Object& element = Object::Handle();
|
| + Integer& intobj = Integer::Handle();
|
| Dart_Handle result;
|
| for (int i = 0; i < length; i++) {
|
| - indexobj = Integer::New(offset + i);
|
| - valueobj = Integer::New(native_array[i]);
|
| - SetListAt(isolate, instance, indexobj, valueobj, function, &result);
|
| + intobj = Integer::New(offset + i);
|
| + element = GetListAt(isolate, instance, intobj, function, &result);
|
| if (Dart_IsError(result)) {
|
| return result; // Error condition.
|
| }
|
| + if (!element.IsInteger()) {
|
| + return Api::Error("%s expects the argument 'list' to be "
|
| + "a List of int", CURRENT_FUNC);
|
| + }
|
| + intobj ^= element.raw();
|
| + ASSERT(intobj.AsInt64Value() <= 0xff);
|
| + // TODO(hpayer): value should always be smaller then 0xff. Add error
|
| + // handling.
|
| + native_array[i] = static_cast<uint8_t>(intobj.AsInt64Value() & 0xff);
|
| }
|
| return Api::Success();
|
| }
|
| @@ -1375,9 +1416,10 @@
|
| }
|
|
|
|
|
| -DART_EXPORT Dart_Handle Dart_ListSetAt(Dart_Handle list,
|
| - intptr_t index,
|
| - Dart_Handle value) {
|
| +DART_EXPORT Dart_Handle Dart_ListSetAsBytes(Dart_Handle list,
|
| + intptr_t offset,
|
| + uint8_t* native_array,
|
| + intptr_t length) {
|
| Isolate* isolate = Isolate::Current();
|
| DARTSCOPE(isolate);
|
| const Object& obj = Object::Handle(Api::UnwrapHandle(list));
|
| @@ -1387,12 +1429,15 @@
|
| }
|
| Array& array_obj = Array::Handle();
|
| array_obj ^= obj.raw();
|
| - const Object& value_obj = Object::Handle(Api::UnwrapHandle(value));
|
| - if ((index >= 0) && (index < array_obj.Length())) {
|
| - array_obj.SetAt(index, value_obj);
|
| + Integer& integer = Integer::Handle();
|
| + if ((offset + length) <= array_obj.Length()) {
|
| + for (int i = 0; i < length; i++) {
|
| + integer = Integer::New(native_array[i]);
|
| + array_obj.SetAt(offset + i, integer);
|
| + }
|
| return Api::Success();
|
| }
|
| - return Api::Error("Invalid index passed in to set array element");
|
| + return Api::Error("Invalid length passed in to set array elements");
|
| }
|
| // TODO(5526318): Make access to GrowableObjectArray more efficient.
|
| // Now check and handle a dart object that implements the List interface.
|
| @@ -1402,24 +1447,41 @@
|
| const Function& function = Function::Handle(
|
| Resolver::ResolveDynamic(instance, name, 3, 0));
|
| if (!function.IsNull()) {
|
| + Integer& indexobj = Integer::Handle();
|
| + Integer& valueobj = Integer::Handle();
|
| Dart_Handle result;
|
| - const Integer& index_obj = Integer::Handle(Integer::New(index));
|
| - const Object& value_obj = Object::Handle(Api::UnwrapHandle(value));
|
| - SetListAt(isolate, instance, index_obj, value_obj, function, &result);
|
| - return result;
|
| + for (int i = 0; i < length; i++) {
|
| + indexobj = Integer::New(offset + i);
|
| + valueobj = Integer::New(native_array[i]);
|
| + SetListAt(isolate, instance, indexobj, valueobj, function, &result);
|
| + if (Dart_IsError(result)) {
|
| + return result; // Error condition.
|
| + }
|
| + }
|
| + return Api::Success();
|
| }
|
| }
|
| return Api::Error("Object does not implement the 'List' interface");
|
| }
|
|
|
|
|
| +// --- Closures ---
|
| +
|
| +
|
| +DART_EXPORT bool Dart_IsClosure(Dart_Handle object) {
|
| + DARTSCOPE(Isolate::Current());
|
| + const Object& obj = Object::Handle(Api::UnwrapHandle(object));
|
| + return obj.IsClosure();
|
| +}
|
| +
|
| +
|
| // 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) {
|
| +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;
|
| @@ -1427,7 +1489,7 @@
|
| if (setjmp(*jump.Set()) == 0) {
|
| const Array& kNoArgumentNames = Array::Handle();
|
| const Instance& retval = Instance::Handle(
|
| - DartEntry::InvokeStatic(function, args, kNoArgumentNames));
|
| + DartEntry::InvokeClosure(closure, args, kNoArgumentNames));
|
| if (retval.IsUnhandledException()) {
|
| *result = Api::ErrorFromException(retval);
|
| } else {
|
| @@ -1440,14 +1502,60 @@
|
| }
|
|
|
|
|
| +DART_EXPORT Dart_Handle Dart_InvokeClosure(Dart_Handle closure,
|
| + int number_of_arguments,
|
| + Dart_Handle* arguments) {
|
| + Isolate* isolate = Isolate::Current();
|
| + DARTSCOPE(isolate);
|
| + const Object& obj = Object::Handle(Api::UnwrapHandle(closure));
|
| + if (obj.IsNull()) {
|
| + return Api::Error("Null object passed in to invoke closure");
|
| + }
|
| + if (!obj.IsClosure()) {
|
| + return Api::Error("Invalid closure passed to invoke closure");
|
| + }
|
| + ASSERT(ClassFinalizer::AllClassesFinalized());
|
| +
|
| + // 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;
|
| +}
|
| +
|
| +
|
| +DART_EXPORT int64_t Dart_ClosureSmrck(Dart_Handle object) {
|
| + DARTSCOPE(Isolate::Current());
|
| + const Closure& obj = Closure::CheckedHandle(Api::UnwrapHandle(object));
|
| + const Integer& smrck = Integer::Handle(obj.smrck());
|
| + return smrck.IsNull() ? 0 : smrck.AsInt64Value();
|
| +}
|
| +
|
| +
|
| +DART_EXPORT void Dart_ClosureSetSmrck(Dart_Handle object, int64_t value) {
|
| + DARTSCOPE(Isolate::Current());
|
| + const Closure& obj = Closure::CheckedHandle(Api::UnwrapHandle(object));
|
| + const Integer& smrck = Integer::Handle(Integer::New(value));
|
| + obj.set_smrck(smrck);
|
| +}
|
| +
|
| +
|
| +// --- Methods and Fields ---
|
| +
|
| +
|
| // 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) {
|
| +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;
|
| @@ -1455,7 +1563,7 @@
|
| if (setjmp(*jump.Set()) == 0) {
|
| const Array& kNoArgumentNames = Array::Handle();
|
| const Instance& retval = Instance::Handle(
|
| - DartEntry::InvokeDynamic(receiver, function, args, kNoArgumentNames));
|
| + DartEntry::InvokeStatic(function, args, kNoArgumentNames));
|
| if (retval.IsUnhandledException()) {
|
| *result = Api::ErrorFromException(retval);
|
| } else {
|
| @@ -1471,8 +1579,9 @@
|
| // 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,
|
| +static void InvokeDynamic(Isolate* isolate,
|
| + const Instance& receiver,
|
| + const Function& function,
|
| GrowableArray<const Object*>& args,
|
| Dart_Handle* result) {
|
| ASSERT(isolate != NULL);
|
| @@ -1482,7 +1591,7 @@
|
| if (setjmp(*jump.Set()) == 0) {
|
| const Array& kNoArgumentNames = Array::Handle();
|
| const Instance& retval = Instance::Handle(
|
| - DartEntry::InvokeClosure(closure, args, kNoArgumentNames));
|
| + DartEntry::InvokeDynamic(receiver, function, args, kNoArgumentNames));
|
| if (retval.IsUnhandledException()) {
|
| *result = Api::ErrorFromException(retval);
|
| } else {
|
| @@ -1598,159 +1707,6 @@
|
| }
|
|
|
|
|
| -DART_EXPORT Dart_Handle Dart_InvokeClosure(Dart_Handle closure,
|
| - int number_of_arguments,
|
| - Dart_Handle* arguments) {
|
| - Isolate* isolate = Isolate::Current();
|
| - DARTSCOPE(isolate);
|
| - const Object& obj = Object::Handle(Api::UnwrapHandle(closure));
|
| - if (obj.IsNull()) {
|
| - return Api::Error("Null object passed in to invoke closure");
|
| - }
|
| - if (!obj.IsClosure()) {
|
| - return Api::Error("Invalid closure passed to invoke closure");
|
| - }
|
| - ASSERT(ClassFinalizer::AllClassesFinalized());
|
| -
|
| - // 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;
|
| -}
|
| -
|
| -
|
| -DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args,
|
| - int index) {
|
| - DARTSCOPE(Isolate::Current());
|
| - NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
|
| - const Object& obj = Object::Handle(arguments->At(index));
|
| - return Api::NewLocalHandle(obj);
|
| -}
|
| -
|
| -
|
| -DART_EXPORT int Dart_GetNativeArgumentCount(Dart_NativeArguments args) {
|
| - NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
|
| - return arguments->Count();
|
| -}
|
| -
|
| -
|
| -DART_EXPORT void Dart_SetReturnValue(Dart_NativeArguments args,
|
| - Dart_Handle retval) {
|
| - DARTSCOPE(Isolate::Current());
|
| - NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
|
| - arguments->SetReturn(Object::Handle(Api::UnwrapHandle(retval)));
|
| -}
|
| -
|
| -
|
| -DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception) {
|
| - Isolate* isolate = Isolate::Current();
|
| - DARTSCOPE(isolate);
|
| - if (isolate->top_exit_frame_info() == 0) {
|
| - // There are no dart frames on the stack so it would be illegal to
|
| - // throw an exception here.
|
| - return Api::Error("No Dart frames on stack, cannot throw exception");
|
| - }
|
| - const Instance& excp = Instance::CheckedHandle(Api::UnwrapHandle(exception));
|
| - // Unwind all the API scopes till the exit frame before throwing an
|
| - // exception.
|
| - ApiState* state = isolate->api_state();
|
| - ASSERT(state != NULL);
|
| - state->UnwindScopes(isolate->top_exit_frame_info());
|
| - Exceptions::Throw(excp);
|
| - return Api::Error("Exception was not thrown, internal error");
|
| -}
|
| -
|
| -
|
| -DART_EXPORT Dart_Handle Dart_ReThrowException(Dart_Handle exception,
|
| - Dart_Handle stacktrace) {
|
| - Isolate* isolate = Isolate::Current();
|
| - ASSERT(isolate != NULL);
|
| - if (isolate->top_exit_frame_info() == 0) {
|
| - // There are no dart frames on the stack so it would be illegal to
|
| - // throw an exception here.
|
| - return Api::Error("No Dart frames on stack, cannot throw exception");
|
| - }
|
| - DARTSCOPE(isolate);
|
| - const Instance& excp = Instance::CheckedHandle(Api::UnwrapHandle(exception));
|
| - const Instance& stk = Instance::CheckedHandle(Api::UnwrapHandle(stacktrace));
|
| - // Unwind all the API scopes till the exit frame before throwing an
|
| - // exception.
|
| - ApiState* state = isolate->api_state();
|
| - ASSERT(state != NULL);
|
| - state->UnwindScopes(isolate->top_exit_frame_info());
|
| - Exceptions::ReThrow(excp, stk);
|
| - return Api::Error("Exception was not re thrown, internal error");
|
| -}
|
| -
|
| -
|
| -DART_EXPORT void Dart_EnterScope() {
|
| - Isolate* isolate = Isolate::Current();
|
| - ASSERT(isolate != NULL);
|
| - ApiState* state = isolate->api_state();
|
| - ASSERT(state != NULL);
|
| - ApiLocalScope* new_scope = new ApiLocalScope(state->top_scope(),
|
| - reinterpret_cast<uword>(&state));
|
| - ASSERT(new_scope != NULL);
|
| - state->set_top_scope(new_scope); // New scope is now the top scope.
|
| -}
|
| -
|
| -
|
| -DART_EXPORT void Dart_ExitScope() {
|
| - Isolate* isolate = Isolate::Current();
|
| - ASSERT(isolate != NULL);
|
| - ApiState* state = isolate->api_state();
|
| - ASSERT(state != NULL);
|
| - ApiLocalScope* scope = state->top_scope();
|
| - ASSERT(scope != NULL);
|
| - state->set_top_scope(scope->previous()); // Reset top scope to previous.
|
| - delete scope; // Free up the old scope which we have just exited.
|
| -}
|
| -
|
| -
|
| -DART_EXPORT Dart_Handle Dart_NewPersistentHandle(Dart_Handle object) {
|
| - Isolate* isolate = Isolate::Current();
|
| - DARTSCOPE(isolate);
|
| - ApiState* state = isolate->api_state();
|
| - ASSERT(state != NULL);
|
| - const Object& old_ref = Object::Handle(Api::UnwrapHandle(object));
|
| - PersistentHandle* new_ref = state->persistent_handles().AllocateHandle();
|
| - new_ref->set_raw(old_ref);
|
| - return reinterpret_cast<Dart_Handle>(new_ref);
|
| -}
|
| -
|
| -
|
| -DART_EXPORT Dart_Handle Dart_MakeWeakPersistentHandle(Dart_Handle object) {
|
| - UNIMPLEMENTED();
|
| - return NULL;
|
| -}
|
| -
|
| -
|
| -DART_EXPORT Dart_Handle Dart_MakePersistentHandle(Dart_Handle object) {
|
| - UNIMPLEMENTED();
|
| - return NULL;
|
| -}
|
| -
|
| -
|
| -DART_EXPORT void Dart_DeletePersistentHandle(Dart_Handle object) {
|
| - Isolate* isolate = Isolate::Current();
|
| - ASSERT(isolate != NULL);
|
| - ApiState* state = isolate->api_state();
|
| - ASSERT(state != NULL);
|
| - PersistentHandle* ref = Api::UnwrapAsPersistentHandle(*state, object);
|
| - ASSERT(!ref->IsProtected());
|
| - if (!ref->IsProtected()) {
|
| - state->persistent_handles().FreeHandle(ref);
|
| - }
|
| -}
|
| -
|
| -
|
| static const bool kGetter = true;
|
| static const bool kSetter = false;
|
|
|
| @@ -1998,252 +1954,350 @@
|
| }
|
|
|
|
|
| -static uint8_t* ApiAllocator(uint8_t* ptr,
|
| - intptr_t old_size,
|
| - intptr_t new_size) {
|
| - uword new_ptr = Api::Reallocate(reinterpret_cast<uword>(ptr),
|
| - old_size,
|
| - new_size);
|
| - return reinterpret_cast<uint8_t*>(new_ptr);
|
| -}
|
| +// --- Exceptions ----
|
|
|
|
|
| -DART_EXPORT Dart_Handle Dart_CreateSnapshot(uint8_t** snapshot_buffer,
|
| - intptr_t* snapshot_size) {
|
| +DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception) {
|
| Isolate* isolate = Isolate::Current();
|
| DARTSCOPE(isolate);
|
| - if (snapshot_buffer == NULL || snapshot_size == NULL) {
|
| - return Api::Error("Invalid input parameters to Dart_CreateSnapshot");
|
| + if (isolate->top_exit_frame_info() == 0) {
|
| + // There are no dart frames on the stack so it would be illegal to
|
| + // throw an exception here.
|
| + return Api::Error("No Dart frames on stack, cannot throw exception");
|
| }
|
| - const char* msg = CheckIsolateState(isolate,
|
| - ClassFinalizer::kGeneratingSnapshot);
|
| - if (msg != NULL) {
|
| - return Api::Error(msg);
|
| - }
|
| - // Since this is only a snapshot the root library should not be set.
|
| - isolate->object_store()->set_root_library(Library::Handle());
|
| - SnapshotWriter writer(true, snapshot_buffer, ApiAllocator);
|
| - writer.WriteFullSnapshot();
|
| - *snapshot_size = writer.Size();
|
| - return Api::Success();
|
| + const Instance& excp = Instance::CheckedHandle(Api::UnwrapHandle(exception));
|
| + // Unwind all the API scopes till the exit frame before throwing an
|
| + // exception.
|
| + ApiState* state = isolate->api_state();
|
| + ASSERT(state != NULL);
|
| + state->UnwindScopes(isolate->top_exit_frame_info());
|
| + Exceptions::Throw(excp);
|
| + return Api::Error("Exception was not thrown, internal error");
|
| }
|
|
|
|
|
| -static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
|
| - void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
|
| - return reinterpret_cast<uint8_t*>(new_ptr);
|
| +DART_EXPORT Dart_Handle Dart_ReThrowException(Dart_Handle exception,
|
| + Dart_Handle stacktrace) {
|
| + Isolate* isolate = Isolate::Current();
|
| + ASSERT(isolate != NULL);
|
| + if (isolate->top_exit_frame_info() == 0) {
|
| + // There are no dart frames on the stack so it would be illegal to
|
| + // throw an exception here.
|
| + return Api::Error("No Dart frames on stack, cannot throw exception");
|
| + }
|
| + DARTSCOPE(isolate);
|
| + const Instance& excp = Instance::CheckedHandle(Api::UnwrapHandle(exception));
|
| + const Instance& stk = Instance::CheckedHandle(Api::UnwrapHandle(stacktrace));
|
| + // Unwind all the API scopes till the exit frame before throwing an
|
| + // exception.
|
| + ApiState* state = isolate->api_state();
|
| + ASSERT(state != NULL);
|
| + state->UnwindScopes(isolate->top_exit_frame_info());
|
| + Exceptions::ReThrow(excp, stk);
|
| + return Api::Error("Exception was not re thrown, internal error");
|
| }
|
|
|
|
|
| -DART_EXPORT bool Dart_PostIntArray(Dart_Port port,
|
| - intptr_t len,
|
| - intptr_t* data) {
|
| - uint8_t* buffer = NULL;
|
| - MessageWriter writer(&buffer, &allocator);
|
| +// --- Native functions ---
|
|
|
| - writer.WriteMessage(len, data);
|
|
|
| - // Post the message at the given port.
|
| - return PortMap::PostMessage(port, kNoReplyPort, buffer);
|
| +DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args,
|
| + int index) {
|
| + DARTSCOPE(Isolate::Current());
|
| + NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
|
| + const Object& obj = Object::Handle(arguments->At(index));
|
| + return Api::NewLocalHandle(obj);
|
| }
|
|
|
|
|
| -DART_EXPORT bool Dart_Post(Dart_Port port, Dart_Handle handle) {
|
| - DARTSCOPE(Isolate::Current());
|
| - const Object& object = Object::Handle(Api::UnwrapHandle(handle));
|
| - uint8_t* data = NULL;
|
| - SnapshotWriter writer(false, &data, &allocator);
|
| - writer.WriteObject(object.raw());
|
| - writer.FinalizeBuffer();
|
| - return PortMap::PostMessage(port, kNoReplyPort, data);
|
| +DART_EXPORT int Dart_GetNativeArgumentCount(Dart_NativeArguments args) {
|
| + NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
|
| + return arguments->Count();
|
| }
|
|
|
|
|
| -DART_EXPORT void Dart_InitPprofSupport() {
|
| - DebugInfo* pprof_symbol_generator = DebugInfo::NewGenerator();
|
| - ASSERT(pprof_symbol_generator != NULL);
|
| - Dart::set_pprof_symbol_generator(pprof_symbol_generator);
|
| +DART_EXPORT void Dart_SetReturnValue(Dart_NativeArguments args,
|
| + Dart_Handle retval) {
|
| + DARTSCOPE(Isolate::Current());
|
| + NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
|
| + arguments->SetReturn(Object::Handle(Api::UnwrapHandle(retval)));
|
| }
|
|
|
|
|
| -DART_EXPORT void Dart_GetPprofSymbolInfo(void** buffer, int* buffer_size) {
|
| - DebugInfo* pprof_symbol_generator = Dart::pprof_symbol_generator();
|
| - if (pprof_symbol_generator != NULL) {
|
| - ByteArray* debug_region = new ByteArray();
|
| - ASSERT(debug_region != NULL);
|
| - pprof_symbol_generator->WriteToMemory(debug_region);
|
| - *buffer_size = debug_region->size();
|
| - if (*buffer_size != 0) {
|
| - *buffer = reinterpret_cast<void*>(Api::Allocate(*buffer_size));
|
| - memmove(*buffer, debug_region->data(), *buffer_size);
|
| - } else {
|
| - *buffer = NULL;
|
| +// --- Scripts and Libraries ---
|
| +
|
| +
|
| +// 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 CompileSource(Isolate* isolate,
|
| + const Library& lib,
|
| + const String& url,
|
| + const String& source,
|
| + RawScript::Kind kind,
|
| + Dart_Handle* result) {
|
| + bool update_lib_status = (kind == RawScript::kScript ||
|
| + kind == RawScript::kLibrary);
|
| + if (update_lib_status) {
|
| + lib.SetLoadInProgress();
|
| + }
|
| + 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);
|
| + *result = Api::NewLocalHandle(lib);
|
| + if (update_lib_status) {
|
| + lib.SetLoaded();
|
| }
|
| - delete debug_region;
|
| } else {
|
| - *buffer = NULL;
|
| - *buffer_size = 0;
|
| + SetupErrorResult(result);
|
| + if (update_lib_status) {
|
| + lib.SetLoadError();
|
| + }
|
| }
|
| + isolate->set_long_jump_base(base);
|
| }
|
|
|
|
|
| -DART_EXPORT bool Dart_IsVMFlagSet(const char* flag_name) {
|
| - if (Flags::Lookup(flag_name) != NULL) {
|
| - return true;
|
| +DART_EXPORT Dart_Handle Dart_LoadScript(Dart_Handle url,
|
| + Dart_Handle source,
|
| + Dart_LibraryTagHandler handler) {
|
| + Isolate* isolate = Isolate::Current();
|
| + DARTSCOPE(isolate);
|
| + TIMERSCOPE(time_script_loading);
|
| + const String& url_str = Api::UnwrapStringHandle(url);
|
| + if (url_str.IsNull()) {
|
| + RETURN_TYPE_ERROR(url, String);
|
| }
|
| - return false;
|
| + const String& source_str = Api::UnwrapStringHandle(source);
|
| + if (source_str.IsNull()) {
|
| + RETURN_TYPE_ERROR(source, String);
|
| + }
|
| + Library& library = Library::Handle(isolate->object_store()->root_library());
|
| + if (!library.IsNull()) {
|
| + const String& library_url = String::Handle(library.url());
|
| + return Api::Error("%s: A script has already been loaded from '%s'.",
|
| + CURRENT_FUNC, library_url.ToCString());
|
| + }
|
| + isolate->set_library_tag_handler(handler);
|
| + library = Library::New(url_str);
|
| + library.Register();
|
| + isolate->object_store()->set_root_library(library);
|
| + Dart_Handle result;
|
| + CompileSource(isolate,
|
| + library,
|
| + url_str,
|
| + source_str,
|
| + RawScript::kScript,
|
| + &result);
|
| + return result;
|
| }
|
|
|
|
|
| -Dart_Handle Api::NewLocalHandle(const Object& object) {
|
| - Isolate* isolate = Isolate::Current();
|
| - ASSERT(isolate != NULL);
|
| - ApiState* state = isolate->api_state();
|
| - ASSERT(state != NULL);
|
| - ApiLocalScope* scope = state->top_scope();
|
| - ASSERT(scope != NULL);
|
| - LocalHandles* local_handles = scope->local_handles();
|
| - ASSERT(local_handles != NULL);
|
| - LocalHandle* ref = local_handles->AllocateHandle();
|
| - ref->set_raw(object);
|
| - return reinterpret_cast<Dart_Handle>(ref);
|
| +DEFINE_FLAG(bool, compile_all, false, "Eagerly compile all code.");
|
| +
|
| +static void CompileAll(Isolate* isolate, Dart_Handle* result) {
|
| + *result = Api::Success();
|
| + if (FLAG_compile_all) {
|
| + ASSERT(isolate != NULL);
|
| + LongJump* base = isolate->long_jump_base();
|
| + LongJump jump;
|
| + isolate->set_long_jump_base(&jump);
|
| + if (setjmp(*jump.Set()) == 0) {
|
| + Library::CompileAll();
|
| + } else {
|
| + SetupErrorResult(result);
|
| + }
|
| + isolate->set_long_jump_base(base);
|
| + }
|
| }
|
|
|
| -RawObject* Api::UnwrapHandle(Dart_Handle object) {
|
| -#ifdef DEBUG
|
| +
|
| +DART_EXPORT Dart_Handle Dart_CompileAll() {
|
| Isolate* isolate = Isolate::Current();
|
| - ASSERT(isolate != NULL);
|
| - ApiState* state = isolate->api_state();
|
| - ASSERT(state != NULL);
|
| - ASSERT(state->IsValidPersistentHandle(object) ||
|
| - state->IsValidLocalHandle(object));
|
| - ASSERT(PersistentHandle::raw_offset() == 0 &&
|
| - LocalHandle::raw_offset() == 0);
|
| -#endif
|
| - return *(reinterpret_cast<RawObject**>(object));
|
| + DARTSCOPE(isolate);
|
| + Dart_Handle result;
|
| + const char* msg = CheckIsolateState(isolate);
|
| + if (msg != NULL) {
|
| + return Api::Error(msg);
|
| + }
|
| + CompileAll(isolate, &result);
|
| + return result;
|
| }
|
|
|
| -#define DEFINE_UNWRAP(Type) \
|
| - const Type& Api::Unwrap##Type##Handle(Dart_Handle dart_handle) { \
|
| - const Object& tmp = Object::Handle(Api::UnwrapHandle(dart_handle)); \
|
| - Type& typed_handle = Type::Handle(); \
|
| - if (tmp.Is##Type()) { \
|
| - typed_handle ^= tmp.raw(); \
|
| - } \
|
| - return typed_handle; \
|
| - }
|
| -CLASS_LIST_NO_OBJECT(DEFINE_UNWRAP)
|
| -#undef DEFINE_UNWRAP
|
|
|
| -
|
| -LocalHandle* Api::UnwrapAsLocalHandle(const ApiState& state,
|
| - Dart_Handle object) {
|
| - ASSERT(state.IsValidLocalHandle(object));
|
| - return reinterpret_cast<LocalHandle*>(object);
|
| +DART_EXPORT bool Dart_IsLibrary(Dart_Handle object) {
|
| + DARTSCOPE(Isolate::Current());
|
| + const Object& obj = Object::Handle(Api::UnwrapHandle(object));
|
| + return obj.IsLibrary();
|
| }
|
|
|
|
|
| -PersistentHandle* Api::UnwrapAsPersistentHandle(const ApiState& state,
|
| - Dart_Handle object) {
|
| - ASSERT(state.IsValidPersistentHandle(object));
|
| - return reinterpret_cast<PersistentHandle*>(object);
|
| +DART_EXPORT Dart_Handle Dart_GetClass(Dart_Handle library, Dart_Handle name) {
|
| + DARTSCOPE(Isolate::Current());
|
| + const Object& param = Object::Handle(Api::UnwrapHandle(name));
|
| + if (param.IsNull() || !param.IsString()) {
|
| + return Api::Error("Invalid class name specified");
|
| + }
|
| + const Library& lib = Library::CheckedHandle(Api::UnwrapHandle(library));
|
| + if (lib.IsNull()) {
|
| + return Api::Error("Invalid parameter, Unknown library specified");
|
| + }
|
| + String& cls_name = String::Handle();
|
| + cls_name ^= param.raw();
|
| + const Class& cls = Class::Handle(lib.LookupClass(cls_name));
|
| + if (cls.IsNull()) {
|
| + const String& lib_name = String::Handle(lib.name());
|
| + return Api::Error("Class '%s' not found in library '%s'.",
|
| + cls_name.ToCString(), lib_name.ToCString());
|
| + }
|
| + return Api::NewLocalHandle(cls);
|
| }
|
|
|
|
|
| -Dart_Handle Api::Success() {
|
| - Isolate* isolate = Isolate::Current();
|
| - ASSERT(isolate != NULL);
|
| - ApiState* state = isolate->api_state();
|
| - ASSERT(state != NULL);
|
| - PersistentHandle* true_handle = state->True();
|
| - return reinterpret_cast<Dart_Handle>(true_handle);
|
| +DART_EXPORT Dart_Handle Dart_LibraryUrl(Dart_Handle library) {
|
| + DARTSCOPE(Isolate::Current());
|
| + const Library& lib = Api::UnwrapLibraryHandle(library);
|
| + if (lib.IsNull()) {
|
| + RETURN_TYPE_ERROR(library, Library);
|
| + }
|
| + const String& url = String::Handle(lib.url());
|
| + ASSERT(!url.IsNull());
|
| + return Api::NewLocalHandle(url);
|
| }
|
|
|
|
|
| -Dart_Handle Api::Error(const char* format, ...) {
|
| +DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url) {
|
| DARTSCOPE(Isolate::Current());
|
| + const String& url_str = Api::UnwrapStringHandle(url);
|
| + if (url_str.IsNull()) {
|
| + RETURN_TYPE_ERROR(url, String);
|
| + }
|
| + const Library& library = Library::Handle(Library::LookupLibrary(url_str));
|
| + if (library.IsNull()) {
|
| + return Api::Error("%s: library '%s' not found.",
|
| + CURRENT_FUNC, url_str.ToCString());
|
| + } else {
|
| + return Api::NewLocalHandle(library);
|
| + }
|
| +}
|
|
|
| - va_list args;
|
| - va_start(args, format);
|
| - intptr_t len = OS::VSNPrint(NULL, 0, format, args);
|
| - va_end(args);
|
|
|
| - char* buffer = reinterpret_cast<char*>(zone.Allocate(len + 1));
|
| - va_list args2;
|
| - va_start(args2, format);
|
| - OS::VSNPrint(buffer, (len + 1), format, args2);
|
| - va_end(args2);
|
| -
|
| - const String& message = String::Handle(String::New(buffer));
|
| - const Object& obj = Object::Handle(ApiError::New(message));
|
| - return Api::NewLocalHandle(obj);
|
| +DART_EXPORT Dart_Handle Dart_LoadLibrary(Dart_Handle url, Dart_Handle source) {
|
| + Isolate* isolate = Isolate::Current();
|
| + DARTSCOPE(isolate);
|
| + const String& url_str = Api::UnwrapStringHandle(url);
|
| + if (url_str.IsNull()) {
|
| + RETURN_TYPE_ERROR(url, String);
|
| + }
|
| + const String& source_str = Api::UnwrapStringHandle(source);
|
| + if (source_str.IsNull()) {
|
| + RETURN_TYPE_ERROR(source, String);
|
| + }
|
| + Library& library = Library::Handle(Library::LookupLibrary(url_str));
|
| + if (library.IsNull()) {
|
| + library = Library::New(url_str);
|
| + library.Register();
|
| + } else if (!library.LoadNotStarted()) {
|
| + // The source for this library has either been loaded or is in the
|
| + // process of loading. Return an error.
|
| + return Api::Error("%s: library '%s' has already been loaded.",
|
| + CURRENT_FUNC, url_str.ToCString());
|
| + }
|
| + Dart_Handle result;
|
| + CompileSource(isolate,
|
| + library,
|
| + url_str,
|
| + source_str,
|
| + RawScript::kLibrary,
|
| + &result);
|
| + return result;
|
| }
|
|
|
|
|
| -Dart_Handle Api::ErrorFromException(const Object& obj) {
|
| +DART_EXPORT Dart_Handle Dart_LibraryImportLibrary(Dart_Handle library,
|
| + Dart_Handle import) {
|
| DARTSCOPE(Isolate::Current());
|
| -
|
| - 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().");
|
| + const Library& library_vm = Api::UnwrapLibraryHandle(library);
|
| + if (library_vm.IsNull()) {
|
| + RETURN_TYPE_ERROR(library, Library);
|
| }
|
| + const Library& import_vm = Api::UnwrapLibraryHandle(import);
|
| + if (import_vm.IsNull()) {
|
| + RETURN_TYPE_ERROR(import, Library);
|
| + }
|
| + library_vm.AddImport(import_vm);
|
| + return Api::Success();
|
| }
|
|
|
|
|
| -Dart_Handle Api::Null() {
|
| +DART_EXPORT Dart_Handle Dart_LoadSource(Dart_Handle library,
|
| + Dart_Handle url,
|
| + Dart_Handle source) {
|
| Isolate* isolate = Isolate::Current();
|
| - ASSERT(isolate != NULL);
|
| - ApiState* state = isolate->api_state();
|
| - ASSERT(state != NULL);
|
| - PersistentHandle* null_handle = state->Null();
|
| - return reinterpret_cast<Dart_Handle>(null_handle);
|
| + DARTSCOPE(isolate);
|
| + const Library& lib = Api::UnwrapLibraryHandle(library);
|
| + if (lib.IsNull()) {
|
| + RETURN_TYPE_ERROR(library, Library);
|
| + }
|
| + const String& url_str = Api::UnwrapStringHandle(url);
|
| + if (url_str.IsNull()) {
|
| + RETURN_TYPE_ERROR(url, String);
|
| + }
|
| + const String& source_str = Api::UnwrapStringHandle(source);
|
| + if (source_str.IsNull()) {
|
| + RETURN_TYPE_ERROR(source, String);
|
| + }
|
| + Dart_Handle result;
|
| + CompileSource(isolate, lib, url_str, source_str, RawScript::kSource, &result);
|
| + return result;
|
| }
|
|
|
|
|
| -Dart_Handle Api::True() {
|
| - Isolate* isolate = Isolate::Current();
|
| - ASSERT(isolate != NULL);
|
| - ApiState* state = isolate->api_state();
|
| - ASSERT(state != NULL);
|
| - PersistentHandle* true_handle = state->True();
|
| - return reinterpret_cast<Dart_Handle>(true_handle);
|
| +DART_EXPORT Dart_Handle Dart_SetNativeResolver(
|
| + Dart_Handle library,
|
| + Dart_NativeEntryResolver resolver) {
|
| + DARTSCOPE(Isolate::Current());
|
| + const Library& lib = Api::UnwrapLibraryHandle(library);
|
| + if (lib.IsNull()) {
|
| + RETURN_TYPE_ERROR(library, Library);
|
| + }
|
| + lib.set_native_entry_resolver(resolver);
|
| + return Api::Success();
|
| }
|
|
|
|
|
| -Dart_Handle Api::False() {
|
| - Isolate* isolate = Isolate::Current();
|
| - ASSERT(isolate != NULL);
|
| - ApiState* state = isolate->api_state();
|
| - ASSERT(state != NULL);
|
| - PersistentHandle* false_handle = state->False();
|
| - return reinterpret_cast<Dart_Handle>(false_handle);
|
| -}
|
| +// --- Profiling support ----
|
|
|
|
|
| -uword Api::Allocate(intptr_t size) {
|
| - Isolate* isolate = Isolate::Current();
|
| - ASSERT(isolate != NULL);
|
| - ApiState* state = isolate->api_state();
|
| - ASSERT(state != NULL);
|
| - ApiLocalScope* scope = state->top_scope();
|
| - ASSERT(scope != NULL);
|
| - return scope->zone().Allocate(size);
|
| +DART_EXPORT void Dart_InitPprofSupport() {
|
| + DebugInfo* pprof_symbol_generator = DebugInfo::NewGenerator();
|
| + ASSERT(pprof_symbol_generator != NULL);
|
| + Dart::set_pprof_symbol_generator(pprof_symbol_generator);
|
| }
|
|
|
|
|
| -uword Api::Reallocate(uword ptr, intptr_t old_size, intptr_t new_size) {
|
| - Isolate* isolate = Isolate::Current();
|
| - ASSERT(isolate != NULL);
|
| - ApiState* state = isolate->api_state();
|
| - ASSERT(state != NULL);
|
| - ApiLocalScope* scope = state->top_scope();
|
| - ASSERT(scope != NULL);
|
| - return scope->zone().Reallocate(ptr, old_size, new_size);
|
| +DART_EXPORT void Dart_GetPprofSymbolInfo(void** buffer, int* buffer_size) {
|
| + DebugInfo* pprof_symbol_generator = Dart::pprof_symbol_generator();
|
| + if (pprof_symbol_generator != NULL) {
|
| + ByteArray* debug_region = new ByteArray();
|
| + ASSERT(debug_region != NULL);
|
| + pprof_symbol_generator->WriteToMemory(debug_region);
|
| + *buffer_size = debug_region->size();
|
| + if (*buffer_size != 0) {
|
| + *buffer = reinterpret_cast<void*>(Api::Allocate(*buffer_size));
|
| + memmove(*buffer, debug_region->data(), *buffer_size);
|
| + } else {
|
| + *buffer = NULL;
|
| + }
|
| + delete debug_region;
|
| + } else {
|
| + *buffer = NULL;
|
| + *buffer_size = 0;
|
| + }
|
| }
|
|
|
|
|
|
|