| 1 | // Copyright (c) 2012, 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 | #ifndef RUNTIME_BIN_PLATFORM_H_ |
| 6 | #define RUNTIME_BIN_PLATFORM_H_ |
| 7 | |
| 8 | #include "bin/builtin.h" |
| 9 | |
| 10 | #include "platform/atomic.h" |
| 11 | #include "platform/globals.h" |
| 12 | #include "platform/utils.h" |
| 13 | |
| 14 | #if defined(DART_HOST_OS_MACOS) |
| 15 | #include "bin/platform_macos.h" |
| 16 | #endif // defined(DART_HOST_OS_MACOS) |
| 17 | |
| 18 | namespace dart { |
| 19 | namespace bin { |
| 20 | |
| 21 | class Platform { |
| 22 | public: |
| 23 | // Perform platform specific initialization. |
| 24 | static bool Initialize(); |
| 25 | |
| 26 | // Returns the number of processors on the machine. |
| 27 | static int NumberOfProcessors(); |
| 28 | |
| 29 | // Returns a string representing the operating system ("linux", |
| 30 | // "macos", "windows", or "android"). The returned string should not be |
| 31 | // deallocated by the caller. |
| 32 | static const char* OperatingSystem() { return kHostOperatingSystemName; } |
| 33 | |
| 34 | // Returns a string representing the version of the operating system. The |
| 35 | // format of the string is determined by the platform. The returned string |
| 36 | // should not be deallocated by the caller. |
| 37 | static const char* OperatingSystemVersion(); |
| 38 | |
| 39 | // Returns the architecture name of the processor the VM is running on |
| 40 | // (ia32, x64, arm, or arm64). |
| 41 | static const char* HostArchitecture() { return kHostArchitectureName; } |
| 42 | |
| 43 | static const char* LibraryPrefix(); |
| 44 | |
| 45 | // Returns a string representing the operating system's shared library |
| 46 | // extension (e.g. 'so', 'dll', ...). The returned string should not be |
| 47 | // deallocated by the caller. |
| 48 | static const char* LibraryExtension(); |
| 49 | |
| 50 | // Extracts the local hostname. |
| 51 | static bool LocalHostname(char* buffer, intptr_t buffer_length); |
| 52 | |
| 53 | static const char* LocaleName(); |
| 54 | |
| 55 | // Extracts the environment variables for the current process. The array of |
| 56 | // strings is Dart_ScopeAllocated. The number of elements in the array is |
| 57 | // returned in the count argument. |
| 58 | static char** Environment(intptr_t* count); |
| 59 | |
| 60 | static const char* ResolveExecutablePath(); |
| 61 | |
| 62 | // This has the same effect as calling ResolveExecutablePath except that |
| 63 | // Dart_ScopeAllocate is not called and that the result goes into the given |
| 64 | // parameters. |
| 65 | // WARNING: On Fuchsia it returns -1, i.e. doesn't work. |
| 66 | // Note that `result` should be pre-allocated with size `result_size`. |
| 67 | // The return-value is the length read into `result` or -1 on failure. |
| 68 | static intptr_t ResolveExecutablePathInto(char* result, size_t result_size); |
| 69 | |
| 70 | // Stores the executable name. |
| 71 | static void SetExecutableName(const char* executable_name) { |
| 72 | executable_name_ = executable_name; |
| 73 | } |
| 74 | static const char* GetExecutableName(); |
| 75 | static const char* GetResolvedExecutableName() { |
| 76 | if (resolved_executable_name_.load() == nullptr) { |
| 77 | // Try to resolve the executable path using platform specific APIs. |
| 78 | const char* resolved_name = Platform::ResolveExecutablePath(); |
| 79 | if (resolved_name != nullptr) { |
| 80 | char* resolved_name_copy = Utils::StrDup(s: resolved_name); |
| 81 | const char* expect_old_is_null = nullptr; |
| 82 | if (!resolved_executable_name_.compare_exchange_strong( |
| 83 | expect_old_is_null, resolved_name_copy)) { |
| 84 | free(resolved_name_copy); |
| 85 | } |
| 86 | } |
| 87 | } |
| 88 | return resolved_executable_name_.load(); |
| 89 | } |
| 90 | |
| 91 | // Stores and gets the flags passed to the executable. |
| 92 | static void SetExecutableArguments(int script_index, char** argv) { |
| 93 | script_index_ = script_index; |
| 94 | argv_ = argv; |
| 95 | } |
| 96 | static int GetScriptIndex() { return script_index_; } |
| 97 | static char** GetArgv() { return argv_; } |
| 98 | |
| 99 | static void SetProcessName(const char* name); |
| 100 | |
| 101 | DART_NORETURN static void Exit(int exit_code); |
| 102 | |
| 103 | static void SetCoreDumpResourceLimit(int value); |
| 104 | |
| 105 | #if defined(DART_HOST_OS_FUCHSIA) |
| 106 | static zx_handle_t GetVMEXResource(); |
| 107 | #endif |
| 108 | |
| 109 | private: |
| 110 | // The path to the executable. |
| 111 | static const char* executable_name_; |
| 112 | |
| 113 | // The path to the resolved executable. |
| 114 | // |
| 115 | // We use require-release semantics to ensure initializing stores to the |
| 116 | // string are visible when the string becomes visible. |
| 117 | static AcqRelAtomic<const char*> resolved_executable_name_; |
| 118 | |
| 119 | static int script_index_; |
| 120 | static char** argv_; // VM flags are argv_[1 ... script_index_ - 1] |
| 121 | |
| 122 | DISALLOW_ALLOCATION(); |
| 123 | DISALLOW_IMPLICIT_CONSTRUCTORS(Platform); |
| 124 | }; |
| 125 | |
| 126 | } // namespace bin |
| 127 | } // namespace dart |
| 128 | |
| 129 | #endif // RUNTIME_BIN_PLATFORM_H_ |
| 130 | |