dart-sdk/runtime/bin/namespace.cc
Daco Harkes 202e32afeb [vm] Native API: Introduce Dart_FinalizableHandle
Introduces Dart_NewFinalizableHandle which does auto delete itself,
but does not allow accessing the weak referenced object.

Issue: https://github.com/dart-lang/sdk/issues/42312

Change-Id: I24ea732925122c453213c4fa3f629761c352f838
Cq-Include-Trybots:dart/try:vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64-try,app-kernel-linux-debug-x64-try,vm-kernel-linux-debug-ia32-try,vm-kernel-win-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-kernel-precomp-linux-debug-x64-try,vm-dartkb-linux-release-x64-abi-try,vm-kernel-precomp-android-release-arm64-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-msan-linux-release-x64-try,vm-kernel-precomp-msan-linux-release-x64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-simarm64-try,vm-kernel-precomp-android-release-arm_x64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,dart-sdk-linux-try,analyzer-analysis-server-linux-try,analyzer-linux-release-try,front-end-linux-release-x64-try,vm-kernel-precomp-win-release-x64-try,vm-kernel-mac-debug-x64-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-nnbd-linux-debug-x64-try,analyzer-nnbd-linux-release-try,front-end-nnbd-linux-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/154695
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2020-07-23 11:30:39 +00:00

141 lines
4.4 KiB
C++

// Copyright (c) 2017, 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.
#if !defined(DART_IO_DISABLED)
#include "bin/namespace.h"
#include "bin/builtin.h"
#include "bin/dartutils.h"
#include "include/dart_api.h"
#include "platform/globals.h"
namespace dart {
namespace bin {
static const int kNamespaceNativeFieldIndex = 0;
static void ReleaseNamespace(void* isolate_callback_data, void* peer) {
Namespace* namespc = reinterpret_cast<Namespace*>(peer);
ASSERT(namespc != NULL);
namespc->Release();
}
#if defined(DEBUG)
static bool IsNamespace(Dart_Handle namespc_obj) {
Dart_Handle namespc_type =
DartUtils::GetDartType("dart:io", "_NamespaceImpl");
ASSERT(!Dart_IsError(namespc_type));
bool isinstance = false;
Dart_Handle result =
Dart_ObjectIsType(namespc_obj, namespc_type, &isinstance);
ASSERT(!Dart_IsError(result));
return isinstance;
}
#endif
void FUNCTION_NAME(Namespace_Create)(Dart_NativeArguments args) {
Dart_Handle namespc_obj = Dart_GetNativeArgument(args, 0);
if (Dart_IsError(namespc_obj)) {
Dart_PropagateError(namespc_obj);
}
DEBUG_ASSERT(IsNamespace(namespc_obj));
// Allocate a native wrapper for the platform namespc bits.
Namespace* namespc = NULL;
Dart_Handle result;
Dart_Handle native_namespc = Dart_GetNativeArgument(args, 1);
if (Dart_IsInteger(native_namespc)) {
int64_t namespc_val;
result = Dart_IntegerToInt64(native_namespc, &namespc_val);
if (Dart_IsError(result)) {
Dart_PropagateError(result);
}
namespc = Namespace::Create(namespc_val);
} else if (Dart_IsString(native_namespc)) {
const char* namespc_path;
result = Dart_StringToCString(native_namespc, &namespc_path);
if (Dart_IsError(result)) {
Dart_PropagateError(result);
}
namespc = Namespace::Create(namespc_path);
} else {
// Propagate a type error.
Dart_ThrowException(
DartUtils::NewDartArgumentError("Argument must be an int or a String"));
}
// We were unable to create a native Namespace wrapper object due to some
// OS-level error.
if (namespc == NULL) {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
}
// Set the Dart objects native field to the native wrapper.
result = Dart_SetNativeInstanceField(namespc_obj, kNamespaceNativeFieldIndex,
reinterpret_cast<intptr_t>(namespc));
if (Dart_IsError(result)) {
namespc->Release();
Dart_PropagateError(result);
}
// Set up a finalizer for the Dart object so that we can do any necessary
// platform-specific cleanup for the namespc.
Dart_NewFinalizableHandle(namespc_obj, reinterpret_cast<void*>(namespc),
sizeof(*namespc), ReleaseNamespace);
Dart_SetReturnValue(args, namespc_obj);
}
void FUNCTION_NAME(Namespace_GetDefault)(Dart_NativeArguments args) {
Dart_SetIntegerReturnValue(args, Namespace::Default());
}
void FUNCTION_NAME(Namespace_GetPointer)(Dart_NativeArguments args) {
Namespace* namespc = Namespace::GetNamespace(args, 0);
ASSERT(namespc != NULL);
namespc->Retain();
Dart_SetIntegerReturnValue(args, reinterpret_cast<intptr_t>(namespc));
}
Namespace* Namespace::GetNamespace(Dart_NativeArguments args, intptr_t index) {
Namespace* namespc;
Dart_Handle status =
Namespace::GetNativeNamespaceArgument(args, index, &namespc);
if (Dart_IsError(status)) {
Dart_PropagateError(status);
}
return namespc;
}
bool Namespace::IsDefault(Namespace* namespc) {
return (namespc == NULL) || (namespc->namespc() == NULL);
}
Dart_Handle Namespace::GetNativeNamespaceArgument(Dart_NativeArguments args,
intptr_t index,
Namespace** namespc) {
Dart_Handle namespc_obj = Dart_GetNativeArgument(args, index);
if (Dart_IsError(namespc_obj)) {
return namespc_obj;
}
DEBUG_ASSERT(IsNamespace(namespc_obj));
Dart_Handle result =
Dart_GetNativeInstanceField(namespc_obj, kNamespaceNativeFieldIndex,
reinterpret_cast<intptr_t*>(namespc));
if (Dart_IsError(result)) {
return result;
}
if (*namespc == NULL) {
return Dart_NewUnhandledExceptionError(
DartUtils::NewInternalError("No native peer"));
}
return Dart_Null();
}
} // namespace bin
} // namespace dart
#endif // !defined(DART_IO_DISABLED)