1 | // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
2 | // for details. All rights reserved. Use of this source code is governed by a |
3 | // BSD-style license that can be found in the LICENSE file. |
4 | |
5 | #if !defined(DART_IO_DISABLED) |
6 | |
7 | #include "bin/namespace.h" |
8 | |
9 | #include "bin/builtin.h" |
10 | #include "bin/dartutils.h" |
11 | #include "include/dart_api.h" |
12 | #include "platform/globals.h" |
13 | |
14 | namespace dart { |
15 | namespace bin { |
16 | |
17 | static const int kNamespaceNativeFieldIndex = 0; |
18 | |
19 | static void ReleaseNamespace(void* isolate_callback_data, void* peer) { |
20 | Namespace* namespc = reinterpret_cast<Namespace*>(peer); |
21 | ASSERT(namespc != NULL); |
22 | namespc->Release(); |
23 | } |
24 | |
25 | #if defined(DEBUG) |
26 | static bool IsNamespace(Dart_Handle namespc_obj) { |
27 | Dart_Handle namespc_type = |
28 | DartUtils::GetDartType("dart:io" , "_NamespaceImpl" ); |
29 | ASSERT(!Dart_IsError(namespc_type)); |
30 | bool isinstance = false; |
31 | Dart_Handle result = |
32 | Dart_ObjectIsType(namespc_obj, namespc_type, &isinstance); |
33 | ASSERT(!Dart_IsError(result)); |
34 | return isinstance; |
35 | } |
36 | #endif |
37 | |
38 | void FUNCTION_NAME(Namespace_Create)(Dart_NativeArguments args) { |
39 | Dart_Handle namespc_obj = Dart_GetNativeArgument(args, 0); |
40 | if (Dart_IsError(namespc_obj)) { |
41 | Dart_PropagateError(namespc_obj); |
42 | } |
43 | DEBUG_ASSERT(IsNamespace(namespc_obj)); |
44 | |
45 | // Allocate a native wrapper for the platform namespc bits. |
46 | Namespace* namespc = NULL; |
47 | Dart_Handle result; |
48 | Dart_Handle native_namespc = Dart_GetNativeArgument(args, 1); |
49 | if (Dart_IsInteger(native_namespc)) { |
50 | int64_t namespc_val; |
51 | result = Dart_IntegerToInt64(native_namespc, &namespc_val); |
52 | if (Dart_IsError(result)) { |
53 | Dart_PropagateError(result); |
54 | } |
55 | namespc = Namespace::Create(namespc_val); |
56 | } else if (Dart_IsString(native_namespc)) { |
57 | const char* namespc_path; |
58 | result = Dart_StringToCString(native_namespc, &namespc_path); |
59 | if (Dart_IsError(result)) { |
60 | Dart_PropagateError(result); |
61 | } |
62 | namespc = Namespace::Create(namespc_path); |
63 | } else { |
64 | // Propagate a type error. |
65 | Dart_ThrowException( |
66 | DartUtils::NewDartArgumentError("Argument must be an int or a String" )); |
67 | } |
68 | |
69 | // We were unable to create a native Namespace wrapper object due to some |
70 | // OS-level error. |
71 | if (namespc == NULL) { |
72 | Dart_SetReturnValue(args, DartUtils::NewDartOSError()); |
73 | } |
74 | |
75 | // Set the Dart objects native field to the native wrapper. |
76 | result = Dart_SetNativeInstanceField(namespc_obj, kNamespaceNativeFieldIndex, |
77 | reinterpret_cast<intptr_t>(namespc)); |
78 | if (Dart_IsError(result)) { |
79 | namespc->Release(); |
80 | Dart_PropagateError(result); |
81 | } |
82 | |
83 | // Set up a finalizer for the Dart object so that we can do any necessary |
84 | // platform-specific cleanup for the namespc. |
85 | Dart_NewFinalizableHandle(namespc_obj, reinterpret_cast<void*>(namespc), |
86 | sizeof(*namespc), ReleaseNamespace); |
87 | Dart_SetReturnValue(args, namespc_obj); |
88 | } |
89 | |
90 | void FUNCTION_NAME(Namespace_GetDefault)(Dart_NativeArguments args) { |
91 | Dart_SetIntegerReturnValue(args, Namespace::Default()); |
92 | } |
93 | |
94 | void FUNCTION_NAME(Namespace_GetPointer)(Dart_NativeArguments args) { |
95 | Namespace* namespc = Namespace::GetNamespace(args, 0); |
96 | ASSERT(namespc != NULL); |
97 | namespc->Retain(); |
98 | Dart_SetIntegerReturnValue(args, reinterpret_cast<intptr_t>(namespc)); |
99 | } |
100 | |
101 | Namespace* Namespace::GetNamespace(Dart_NativeArguments args, intptr_t index) { |
102 | Namespace* namespc; |
103 | Dart_Handle status = |
104 | Namespace::GetNativeNamespaceArgument(args, index, &namespc); |
105 | if (Dart_IsError(status)) { |
106 | Dart_PropagateError(status); |
107 | } |
108 | return namespc; |
109 | } |
110 | |
111 | bool Namespace::IsDefault(Namespace* namespc) { |
112 | return (namespc == NULL) || (namespc->namespc() == NULL); |
113 | } |
114 | |
115 | Dart_Handle Namespace::GetNativeNamespaceArgument(Dart_NativeArguments args, |
116 | intptr_t index, |
117 | Namespace** namespc) { |
118 | Dart_Handle namespc_obj = Dart_GetNativeArgument(args, index); |
119 | if (Dart_IsError(namespc_obj)) { |
120 | return namespc_obj; |
121 | } |
122 | DEBUG_ASSERT(IsNamespace(namespc_obj)); |
123 | |
124 | Dart_Handle result = |
125 | Dart_GetNativeInstanceField(namespc_obj, kNamespaceNativeFieldIndex, |
126 | reinterpret_cast<intptr_t*>(namespc)); |
127 | if (Dart_IsError(result)) { |
128 | return result; |
129 | } |
130 | if (*namespc == NULL) { |
131 | return Dart_NewUnhandledExceptionError( |
132 | DartUtils::NewInternalError("No native peer" )); |
133 | } |
134 | return Dart_Null(); |
135 | } |
136 | |
137 | } // namespace bin |
138 | } // namespace dart |
139 | |
140 | #endif // !defined(DART_IO_DISABLED) |
141 | |