blob: a1425407db4e8b46893bac13ee6e903236ccc809 [file] [log] [blame]
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "include/dart_native_api.h"
#include "platform/assert.h"
#include "vm/dart_api_impl.h"
#include "vm/dart_api_message.h"
#include "vm/dart_api_state.h"
#include "vm/message.h"
#include "vm/native_message_handler.h"
#include "vm/port.h"
namespace dart {
// --- Message sending/receiving from native code ---
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 bool Dart_PostCObject(Dart_Port port_id, Dart_CObject* message) {
uint8_t* buffer = NULL;
ApiMessageWriter writer(&buffer, allocator);
bool success = writer.WriteCMessage(message);
if (!success) return success;
// Post the message at the given port.
return PortMap::PostMessage(new Message(
port_id, Message::kIllegalPort, buffer, writer.BytesWritten(),
Message::kNormalPriority));
}
DART_EXPORT Dart_Port Dart_NewNativePort(const char* name,
Dart_NativeMessageHandler handler,
bool handle_concurrently) {
if (name == NULL) {
name = "<UnnamedNativePort>";
}
if (handler == NULL) {
OS::PrintErr("%s expects argument 'handler' to be non-null.\n",
CURRENT_FUNC);
return ILLEGAL_PORT;
}
// Start the native port without a current isolate.
IsolateSaver saver(Isolate::Current());
Isolate::SetCurrent(NULL);
NativeMessageHandler* nmh = new NativeMessageHandler(name, handler);
Dart_Port port_id = PortMap::CreatePort(nmh);
nmh->Run(Dart::thread_pool(), NULL, NULL, 0);
return port_id;
}
DART_EXPORT bool Dart_CloseNativePort(Dart_Port native_port_id) {
// Close the native port without a current isolate.
IsolateSaver saver(Isolate::Current());
Isolate::SetCurrent(NULL);
// TODO(turnidge): Check that the port is native before trying to close.
return PortMap::ClosePort(native_port_id);
}
// --- Profiling support ---
// TODO(7565): Dartium should use the new VM flag "generate_pprof_symbols" for
// pprof profiling. Then these symbols should be removed.
DART_EXPORT void Dart_InitPprofSupport() { }
DART_EXPORT void Dart_GetPprofSymbolInfo(void** buffer, int* buffer_size) {
*buffer = NULL;
*buffer_size = 0;
}
// --- Heap Profiler ---
DART_EXPORT Dart_Handle Dart_HeapProfile(Dart_FileWriteCallback callback,
void* stream) {
Isolate* isolate = Isolate::Current();
CHECK_ISOLATE(isolate);
if (callback == NULL) {
RETURN_NULL_ERROR(callback);
}
isolate->heap()->Profile(callback, stream);
return Api::Success();
}
// --- Verification tools ---
static void CompileAll(Isolate* isolate, Dart_Handle* result) {
ASSERT(isolate != NULL);
const Error& error = Error::Handle(isolate, Library::CompileAll());
if (error.IsNull()) {
*result = Api::Success();
} else {
*result = Api::NewHandle(isolate, error.raw());
}
}
DART_EXPORT Dart_Handle Dart_CompileAll() {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
Dart_Handle result = Api::CheckIsolateState(isolate);
if (::Dart_IsError(result)) {
return result;
}
CHECK_CALLBACK_STATE(isolate);
CompileAll(isolate, &result);
return result;
}
DART_EXPORT Dart_Handle Dart_CheckFunctionFingerprints() {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
Dart_Handle result = Api::CheckIsolateState(isolate);
if (::Dart_IsError(result)) {
return result;
}
CHECK_CALLBACK_STATE(isolate);
Library::CheckFunctionFingerprints();
return result;
}
} // namespace dart