From 5726900c84712e4696ce7fc2a838beede2d7919b Mon Sep 17 00:00:00 2001 From: Osei Fortune Date: Tue, 25 Jan 2022 12:26:55 -0400 Subject: [PATCH 1/3] poc --- .gitignore | 25 + .../Inspector/base/trace_event/common | 1 + .../Inspector/src/base/address-region.h | 95 + .../Inspector/src/base/atomic-utils.h | 250 + .../Inspector/src/base/atomicops.h | 448 ++ .../atomicops_internals_atomicword_compat.h | 89 + .../Inspector/src/base/base-export.h | 31 + Source/NativeScript/Inspector/src/base/bits.h | 345 ++ .../Inspector/src/base/build_config.h | 257 + .../Inspector/src/base/compiler-specific.h | 138 + .../Inspector/src/base/enum-set.h | 92 + .../Inspector/src/base/export-template.h | 163 + .../NativeScript/Inspector/src/base/flags.h | 130 + .../Inspector/src/base/immediate-crash.h | 162 + .../Inspector/src/base/lazy-instance.h | 258 + .../NativeScript/Inspector/src/base/logging.h | 417 ++ .../NativeScript/Inspector/src/base/macros.h | 442 ++ .../NativeScript/Inspector/src/base/memory.h | 89 + Source/NativeScript/Inspector/src/base/once.h | 108 + .../Inspector/src/base/optional.h | 882 +++ .../Inspector/src/base/platform/mutex.h | 375 ++ .../Inspector/src/base/platform/platform.h | 600 ++ .../Inspector/src/base/platform/semaphore.h | 108 + .../Inspector/src/base/platform/time.h | 513 ++ .../Inspector/src/base/platform/wrappers.h | 70 + .../Inspector/src/base/safe_conversions.h | 389 ++ .../src/base/safe_conversions_impl.h | 822 +++ .../NativeScript/Inspector/src/base/strings.h | 51 + .../Inspector/src/base/template-utils.h | 113 + .../Inspector/src/base/v8-fallthrough.h | 21 + .../NativeScript/Inspector/src/base/vector.h | 323 + .../Inspector/src/base/win32-headers.h | 120 + .../Inspector/src/common/checks.h | 38 + .../Inspector/src/common/globals.h | 1942 ++++++ Source/NativeScript/Inspector/src/init/v8.h | 56 + .../Inspector/src/inspector/custom-preview.cc | 401 ++ .../Inspector/src/inspector/custom-preview.h | 24 + .../src/inspector/injected-script.cc | 1046 ++++ .../Inspector/src/inspector/injected-script.h | 253 + .../src/inspector/inspected-context.cc | 164 + .../src/inspector/inspected-context.h | 85 + .../Inspector/src/inspector/protocol/CSS.cpp | 1512 +++++ .../Inspector/src/inspector/protocol/CSS.h | 2148 +++++++ .../src/inspector/protocol/Console.cpp | 231 + .../src/inspector/protocol/Console.h | 211 + .../Inspector/src/inspector/protocol/DOM.cpp | 2308 +++++++ .../Inspector/src/inspector/protocol/DOM.h | 1008 +++ .../src/inspector/protocol/Debugger.cpp | 1746 ++++++ .../src/inspector/protocol/Debugger.h | 892 +++ .../src/inspector/protocol/Forward.h | 75 + .../src/inspector/protocol/HeapProfiler.cpp | 666 ++ .../src/inspector/protocol/HeapProfiler.h | 346 ++ .../Inspector/src/inspector/protocol/Log.cpp | 324 + .../Inspector/src/inspector/protocol/Log.h | 342 ++ .../src/inspector/protocol/Network.cpp | 1506 +++++ .../src/inspector/protocol/Network.h | 2528 ++++++++ .../src/inspector/protocol/Overlay.cpp | 887 +++ .../src/inspector/protocol/Overlay.h | 281 + .../Inspector/src/inspector/protocol/Page.cpp | 1709 ++++++ .../Inspector/src/inspector/protocol/Page.h | 1189 ++++ .../src/inspector/protocol/Profiler.cpp | 659 ++ .../src/inspector/protocol/Profiler.h | 840 +++ .../src/inspector/protocol/Protocol.cpp | 727 +++ .../src/inspector/protocol/Protocol.h | 617 ++ .../src/inspector/protocol/Runtime.cpp | 1536 +++++ .../src/inspector/protocol/Runtime.h | 1707 ++++++ .../src/inspector/protocol/Schema.cpp | 160 + .../Inspector/src/inspector/protocol/Schema.h | 146 + .../src/inspector/protocol/Security.cpp | 275 + .../src/inspector/protocol/Security.h | 793 +++ .../src/inspector/remote-object-id.cc | 77 + .../src/inspector/remote-object-id.h | 54 + .../Inspector/src/inspector/search-util.cc | 168 + .../Inspector/src/inspector/search-util.h | 26 + .../Inspector/src/inspector/string-16.cc | 250 + .../Inspector/src/inspector/string-16.h | 180 + .../Inspector/src/inspector/string-util.cc | 312 + .../Inspector/src/inspector/string-util.h | 132 + .../src/inspector/v8-console-agent-impl.cc | 80 + .../src/inspector/v8-console-agent-impl.h | 48 + .../src/inspector/v8-console-message.cc | 666 ++ .../src/inspector/v8-console-message.h | 150 + .../Inspector/src/inspector/v8-console.cc | 978 +++ .../Inspector/src/inspector/v8-console.h | 197 + .../src/inspector/v8-css-agent-impl.cpp | 271 + .../src/inspector/v8-css-agent-impl.h | 123 + .../src/inspector/v8-debugger-agent-impl.cc | 2007 ++++++ .../src/inspector/v8-debugger-agent-impl.h | 253 + .../Inspector/src/inspector/v8-debugger-id.cc | 45 + .../Inspector/src/inspector/v8-debugger-id.h | 44 + .../src/inspector/v8-debugger-script.cc | 405 ++ .../src/inspector/v8-debugger-script.h | 127 + .../Inspector/src/inspector/v8-debugger.cc | 1155 ++++ .../Inspector/src/inspector/v8-debugger.h | 287 + .../src/inspector/v8-dom-agent-impl.cpp | 480 ++ .../src/inspector/v8-dom-agent-impl.h | 171 + .../inspector/v8-heap-profiler-agent-impl.cc | 465 ++ .../inspector/v8-heap-profiler-agent-impl.h | 82 + .../src/inspector/v8-inspector-impl.cc | 526 ++ .../src/inspector/v8-inspector-impl.h | 193 + .../inspector/v8-inspector-session-impl.cc | 503 ++ .../src/inspector/v8-inspector-session-impl.h | 141 + .../src/inspector/v8-log-agent-impl.cpp | 91 + .../src/inspector/v8-log-agent-impl.h | 45 + .../src/inspector/v8-network-agent-impl.cpp | 307 + .../src/inspector/v8-network-agent-impl.h | 97 + .../inspector/v8-ns-debugger-agent-impl.cpp | 25 + .../src/inspector/v8-ns-debugger-agent-impl.h | 26 + .../src/inspector/v8-overlay-agent-impl.cpp | 124 + .../src/inspector/v8-overlay-agent-impl.h | 85 + .../src/inspector/v8-page-agent-impl.cpp | 334 + .../src/inspector/v8-page-agent-impl.h | 139 + .../src/inspector/v8-profiler-agent-impl.cc | 568 ++ .../src/inspector/v8-profiler-agent-impl.h | 89 + .../Inspector/src/inspector/v8-regex.cc | 107 + .../Inspector/src/inspector/v8-regex.h | 41 + .../src/inspector/v8-runtime-agent-impl.cc | 939 +++ .../src/inspector/v8-runtime-agent-impl.h | 164 + .../src/inspector/v8-schema-agent-impl.cc | 27 + .../src/inspector/v8-schema-agent-impl.h | 38 + .../src/inspector/v8-stack-trace-impl.cc | 481 ++ .../src/inspector/v8-stack-trace-impl.h | 164 + .../src/inspector/v8-string-conversions.cc | 403 ++ .../src/inspector/v8-string-conversions.h | 17 + .../Inspector/src/inspector/v8-value-utils.cc | 33 + .../Inspector/src/inspector/v8-value-utils.h | 22 + .../Inspector/src/inspector/value-mirror.cc | 1679 +++++ .../Inspector/src/inspector/value-mirror.h | 99 + .../src/libplatform/default-platform.h | 92 + .../Inspector/src/logging/tracing-flags.h | 52 + .../Inspector/src/numbers/conversions.h | 189 + .../Inspector/src/tracing/trace-event.h | 664 ++ .../Inspector/src/utils/allocation.h | 399 ++ .../inspector_protocol/crdtp/cbor.h | 305 + .../inspector_protocol/crdtp/dispatch.h | 314 + .../inspector_protocol/crdtp/error_support.h | 62 + .../inspector_protocol/crdtp/export.h | 6 + .../inspector_protocol/crdtp/find_by_first.h | 58 + .../crdtp/frontend_channel.h | 47 + .../inspector_protocol/crdtp/glue.h | 80 + .../inspector_protocol/crdtp/json.h | 52 + .../inspector_protocol/crdtp/json_platform.h | 26 + .../inspector_protocol/crdtp/maybe.h | 104 + .../inspector_protocol/crdtp/parser_handler.h | 39 + .../inspector_protocol/crdtp/protocol_core.h | 406 ++ .../inspector_protocol/crdtp/serializable.h | 32 + .../crdtp/serializer_traits.h | 158 + .../inspector_protocol/crdtp/span.h | 99 + .../inspector_protocol/crdtp/status.h | 140 + Source/NativeScript/Inspector/utils.cpp | 67 + Source/NativeScript/Inspector/utils.h | 45 + .../NativeScript/Metadata/MetadataReader.cpp | 123 + Source/NativeScript/Metadata/MetadataReader.h | 16 + Source/NativeScript/NativeScript.cpp | 34 + Source/NativeScript/NativeScript.h | 14 + Source/NativeScript/NativeScript.log | 1 + Source/NativeScript/NativeScript.vcxproj | 278 + .../NativeScript/NativeScript.vcxproj.filters | 42 + Source/NativeScript/NativeScript.vcxproj.user | 6 + Source/NativeScript/Runtime/Caches.cpp | 41 + Source/NativeScript/Runtime/Caches.h | 29 + Source/NativeScript/Runtime/Common.h | 10 + Source/NativeScript/Runtime/ConcurrentMap.h | 50 + Source/NativeScript/Runtime/Console.cpp | 389 ++ Source/NativeScript/Runtime/Console.h | 36 + Source/NativeScript/Runtime/Helpers.cpp | 585 ++ Source/NativeScript/Runtime/Helpers.h | 73 + .../NativeScript/Runtime/MetadataBuilder.cpp | 30 + Source/NativeScript/Runtime/MetadataBuilder.h | 21 + .../NativeScript/Runtime/ModuleInternal.cpp | 489 ++ Source/NativeScript/Runtime/ModuleInternal.h | 56 + .../Runtime/NativeScriptException.cpp | 199 + .../Runtime/NativeScriptException.h | 22 + Source/NativeScript/Runtime/Runtime.cpp | 191 + Source/NativeScript/Runtime/Runtime.h | 50 + Source/NativeScript/Runtime/RuntimeConfig.cpp | 4 + Source/NativeScript/Runtime/RuntimeConfig.h | 11 + .../NativeScript/Runtime/SimpleAllocator.cpp | 29 + Source/NativeScript/Runtime/SimpleAllocator.h | 18 + Source/NativeScript/Runtime/WeakRef.cpp | 28 + Source/NativeScript/Runtime/WeakRef.h | 11 + Source/NativeScript/Runtime/robin_hood.h | 2544 ++++++++ Source/NativeScript/include/APIDesign.md | 72 + Source/NativeScript/include/DEPS | 10 + Source/NativeScript/include/DIR_METADATA | 11 + Source/NativeScript/include/OWNERS | 20 + Source/NativeScript/include/cppgc/DEPS | 8 + Source/NativeScript/include/cppgc/OWNERS | 2 + Source/NativeScript/include/cppgc/README.md | 16 + .../NativeScript/include/cppgc/allocation.h | 310 + Source/NativeScript/include/cppgc/common.h | 29 + .../include/cppgc/cross-thread-persistent.h | 465 ++ .../NativeScript/include/cppgc/custom-space.h | 97 + .../include/cppgc/default-platform.h | 75 + .../include/cppgc/ephemeron-pair.h | 30 + .../include/cppgc/explicit-management.h | 82 + .../include/cppgc/garbage-collected.h | 105 + .../include/cppgc/heap-consistency.h | 253 + .../NativeScript/include/cppgc/heap-state.h | 82 + .../include/cppgc/heap-statistics.h | 120 + Source/NativeScript/include/cppgc/heap.h | 201 + .../include/cppgc/internal/api-constants.h | 52 + .../cppgc/internal/atomic-entry-flag.h | 48 + .../cppgc/internal/caged-heap-local-data.h | 68 + .../cppgc/internal/compiler-specific.h | 38 + .../include/cppgc/internal/finalizer-trait.h | 92 + .../include/cppgc/internal/gc-info.h | 156 + .../include/cppgc/internal/logging.h | 50 + .../include/cppgc/internal/name-trait.h | 122 + .../include/cppgc/internal/persistent-node.h | 216 + .../include/cppgc/internal/pointer-policies.h | 186 + .../cppgc/internal/prefinalizer-handler.h | 30 + .../include/cppgc/internal/write-barrier.h | 441 ++ .../include/cppgc/liveness-broker.h | 77 + Source/NativeScript/include/cppgc/macros.h | 26 + Source/NativeScript/include/cppgc/member.h | 288 + .../include/cppgc/name-provider.h | 65 + .../include/cppgc/object-size-trait.h | 58 + .../NativeScript/include/cppgc/persistent.h | 371 ++ Source/NativeScript/include/cppgc/platform.h | 154 + .../NativeScript/include/cppgc/prefinalizer.h | 52 + .../include/cppgc/process-heap-statistics.h | 36 + .../include/cppgc/sentinel-pointer.h | 32 + .../include/cppgc/source-location.h | 92 + Source/NativeScript/include/cppgc/testing.h | 99 + .../NativeScript/include/cppgc/trace-trait.h | 116 + .../NativeScript/include/cppgc/type-traits.h | 247 + Source/NativeScript/include/cppgc/visitor.h | 379 ++ .../NativeScript/include/inspector/Debugger.h | 59 + .../NativeScript/include/inspector/Runtime.h | 52 + .../NativeScript/include/inspector/Schema.h | 42 + .../NativeScript/include/js_protocol-1.2.json | 997 +++ .../NativeScript/include/js_protocol-1.3.json | 1205 ++++ Source/NativeScript/include/js_protocol.pdl | 5439 +++++++++++++++++ Source/NativeScript/include/libplatform/DEPS | 9 + .../include/libplatform/libplatform-export.h | 29 + .../include/libplatform/libplatform.h | 117 + .../include/libplatform/v8-tracing.h | 333 + Source/NativeScript/include/v8-array-buffer.h | 433 ++ Source/NativeScript/include/v8-callbacks.h | 383 ++ Source/NativeScript/include/v8-container.h | 129 + Source/NativeScript/include/v8-context.h | 418 ++ Source/NativeScript/include/v8-cppgc.h | 344 ++ Source/NativeScript/include/v8-data.h | 80 + Source/NativeScript/include/v8-date.h | 43 + Source/NativeScript/include/v8-debug.h | 151 + .../NativeScript/include/v8-embedder-heap.h | 239 + .../include/v8-embedder-state-scope.h | 48 + Source/NativeScript/include/v8-exception.h | 224 + Source/NativeScript/include/v8-extension.h | 62 + Source/NativeScript/include/v8-external.h | 37 + .../NativeScript/include/v8-fast-api-calls.h | 944 +++ Source/NativeScript/include/v8-forward.h | 81 + .../include/v8-function-callback.h | 475 ++ Source/NativeScript/include/v8-function.h | 125 + .../NativeScript/include/v8-initialization.h | 294 + .../include/v8-inspector-protocol.h | 13 + Source/NativeScript/include/v8-inspector.h | 331 + Source/NativeScript/include/v8-internal.h | 615 ++ Source/NativeScript/include/v8-isolate.h | 1694 +++++ Source/NativeScript/include/v8-json.h | 47 + Source/NativeScript/include/v8-local-handle.h | 459 ++ Source/NativeScript/include/v8-locker.h | 148 + Source/NativeScript/include/v8-maybe.h | 137 + Source/NativeScript/include/v8-memory-span.h | 43 + Source/NativeScript/include/v8-message.h | 257 + Source/NativeScript/include/v8-metrics.h | 238 + .../NativeScript/include/v8-microtask-queue.h | 152 + Source/NativeScript/include/v8-microtask.h | 28 + Source/NativeScript/include/v8-object.h | 775 +++ .../include/v8-persistent-handle.h | 590 ++ Source/NativeScript/include/v8-platform.h | 954 +++ .../include/v8-primitive-object.h | 118 + Source/NativeScript/include/v8-primitive.h | 868 +++ Source/NativeScript/include/v8-profiler.h | 1134 ++++ Source/NativeScript/include/v8-promise.h | 174 + Source/NativeScript/include/v8-proxy.h | 50 + Source/NativeScript/include/v8-regexp.h | 105 + Source/NativeScript/include/v8-script.h | 790 +++ Source/NativeScript/include/v8-snapshot.h | 198 + Source/NativeScript/include/v8-statistics.h | 217 + Source/NativeScript/include/v8-template.h | 1052 ++++ .../NativeScript/include/v8-traced-handle.h | 622 ++ Source/NativeScript/include/v8-typed-array.h | 282 + .../NativeScript/include/v8-unwinder-state.h | 31 + Source/NativeScript/include/v8-unwinder.h | 132 + Source/NativeScript/include/v8-util.h | 658 ++ .../include/v8-value-serializer-version.h | 24 + .../include/v8-value-serializer.h | 249 + Source/NativeScript/include/v8-value.h | 526 ++ .../NativeScript/include/v8-version-string.h | 38 + Source/NativeScript/include/v8-version.h | 20 + .../include/v8-wasm-trap-handler-posix.h | 31 + .../include/v8-wasm-trap-handler-win.h | 28 + Source/NativeScript/include/v8-wasm.h | 257 + .../include/v8-weak-callback-info.h | 73 + Source/NativeScript/include/v8.h | 89 + Source/NativeScript/include/v8config.h | 605 ++ Source/NativeScript/pch.cpp | 1 + Source/NativeScript/pch.h | 9 + Source/NativeScript/targetver.h | 8 + Source/Nativescript.DLL/Nativescript.DLL.cpp | 12 + Source/Nativescript.DLL/Nativescript.DLL.h | 15 + Source/Nativescript.DLL/Nativescript.DLL.log | 1 + .../Nativescript.DLL/Nativescript.DLL.vcxproj | 285 + .../Nativescript.DLL.vcxproj.filters | 19 + Source/Nativescript.DLL/dllmain.cpp | 14 + Source/Nativescript.DLL/pch.cpp | 1 + Source/Nativescript.DLL/pch.h | 11 + Source/Nativescript.DLL/targetver.h | 8 + Source/TestRunner/App.xaml | 7 + Source/TestRunner/App.xaml.cpp | 127 + Source/TestRunner/App.xaml.h | 29 + Source/TestRunner/App/index.js | 10 + .../Assets/LockScreenLogo.scale-200.png | Bin 0 -> 1430 bytes .../Assets/SplashScreen.scale-200.png | Bin 0 -> 7700 bytes .../Assets/Square150x150Logo.scale-200.png | Bin 0 -> 2937 bytes .../Assets/Square44x44Logo.scale-200.png | Bin 0 -> 1647 bytes ...x44Logo.targetsize-24_altform-unplated.png | Bin 0 -> 1255 bytes Source/TestRunner/Assets/StoreLogo.png | Bin 0 -> 1451 bytes .../Assets/Wide310x150Logo.scale-200.png | Bin 0 -> 3204 bytes Source/TestRunner/Generated Files/App.g.h | 27 + Source/TestRunner/Generated Files/App.g.hpp | 96 + Source/TestRunner/Generated Files/App.xaml | 8 + Source/TestRunner/Generated Files/App.xbf | Bin 0 -> 502 bytes .../TestRunner/Generated Files/MainPage.g.h | 28 + .../TestRunner/Generated Files/MainPage.g.hpp | 40 + .../TestRunner/Generated Files/MainPage.xaml | 15 + .../TestRunner/Generated Files/MainPage.xbf | Bin 0 -> 859 bytes .../Generated Files/XamlBindingInfo.g.h | 57 + .../Generated Files/XamlBindingInfo.g.hpp | 13 + .../XamlLibMetadataProvider.g.cpp | 2 + .../Generated Files/XamlTypeInfo.Impl.g.cpp | 579 ++ .../Generated Files/XamlTypeInfo.g.cpp | 193 + .../Generated Files/XamlTypeInfo.g.h | 351 ++ Source/TestRunner/MainPage.xaml | 14 + Source/TestRunner/MainPage.xaml.cpp | 27 + Source/TestRunner/MainPage.xaml.h | 21 + Source/TestRunner/Package.appxmanifest | 49 + Source/TestRunner/TestRunner.log | 1 + Source/TestRunner/TestRunner.vcxproj | 250 + Source/TestRunner/TestRunner.vcxproj.filters | 57 + Source/TestRunner/TestRunner.vcxproj.user | 6 + Source/TestRunner/pch.cpp | 5 + Source/TestRunner/pch.h | 10 + Source/Windows.Runtime.sln | 105 + Source/Windows.Runtime.vcxproj | 146 + Source/Windows.Runtime.vcxproj.filters | 17 + Source/Windows.Runtime.vcxproj.user | 4 + 349 files changed, 100812 insertions(+) create mode 100644 .gitignore create mode 160000 Source/NativeScript/Inspector/base/trace_event/common create mode 100644 Source/NativeScript/Inspector/src/base/address-region.h create mode 100644 Source/NativeScript/Inspector/src/base/atomic-utils.h create mode 100644 Source/NativeScript/Inspector/src/base/atomicops.h create mode 100644 Source/NativeScript/Inspector/src/base/atomicops_internals_atomicword_compat.h create mode 100644 Source/NativeScript/Inspector/src/base/base-export.h create mode 100644 Source/NativeScript/Inspector/src/base/bits.h create mode 100644 Source/NativeScript/Inspector/src/base/build_config.h create mode 100644 Source/NativeScript/Inspector/src/base/compiler-specific.h create mode 100644 Source/NativeScript/Inspector/src/base/enum-set.h create mode 100644 Source/NativeScript/Inspector/src/base/export-template.h create mode 100644 Source/NativeScript/Inspector/src/base/flags.h create mode 100644 Source/NativeScript/Inspector/src/base/immediate-crash.h create mode 100644 Source/NativeScript/Inspector/src/base/lazy-instance.h create mode 100644 Source/NativeScript/Inspector/src/base/logging.h create mode 100644 Source/NativeScript/Inspector/src/base/macros.h create mode 100644 Source/NativeScript/Inspector/src/base/memory.h create mode 100644 Source/NativeScript/Inspector/src/base/once.h create mode 100644 Source/NativeScript/Inspector/src/base/optional.h create mode 100644 Source/NativeScript/Inspector/src/base/platform/mutex.h create mode 100644 Source/NativeScript/Inspector/src/base/platform/platform.h create mode 100644 Source/NativeScript/Inspector/src/base/platform/semaphore.h create mode 100644 Source/NativeScript/Inspector/src/base/platform/time.h create mode 100644 Source/NativeScript/Inspector/src/base/platform/wrappers.h create mode 100644 Source/NativeScript/Inspector/src/base/safe_conversions.h create mode 100644 Source/NativeScript/Inspector/src/base/safe_conversions_impl.h create mode 100644 Source/NativeScript/Inspector/src/base/strings.h create mode 100644 Source/NativeScript/Inspector/src/base/template-utils.h create mode 100644 Source/NativeScript/Inspector/src/base/v8-fallthrough.h create mode 100644 Source/NativeScript/Inspector/src/base/vector.h create mode 100644 Source/NativeScript/Inspector/src/base/win32-headers.h create mode 100644 Source/NativeScript/Inspector/src/common/checks.h create mode 100644 Source/NativeScript/Inspector/src/common/globals.h create mode 100644 Source/NativeScript/Inspector/src/init/v8.h create mode 100644 Source/NativeScript/Inspector/src/inspector/custom-preview.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/custom-preview.h create mode 100644 Source/NativeScript/Inspector/src/inspector/injected-script.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/injected-script.h create mode 100644 Source/NativeScript/Inspector/src/inspector/inspected-context.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/inspected-context.h create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/CSS.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/CSS.h create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Console.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Console.h create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/DOM.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/DOM.h create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Debugger.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Debugger.h create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Forward.h create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/HeapProfiler.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/HeapProfiler.h create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Log.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Log.h create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Network.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Network.h create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Overlay.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Overlay.h create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Page.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Page.h create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Profiler.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Profiler.h create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Protocol.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Protocol.h create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Runtime.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Runtime.h create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Schema.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Schema.h create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Security.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/protocol/Security.h create mode 100644 Source/NativeScript/Inspector/src/inspector/remote-object-id.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/remote-object-id.h create mode 100644 Source/NativeScript/Inspector/src/inspector/search-util.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/search-util.h create mode 100644 Source/NativeScript/Inspector/src/inspector/string-16.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/string-16.h create mode 100644 Source/NativeScript/Inspector/src/inspector/string-util.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/string-util.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-console-agent-impl.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-console-agent-impl.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-console-message.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-console-message.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-console.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-console.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-css-agent-impl.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-css-agent-impl.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-debugger-agent-impl.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-debugger-agent-impl.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-debugger-id.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-debugger-id.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-debugger-script.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-debugger-script.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-debugger.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-debugger.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-dom-agent-impl.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-dom-agent-impl.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-heap-profiler-agent-impl.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-heap-profiler-agent-impl.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-inspector-impl.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-inspector-impl.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-inspector-session-impl.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-inspector-session-impl.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-log-agent-impl.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-log-agent-impl.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-network-agent-impl.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-network-agent-impl.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-ns-debugger-agent-impl.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-ns-debugger-agent-impl.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-overlay-agent-impl.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-overlay-agent-impl.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-page-agent-impl.cpp create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-page-agent-impl.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-profiler-agent-impl.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-profiler-agent-impl.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-regex.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-regex.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-runtime-agent-impl.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-runtime-agent-impl.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-schema-agent-impl.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-schema-agent-impl.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-stack-trace-impl.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-stack-trace-impl.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-string-conversions.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-string-conversions.h create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-value-utils.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/v8-value-utils.h create mode 100644 Source/NativeScript/Inspector/src/inspector/value-mirror.cc create mode 100644 Source/NativeScript/Inspector/src/inspector/value-mirror.h create mode 100644 Source/NativeScript/Inspector/src/libplatform/default-platform.h create mode 100644 Source/NativeScript/Inspector/src/logging/tracing-flags.h create mode 100644 Source/NativeScript/Inspector/src/numbers/conversions.h create mode 100644 Source/NativeScript/Inspector/src/tracing/trace-event.h create mode 100644 Source/NativeScript/Inspector/src/utils/allocation.h create mode 100644 Source/NativeScript/Inspector/third_party/inspector_protocol/crdtp/cbor.h create mode 100644 Source/NativeScript/Inspector/third_party/inspector_protocol/crdtp/dispatch.h create mode 100644 Source/NativeScript/Inspector/third_party/inspector_protocol/crdtp/error_support.h create mode 100644 Source/NativeScript/Inspector/third_party/inspector_protocol/crdtp/export.h create mode 100644 Source/NativeScript/Inspector/third_party/inspector_protocol/crdtp/find_by_first.h create mode 100644 Source/NativeScript/Inspector/third_party/inspector_protocol/crdtp/frontend_channel.h create mode 100644 Source/NativeScript/Inspector/third_party/inspector_protocol/crdtp/glue.h create mode 100644 Source/NativeScript/Inspector/third_party/inspector_protocol/crdtp/json.h create mode 100644 Source/NativeScript/Inspector/third_party/inspector_protocol/crdtp/json_platform.h create mode 100644 Source/NativeScript/Inspector/third_party/inspector_protocol/crdtp/maybe.h create mode 100644 Source/NativeScript/Inspector/third_party/inspector_protocol/crdtp/parser_handler.h create mode 100644 Source/NativeScript/Inspector/third_party/inspector_protocol/crdtp/protocol_core.h create mode 100644 Source/NativeScript/Inspector/third_party/inspector_protocol/crdtp/serializable.h create mode 100644 Source/NativeScript/Inspector/third_party/inspector_protocol/crdtp/serializer_traits.h create mode 100644 Source/NativeScript/Inspector/third_party/inspector_protocol/crdtp/span.h create mode 100644 Source/NativeScript/Inspector/third_party/inspector_protocol/crdtp/status.h create mode 100644 Source/NativeScript/Inspector/utils.cpp create mode 100644 Source/NativeScript/Inspector/utils.h create mode 100644 Source/NativeScript/Metadata/MetadataReader.cpp create mode 100644 Source/NativeScript/Metadata/MetadataReader.h create mode 100644 Source/NativeScript/NativeScript.cpp create mode 100644 Source/NativeScript/NativeScript.h create mode 100644 Source/NativeScript/NativeScript.log create mode 100644 Source/NativeScript/NativeScript.vcxproj create mode 100644 Source/NativeScript/NativeScript.vcxproj.filters create mode 100644 Source/NativeScript/NativeScript.vcxproj.user create mode 100644 Source/NativeScript/Runtime/Caches.cpp create mode 100644 Source/NativeScript/Runtime/Caches.h create mode 100644 Source/NativeScript/Runtime/Common.h create mode 100644 Source/NativeScript/Runtime/ConcurrentMap.h create mode 100644 Source/NativeScript/Runtime/Console.cpp create mode 100644 Source/NativeScript/Runtime/Console.h create mode 100644 Source/NativeScript/Runtime/Helpers.cpp create mode 100644 Source/NativeScript/Runtime/Helpers.h create mode 100644 Source/NativeScript/Runtime/MetadataBuilder.cpp create mode 100644 Source/NativeScript/Runtime/MetadataBuilder.h create mode 100644 Source/NativeScript/Runtime/ModuleInternal.cpp create mode 100644 Source/NativeScript/Runtime/ModuleInternal.h create mode 100644 Source/NativeScript/Runtime/NativeScriptException.cpp create mode 100644 Source/NativeScript/Runtime/NativeScriptException.h create mode 100644 Source/NativeScript/Runtime/Runtime.cpp create mode 100644 Source/NativeScript/Runtime/Runtime.h create mode 100644 Source/NativeScript/Runtime/RuntimeConfig.cpp create mode 100644 Source/NativeScript/Runtime/RuntimeConfig.h create mode 100644 Source/NativeScript/Runtime/SimpleAllocator.cpp create mode 100644 Source/NativeScript/Runtime/SimpleAllocator.h create mode 100644 Source/NativeScript/Runtime/WeakRef.cpp create mode 100644 Source/NativeScript/Runtime/WeakRef.h create mode 100644 Source/NativeScript/Runtime/robin_hood.h create mode 100644 Source/NativeScript/include/APIDesign.md create mode 100644 Source/NativeScript/include/DEPS create mode 100644 Source/NativeScript/include/DIR_METADATA create mode 100644 Source/NativeScript/include/OWNERS create mode 100644 Source/NativeScript/include/cppgc/DEPS create mode 100644 Source/NativeScript/include/cppgc/OWNERS create mode 100644 Source/NativeScript/include/cppgc/README.md create mode 100644 Source/NativeScript/include/cppgc/allocation.h create mode 100644 Source/NativeScript/include/cppgc/common.h create mode 100644 Source/NativeScript/include/cppgc/cross-thread-persistent.h create mode 100644 Source/NativeScript/include/cppgc/custom-space.h create mode 100644 Source/NativeScript/include/cppgc/default-platform.h create mode 100644 Source/NativeScript/include/cppgc/ephemeron-pair.h create mode 100644 Source/NativeScript/include/cppgc/explicit-management.h create mode 100644 Source/NativeScript/include/cppgc/garbage-collected.h create mode 100644 Source/NativeScript/include/cppgc/heap-consistency.h create mode 100644 Source/NativeScript/include/cppgc/heap-state.h create mode 100644 Source/NativeScript/include/cppgc/heap-statistics.h create mode 100644 Source/NativeScript/include/cppgc/heap.h create mode 100644 Source/NativeScript/include/cppgc/internal/api-constants.h create mode 100644 Source/NativeScript/include/cppgc/internal/atomic-entry-flag.h create mode 100644 Source/NativeScript/include/cppgc/internal/caged-heap-local-data.h create mode 100644 Source/NativeScript/include/cppgc/internal/compiler-specific.h create mode 100644 Source/NativeScript/include/cppgc/internal/finalizer-trait.h create mode 100644 Source/NativeScript/include/cppgc/internal/gc-info.h create mode 100644 Source/NativeScript/include/cppgc/internal/logging.h create mode 100644 Source/NativeScript/include/cppgc/internal/name-trait.h create mode 100644 Source/NativeScript/include/cppgc/internal/persistent-node.h create mode 100644 Source/NativeScript/include/cppgc/internal/pointer-policies.h create mode 100644 Source/NativeScript/include/cppgc/internal/prefinalizer-handler.h create mode 100644 Source/NativeScript/include/cppgc/internal/write-barrier.h create mode 100644 Source/NativeScript/include/cppgc/liveness-broker.h create mode 100644 Source/NativeScript/include/cppgc/macros.h create mode 100644 Source/NativeScript/include/cppgc/member.h create mode 100644 Source/NativeScript/include/cppgc/name-provider.h create mode 100644 Source/NativeScript/include/cppgc/object-size-trait.h create mode 100644 Source/NativeScript/include/cppgc/persistent.h create mode 100644 Source/NativeScript/include/cppgc/platform.h create mode 100644 Source/NativeScript/include/cppgc/prefinalizer.h create mode 100644 Source/NativeScript/include/cppgc/process-heap-statistics.h create mode 100644 Source/NativeScript/include/cppgc/sentinel-pointer.h create mode 100644 Source/NativeScript/include/cppgc/source-location.h create mode 100644 Source/NativeScript/include/cppgc/testing.h create mode 100644 Source/NativeScript/include/cppgc/trace-trait.h create mode 100644 Source/NativeScript/include/cppgc/type-traits.h create mode 100644 Source/NativeScript/include/cppgc/visitor.h create mode 100644 Source/NativeScript/include/inspector/Debugger.h create mode 100644 Source/NativeScript/include/inspector/Runtime.h create mode 100644 Source/NativeScript/include/inspector/Schema.h create mode 100644 Source/NativeScript/include/js_protocol-1.2.json create mode 100644 Source/NativeScript/include/js_protocol-1.3.json create mode 100644 Source/NativeScript/include/js_protocol.pdl create mode 100644 Source/NativeScript/include/libplatform/DEPS create mode 100644 Source/NativeScript/include/libplatform/libplatform-export.h create mode 100644 Source/NativeScript/include/libplatform/libplatform.h create mode 100644 Source/NativeScript/include/libplatform/v8-tracing.h create mode 100644 Source/NativeScript/include/v8-array-buffer.h create mode 100644 Source/NativeScript/include/v8-callbacks.h create mode 100644 Source/NativeScript/include/v8-container.h create mode 100644 Source/NativeScript/include/v8-context.h create mode 100644 Source/NativeScript/include/v8-cppgc.h create mode 100644 Source/NativeScript/include/v8-data.h create mode 100644 Source/NativeScript/include/v8-date.h create mode 100644 Source/NativeScript/include/v8-debug.h create mode 100644 Source/NativeScript/include/v8-embedder-heap.h create mode 100644 Source/NativeScript/include/v8-embedder-state-scope.h create mode 100644 Source/NativeScript/include/v8-exception.h create mode 100644 Source/NativeScript/include/v8-extension.h create mode 100644 Source/NativeScript/include/v8-external.h create mode 100644 Source/NativeScript/include/v8-fast-api-calls.h create mode 100644 Source/NativeScript/include/v8-forward.h create mode 100644 Source/NativeScript/include/v8-function-callback.h create mode 100644 Source/NativeScript/include/v8-function.h create mode 100644 Source/NativeScript/include/v8-initialization.h create mode 100644 Source/NativeScript/include/v8-inspector-protocol.h create mode 100644 Source/NativeScript/include/v8-inspector.h create mode 100644 Source/NativeScript/include/v8-internal.h create mode 100644 Source/NativeScript/include/v8-isolate.h create mode 100644 Source/NativeScript/include/v8-json.h create mode 100644 Source/NativeScript/include/v8-local-handle.h create mode 100644 Source/NativeScript/include/v8-locker.h create mode 100644 Source/NativeScript/include/v8-maybe.h create mode 100644 Source/NativeScript/include/v8-memory-span.h create mode 100644 Source/NativeScript/include/v8-message.h create mode 100644 Source/NativeScript/include/v8-metrics.h create mode 100644 Source/NativeScript/include/v8-microtask-queue.h create mode 100644 Source/NativeScript/include/v8-microtask.h create mode 100644 Source/NativeScript/include/v8-object.h create mode 100644 Source/NativeScript/include/v8-persistent-handle.h create mode 100644 Source/NativeScript/include/v8-platform.h create mode 100644 Source/NativeScript/include/v8-primitive-object.h create mode 100644 Source/NativeScript/include/v8-primitive.h create mode 100644 Source/NativeScript/include/v8-profiler.h create mode 100644 Source/NativeScript/include/v8-promise.h create mode 100644 Source/NativeScript/include/v8-proxy.h create mode 100644 Source/NativeScript/include/v8-regexp.h create mode 100644 Source/NativeScript/include/v8-script.h create mode 100644 Source/NativeScript/include/v8-snapshot.h create mode 100644 Source/NativeScript/include/v8-statistics.h create mode 100644 Source/NativeScript/include/v8-template.h create mode 100644 Source/NativeScript/include/v8-traced-handle.h create mode 100644 Source/NativeScript/include/v8-typed-array.h create mode 100644 Source/NativeScript/include/v8-unwinder-state.h create mode 100644 Source/NativeScript/include/v8-unwinder.h create mode 100644 Source/NativeScript/include/v8-util.h create mode 100644 Source/NativeScript/include/v8-value-serializer-version.h create mode 100644 Source/NativeScript/include/v8-value-serializer.h create mode 100644 Source/NativeScript/include/v8-value.h create mode 100644 Source/NativeScript/include/v8-version-string.h create mode 100644 Source/NativeScript/include/v8-version.h create mode 100644 Source/NativeScript/include/v8-wasm-trap-handler-posix.h create mode 100644 Source/NativeScript/include/v8-wasm-trap-handler-win.h create mode 100644 Source/NativeScript/include/v8-wasm.h create mode 100644 Source/NativeScript/include/v8-weak-callback-info.h create mode 100644 Source/NativeScript/include/v8.h create mode 100644 Source/NativeScript/include/v8config.h create mode 100644 Source/NativeScript/pch.cpp create mode 100644 Source/NativeScript/pch.h create mode 100644 Source/NativeScript/targetver.h create mode 100644 Source/Nativescript.DLL/Nativescript.DLL.cpp create mode 100644 Source/Nativescript.DLL/Nativescript.DLL.h create mode 100644 Source/Nativescript.DLL/Nativescript.DLL.log create mode 100644 Source/Nativescript.DLL/Nativescript.DLL.vcxproj create mode 100644 Source/Nativescript.DLL/Nativescript.DLL.vcxproj.filters create mode 100644 Source/Nativescript.DLL/dllmain.cpp create mode 100644 Source/Nativescript.DLL/pch.cpp create mode 100644 Source/Nativescript.DLL/pch.h create mode 100644 Source/Nativescript.DLL/targetver.h create mode 100644 Source/TestRunner/App.xaml create mode 100644 Source/TestRunner/App.xaml.cpp create mode 100644 Source/TestRunner/App.xaml.h create mode 100644 Source/TestRunner/App/index.js create mode 100644 Source/TestRunner/Assets/LockScreenLogo.scale-200.png create mode 100644 Source/TestRunner/Assets/SplashScreen.scale-200.png create mode 100644 Source/TestRunner/Assets/Square150x150Logo.scale-200.png create mode 100644 Source/TestRunner/Assets/Square44x44Logo.scale-200.png create mode 100644 Source/TestRunner/Assets/Square44x44Logo.targetsize-24_altform-unplated.png create mode 100644 Source/TestRunner/Assets/StoreLogo.png create mode 100644 Source/TestRunner/Assets/Wide310x150Logo.scale-200.png create mode 100644 Source/TestRunner/Generated Files/App.g.h create mode 100644 Source/TestRunner/Generated Files/App.g.hpp create mode 100644 Source/TestRunner/Generated Files/App.xaml create mode 100644 Source/TestRunner/Generated Files/App.xbf create mode 100644 Source/TestRunner/Generated Files/MainPage.g.h create mode 100644 Source/TestRunner/Generated Files/MainPage.g.hpp create mode 100644 Source/TestRunner/Generated Files/MainPage.xaml create mode 100644 Source/TestRunner/Generated Files/MainPage.xbf create mode 100644 Source/TestRunner/Generated Files/XamlBindingInfo.g.h create mode 100644 Source/TestRunner/Generated Files/XamlBindingInfo.g.hpp create mode 100644 Source/TestRunner/Generated Files/XamlLibMetadataProvider.g.cpp create mode 100644 Source/TestRunner/Generated Files/XamlTypeInfo.Impl.g.cpp create mode 100644 Source/TestRunner/Generated Files/XamlTypeInfo.g.cpp create mode 100644 Source/TestRunner/Generated Files/XamlTypeInfo.g.h create mode 100644 Source/TestRunner/MainPage.xaml create mode 100644 Source/TestRunner/MainPage.xaml.cpp create mode 100644 Source/TestRunner/MainPage.xaml.h create mode 100644 Source/TestRunner/Package.appxmanifest create mode 100644 Source/TestRunner/TestRunner.log create mode 100644 Source/TestRunner/TestRunner.vcxproj create mode 100644 Source/TestRunner/TestRunner.vcxproj.filters create mode 100644 Source/TestRunner/TestRunner.vcxproj.user create mode 100644 Source/TestRunner/pch.cpp create mode 100644 Source/TestRunner/pch.h create mode 100644 Source/Windows.Runtime.sln create mode 100644 Source/Windows.Runtime.vcxproj create mode 100644 Source/Windows.Runtime.vcxproj.filters create mode 100644 Source/Windows.Runtime.vcxproj.user diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..adaf92f --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ + + + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile + + +# Visual Studio 2015 cache/options directory +.vs/ \ No newline at end of file diff --git a/Source/NativeScript/Inspector/base/trace_event/common b/Source/NativeScript/Inspector/base/trace_event/common new file mode 160000 index 0000000..7f36dbc --- /dev/null +++ b/Source/NativeScript/Inspector/base/trace_event/common @@ -0,0 +1 @@ +Subproject commit 7f36dbc19d31e2aad895c60261ca8f726442bfbb diff --git a/Source/NativeScript/Inspector/src/base/address-region.h b/Source/NativeScript/Inspector/src/base/address-region.h new file mode 100644 index 0000000..010a123 --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/address-region.h @@ -0,0 +1,95 @@ +// Copyright 2018 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_BASE_ADDRESS_REGION_H_ +#define V8_BASE_ADDRESS_REGION_H_ + +#include + +#include "src/base/macros.h" + +namespace v8 { +namespace base { + +// Helper class representing an address region of certain size. +class AddressRegion { + public: + // Function object that compares the start address of two regions. Usable as + // compare function on std data structures and algorithms. + struct StartAddressLess { + bool operator()(base::AddressRegion a, base::AddressRegion b) const { + return a.begin() < b.begin(); + } + }; + + using Address = uintptr_t; + + constexpr AddressRegion() = default; + + constexpr AddressRegion(Address address, size_t size) + : address_(address), size_(size) {} + + Address begin() const { return address_; } + Address end() const { return address_ + size_; } + + size_t size() const { return size_; } + void set_size(size_t size) { size_ = size; } + + bool is_empty() const { return size_ == 0; } + + bool contains(Address address) const { + STATIC_ASSERT(std::is_unsigned
::value); + return (address - begin()) < size(); + } + + bool contains(Address address, size_t size) const { + STATIC_ASSERT(std::is_unsigned
::value); + Address offset = address - begin(); + return (offset < size_) && (offset + size <= size_); + } + + bool contains(AddressRegion region) const { + return contains(region.address_, region.size_); + } + + base::AddressRegion GetOverlap(AddressRegion region) const { + Address overlap_start = std::max(begin(), region.begin()); + Address overlap_end = + std::max(overlap_start, std::min(end(), region.end())); + return {overlap_start, overlap_end - overlap_start}; + } + + bool operator==(AddressRegion other) const { + return address_ == other.address_ && size_ == other.size_; + } + + bool operator!=(AddressRegion other) const { + return address_ != other.address_ || size_ != other.size_; + } + + private: + Address address_ = 0; + size_t size_ = 0; +}; +ASSERT_TRIVIALLY_COPYABLE(AddressRegion); + +// Construct an AddressRegion from anything providing a {data()} and {size()} +// accessor. +template ().data()), + typename = decltype(std::declval().size())> +inline constexpr AddressRegion AddressRegionOf(Container&& c) { + return AddressRegion{reinterpret_cast(c.data()), + sizeof(*c.data()) * c.size()}; +} + +inline std::ostream& operator<<(std::ostream& out, AddressRegion region) { + return out << "[" << reinterpret_cast(region.begin()) << "+" + << region.size() << "]"; +} + +} // namespace base +} // namespace v8 + +#endif // V8_BASE_ADDRESS_REGION_H_ diff --git a/Source/NativeScript/Inspector/src/base/atomic-utils.h b/Source/NativeScript/Inspector/src/base/atomic-utils.h new file mode 100644 index 0000000..84015af --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/atomic-utils.h @@ -0,0 +1,250 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_BASE_ATOMIC_UTILS_H_ +#define V8_BASE_ATOMIC_UTILS_H_ + +#include + +#include +#include + +#include "src/base/atomicops.h" +#include "src/base/macros.h" + +namespace v8 { +namespace base { + +// Deprecated. Use std::atomic for new code. +// Flag using T atomically. Also accepts void* as T. +template +class AtomicValue { + public: + AtomicValue() : value_(0) {} + + explicit AtomicValue(T initial) + : value_(cast_helper::to_storage_type(initial)) {} + + V8_INLINE T Value() const { + return cast_helper::to_return_type(base::Acquire_Load(&value_)); + } + + V8_INLINE void SetValue(T new_value) { + base::Release_Store(&value_, cast_helper::to_storage_type(new_value)); + } + + private: + STATIC_ASSERT(sizeof(T) <= sizeof(base::AtomicWord)); + + template + struct cast_helper { + static base::AtomicWord to_storage_type(S value) { + return static_cast(value); + } + static S to_return_type(base::AtomicWord value) { + return static_cast(value); + } + }; + + template + struct cast_helper { + static base::AtomicWord to_storage_type(S* value) { + return reinterpret_cast(value); + } + static S* to_return_type(base::AtomicWord value) { + return reinterpret_cast(value); + } + }; + + base::AtomicWord value_; +}; + +// Provides atomic operations for a values stored at some address. +template +class AsAtomicImpl { + public: + using AtomicStorageType = TAtomicStorageType; + + template + static T Acquire_Load(T* addr) { + STATIC_ASSERT(sizeof(T) <= sizeof(AtomicStorageType)); + return cast_helper::to_return_type( + base::Acquire_Load(to_storage_addr(addr))); + } + + template + static T Relaxed_Load(T* addr) { + STATIC_ASSERT(sizeof(T) <= sizeof(AtomicStorageType)); + return cast_helper::to_return_type( + base::Relaxed_Load(to_storage_addr(addr))); + } + + template + static void Release_Store(T* addr, + typename std::remove_reference::type new_value) { + STATIC_ASSERT(sizeof(T) <= sizeof(AtomicStorageType)); + base::Release_Store(to_storage_addr(addr), + cast_helper::to_storage_type(new_value)); + } + + template + static void Relaxed_Store(T* addr, + typename std::remove_reference::type new_value) { + STATIC_ASSERT(sizeof(T) <= sizeof(AtomicStorageType)); + base::Relaxed_Store(to_storage_addr(addr), + cast_helper::to_storage_type(new_value)); + } + + template + static T Release_CompareAndSwap( + T* addr, typename std::remove_reference::type old_value, + typename std::remove_reference::type new_value) { + STATIC_ASSERT(sizeof(T) <= sizeof(AtomicStorageType)); + return cast_helper::to_return_type(base::Release_CompareAndSwap( + to_storage_addr(addr), cast_helper::to_storage_type(old_value), + cast_helper::to_storage_type(new_value))); + } + + template + static T Relaxed_CompareAndSwap( + T* addr, typename std::remove_reference::type old_value, + typename std::remove_reference::type new_value) { + STATIC_ASSERT(sizeof(T) <= sizeof(AtomicStorageType)); + return cast_helper::to_return_type(base::Relaxed_CompareAndSwap( + to_storage_addr(addr), cast_helper::to_storage_type(old_value), + cast_helper::to_storage_type(new_value))); + } + + template + static T AcquireRelease_CompareAndSwap( + T* addr, typename std::remove_reference::type old_value, + typename std::remove_reference::type new_value) { + STATIC_ASSERT(sizeof(T) <= sizeof(AtomicStorageType)); + return cast_helper::to_return_type(base::AcquireRelease_CompareAndSwap( + to_storage_addr(addr), cast_helper::to_storage_type(old_value), + cast_helper::to_storage_type(new_value))); + } + + // Atomically sets bits selected by the mask to the given value. + // Returns false if the bits are already set as needed. + template + static bool SetBits(T* addr, T bits, T mask) { + STATIC_ASSERT(sizeof(T) <= sizeof(AtomicStorageType)); + DCHECK_EQ(bits & ~mask, static_cast(0)); + T old_value = Relaxed_Load(addr); + T new_value, old_value_before_cas; + do { + if ((old_value & mask) == bits) return false; + new_value = (old_value & ~mask) | bits; + old_value_before_cas = old_value; + old_value = Release_CompareAndSwap(addr, old_value, new_value); + } while (old_value != old_value_before_cas); + return true; + } + + private: + template + struct cast_helper { + static AtomicStorageType to_storage_type(U value) { + return static_cast(value); + } + static U to_return_type(AtomicStorageType value) { + return static_cast(value); + } + }; + + template + struct cast_helper { + static AtomicStorageType to_storage_type(U* value) { + return reinterpret_cast(value); + } + static U* to_return_type(AtomicStorageType value) { + return reinterpret_cast(value); + } + }; + + template + static AtomicStorageType* to_storage_addr(T* value) { + return reinterpret_cast(value); + } + template + static const AtomicStorageType* to_storage_addr(const T* value) { + return reinterpret_cast(value); + } +}; + +using AsAtomic8 = AsAtomicImpl; +using AsAtomic32 = AsAtomicImpl; +using AsAtomicWord = AsAtomicImpl; + +template +struct AtomicTypeFromByteWidth {}; +template <> +struct AtomicTypeFromByteWidth<1> { + using type = base::Atomic8; +}; +template <> +struct AtomicTypeFromByteWidth<2> { + using type = base::Atomic16; +}; +template <> +struct AtomicTypeFromByteWidth<4> { + using type = base::Atomic32; +}; +#if V8_HOST_ARCH_64_BIT +template <> +struct AtomicTypeFromByteWidth<8> { + using type = base::Atomic64; +}; +#endif + +// This is similar to AsAtomicWord but it explicitly deletes functionality +// provided atomic access to bit representation of stored values. +template +class AsAtomicPointerImpl : public AsAtomicImpl { + public: + template + static bool SetBits(T* addr, T bits, T mask) = delete; +}; + +using AsAtomicPointer = AsAtomicPointerImpl; + +template ::value>::type> +inline void CheckedIncrement( + std::atomic* number, T amount, + std::memory_order order = std::memory_order_seq_cst) { + const T old = number->fetch_add(amount, order); + DCHECK_GE(old + amount, old); + USE(old); +} + +template ::value>::type> +inline void CheckedDecrement( + std::atomic* number, T amount, + std::memory_order order = std::memory_order_seq_cst) { + const T old = number->fetch_sub(amount, order); + DCHECK_GE(old, amount); + USE(old); +} + +template +V8_INLINE std::atomic* AsAtomicPtr(T* t) { + STATIC_ASSERT(sizeof(T) == sizeof(std::atomic)); + STATIC_ASSERT(alignof(T) >= alignof(std::atomic)); + return reinterpret_cast*>(t); +} + +template +V8_INLINE const std::atomic* AsAtomicPtr(const T* t) { + STATIC_ASSERT(sizeof(T) == sizeof(std::atomic)); + STATIC_ASSERT(alignof(T) >= alignof(std::atomic)); + return reinterpret_cast*>(t); +} + +} // namespace base +} // namespace v8 + +#endif // V8_BASE_ATOMIC_UTILS_H_ diff --git a/Source/NativeScript/Inspector/src/base/atomicops.h b/Source/NativeScript/Inspector/src/base/atomicops.h new file mode 100644 index 0000000..56fd5f3 --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/atomicops.h @@ -0,0 +1,448 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The routines exported by this module are subtle. If you use them, even if +// you get the code right, it will depend on careful reasoning about atomicity +// and memory ordering; it will be less readable, and harder to maintain. If +// you plan to use these routines, you should have a good reason, such as solid +// evidence that performance would otherwise suffer, or there being no +// alternative. You should assume only properties explicitly guaranteed by the +// specifications in this file. You are almost certainly _not_ writing code +// just for the x86; if you assume x86 semantics, x86 hardware bugs and +// implementations on other archtectures will cause your code to break. If you +// do not know what you are doing, avoid these routines, and use a Mutex. +// +// It is incorrect to make direct assignments to/from an atomic variable. +// You should use one of the Load or Store routines. The Relaxed versions +// are provided when no fences are needed: +// Relaxed_Store() +// Relaxed_Load() +// Although there are currently no compiler enforcement, you are encouraged +// to use these. +// + +#ifndef V8_BASE_ATOMICOPS_H_ +#define V8_BASE_ATOMICOPS_H_ + +#include + +#include + +// Small C++ header which defines implementation specific macros used to +// identify the STL implementation. +// - libc++: captures __config for _LIBCPP_VERSION +// - libstdc++: captures bits/c++config.h for __GLIBCXX__ +#include + +#include "src/base/base-export.h" +#include "src/base/build_config.h" +#include "src/base/macros.h" + +#if defined(V8_OS_STARBOARD) +#include "starboard/atomic.h" +#endif // V8_OS_STARBOARD + +namespace v8 { +namespace base { + +#ifdef V8_OS_STARBOARD +using Atomic8 = SbAtomic8; +using Atomic16 = int16_t; +using Atomic32 = SbAtomic32; +#if SB_IS_64_BIT +using Atomic64 = SbAtomic64; +#endif +#else +using Atomic8 = char; +using Atomic16 = int16_t; +using Atomic32 = int32_t; +#if defined(V8_HOST_ARCH_64_BIT) +// We need to be able to go between Atomic64 and AtomicWord implicitly. This +// means Atomic64 and AtomicWord should be the same type on 64-bit. +#if defined(__ILP32__) +using Atomic64 = int64_t; +#else +using Atomic64 = intptr_t; +#endif // defined(__ILP32__) +#endif // defined(V8_HOST_ARCH_64_BIT) +#endif // V8_OS_STARBOARD + +// Use AtomicWord for a machine-sized pointer. It will use the Atomic32 or +// Atomic64 routines below, depending on your architecture. +#if defined(V8_OS_STARBOARD) +using AtomicWord = SbAtomicPtr; +#else +using AtomicWord = intptr_t; +#endif + +namespace helper { +template +volatile std::atomic* to_std_atomic(volatile T* ptr) { + return reinterpret_cast*>(ptr); +} +template +volatile const std::atomic* to_std_atomic_const(volatile const T* ptr) { + return reinterpret_cast*>(ptr); +} +} // namespace helper + +inline void SeqCst_MemoryFence() { + std::atomic_thread_fence(std::memory_order_seq_cst); +} + +// Atomically execute: +// result = *ptr; +// if (result == old_value) +// *ptr = new_value; +// return result; +// +// I.e. replace |*ptr| with |new_value| if |*ptr| used to be |old_value|. +// Always return the value of |*ptr| before the operation. +// Acquire, Relaxed, Release correspond to standard C++ memory orders. +inline Atomic8 Relaxed_CompareAndSwap(volatile Atomic8* ptr, Atomic8 old_value, + Atomic8 new_value) { + std::atomic_compare_exchange_strong_explicit( + helper::to_std_atomic(ptr), &old_value, new_value, + std::memory_order_relaxed, std::memory_order_relaxed); + return old_value; +} + +inline Atomic16 Relaxed_CompareAndSwap(volatile Atomic16* ptr, + Atomic16 old_value, Atomic16 new_value) { + std::atomic_compare_exchange_strong_explicit( + helper::to_std_atomic(ptr), &old_value, new_value, + std::memory_order_relaxed, std::memory_order_relaxed); + return old_value; +} + +inline Atomic32 Relaxed_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, Atomic32 new_value) { + std::atomic_compare_exchange_strong_explicit( + helper::to_std_atomic(ptr), &old_value, new_value, + std::memory_order_relaxed, std::memory_order_relaxed); + return old_value; +} + +inline Atomic32 Relaxed_AtomicExchange(volatile Atomic32* ptr, + Atomic32 new_value) { + return std::atomic_exchange_explicit(helper::to_std_atomic(ptr), new_value, + std::memory_order_relaxed); +} + +inline Atomic32 Relaxed_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return increment + std::atomic_fetch_add_explicit(helper::to_std_atomic(ptr), + increment, + std::memory_order_relaxed); +} + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, Atomic32 new_value) { + atomic_compare_exchange_strong_explicit( + helper::to_std_atomic(ptr), &old_value, new_value, + std::memory_order_acquire, std::memory_order_acquire); + return old_value; +} + +inline Atomic8 Release_CompareAndSwap(volatile Atomic8* ptr, Atomic8 old_value, + Atomic8 new_value) { + bool result = atomic_compare_exchange_strong_explicit( + helper::to_std_atomic(ptr), &old_value, new_value, + std::memory_order_release, std::memory_order_relaxed); + USE(result); // Make gcc compiler happy. + return old_value; +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, Atomic32 new_value) { + atomic_compare_exchange_strong_explicit( + helper::to_std_atomic(ptr), &old_value, new_value, + std::memory_order_release, std::memory_order_relaxed); + return old_value; +} + +inline Atomic32 AcquireRelease_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + atomic_compare_exchange_strong_explicit( + helper::to_std_atomic(ptr), &old_value, new_value, + std::memory_order_acq_rel, std::memory_order_acquire); + return old_value; +} + +inline void Relaxed_Store(volatile Atomic8* ptr, Atomic8 value) { + std::atomic_store_explicit(helper::to_std_atomic(ptr), value, + std::memory_order_relaxed); +} + +inline void Relaxed_Store(volatile Atomic16* ptr, Atomic16 value) { + std::atomic_store_explicit(helper::to_std_atomic(ptr), value, + std::memory_order_relaxed); +} + +inline void Relaxed_Store(volatile Atomic32* ptr, Atomic32 value) { + std::atomic_store_explicit(helper::to_std_atomic(ptr), value, + std::memory_order_relaxed); +} + +inline void Release_Store(volatile Atomic8* ptr, Atomic8 value) { + std::atomic_store_explicit(helper::to_std_atomic(ptr), value, + std::memory_order_release); +} + +inline void Release_Store(volatile Atomic16* ptr, Atomic16 value) { + std::atomic_store_explicit(helper::to_std_atomic(ptr), value, + std::memory_order_release); +} + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + std::atomic_store_explicit(helper::to_std_atomic(ptr), value, + std::memory_order_release); +} + +inline void SeqCst_Store(volatile Atomic8* ptr, Atomic8 value) { + std::atomic_store_explicit(helper::to_std_atomic(ptr), value, + std::memory_order_seq_cst); +} + +inline void SeqCst_Store(volatile Atomic16* ptr, Atomic16 value) { + std::atomic_store_explicit(helper::to_std_atomic(ptr), value, + std::memory_order_seq_cst); +} + +inline void SeqCst_Store(volatile Atomic32* ptr, Atomic32 value) { + std::atomic_store_explicit(helper::to_std_atomic(ptr), value, + std::memory_order_seq_cst); +} + +inline Atomic8 Relaxed_Load(volatile const Atomic8* ptr) { + return std::atomic_load_explicit(helper::to_std_atomic_const(ptr), + std::memory_order_relaxed); +} + +inline Atomic16 Relaxed_Load(volatile const Atomic16* ptr) { + return std::atomic_load_explicit(helper::to_std_atomic_const(ptr), + std::memory_order_relaxed); +} + +inline Atomic32 Relaxed_Load(volatile const Atomic32* ptr) { + return std::atomic_load_explicit(helper::to_std_atomic_const(ptr), + std::memory_order_relaxed); +} + +inline Atomic8 Acquire_Load(volatile const Atomic8* ptr) { + return std::atomic_load_explicit(helper::to_std_atomic_const(ptr), + std::memory_order_acquire); +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + return std::atomic_load_explicit(helper::to_std_atomic_const(ptr), + std::memory_order_acquire); +} + +#if defined(V8_HOST_ARCH_64_BIT) + +inline Atomic64 Relaxed_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, Atomic64 new_value) { + std::atomic_compare_exchange_strong_explicit( + helper::to_std_atomic(ptr), &old_value, new_value, + std::memory_order_relaxed, std::memory_order_relaxed); + return old_value; +} + +inline Atomic64 Relaxed_AtomicExchange(volatile Atomic64* ptr, + Atomic64 new_value) { + return std::atomic_exchange_explicit(helper::to_std_atomic(ptr), new_value, + std::memory_order_relaxed); +} + +inline Atomic64 Relaxed_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + return increment + std::atomic_fetch_add_explicit(helper::to_std_atomic(ptr), + increment, + std::memory_order_relaxed); +} + +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, Atomic64 new_value) { + std::atomic_compare_exchange_strong_explicit( + helper::to_std_atomic(ptr), &old_value, new_value, + std::memory_order_acquire, std::memory_order_acquire); + return old_value; +} + +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, Atomic64 new_value) { + std::atomic_compare_exchange_strong_explicit( + helper::to_std_atomic(ptr), &old_value, new_value, + std::memory_order_release, std::memory_order_relaxed); + return old_value; +} + +inline Atomic64 AcquireRelease_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + std::atomic_compare_exchange_strong_explicit( + helper::to_std_atomic(ptr), &old_value, new_value, + std::memory_order_acq_rel, std::memory_order_acquire); + return old_value; +} + +inline void Relaxed_Store(volatile Atomic64* ptr, Atomic64 value) { + std::atomic_store_explicit(helper::to_std_atomic(ptr), value, + std::memory_order_relaxed); +} + +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { + std::atomic_store_explicit(helper::to_std_atomic(ptr), value, + std::memory_order_release); +} + +inline void SeqCst_Store(volatile Atomic64* ptr, Atomic64 value) { + std::atomic_store_explicit(helper::to_std_atomic(ptr), value, + std::memory_order_seq_cst); +} + +inline Atomic64 Relaxed_Load(volatile const Atomic64* ptr) { + return std::atomic_load_explicit(helper::to_std_atomic_const(ptr), + std::memory_order_relaxed); +} + +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { + return std::atomic_load_explicit(helper::to_std_atomic_const(ptr), + std::memory_order_acquire); +} + +#endif // defined(V8_HOST_ARCH_64_BIT) + +inline void Relaxed_Memcpy(volatile Atomic8* dst, volatile const Atomic8* src, + size_t bytes) { + constexpr size_t kAtomicWordSize = sizeof(AtomicWord); + while (bytes > 0 && + !IsAligned(reinterpret_cast(dst), kAtomicWordSize)) { + Relaxed_Store(dst++, Relaxed_Load(src++)); + --bytes; + } + if (IsAligned(reinterpret_cast(src), kAtomicWordSize) && + IsAligned(reinterpret_cast(dst), kAtomicWordSize)) { + while (bytes >= kAtomicWordSize) { + Relaxed_Store( + reinterpret_cast(dst), + Relaxed_Load(reinterpret_cast(src))); + dst += kAtomicWordSize; + src += kAtomicWordSize; + bytes -= kAtomicWordSize; + } + } + while (bytes > 0) { + Relaxed_Store(dst++, Relaxed_Load(src++)); + --bytes; + } +} + +inline void Relaxed_Memmove(volatile Atomic8* dst, volatile const Atomic8* src, + size_t bytes) { + // Use Relaxed_Memcpy if copying forwards is safe. This is the case if there + // is no overlap, or {dst} lies before {src}. + // This single check checks for both: + if (reinterpret_cast(dst) - reinterpret_cast(src) >= + bytes) { + Relaxed_Memcpy(dst, src, bytes); + return; + } + + // Otherwise copy backwards. + dst += bytes; + src += bytes; + constexpr size_t kAtomicWordSize = sizeof(AtomicWord); + while (bytes > 0 && + !IsAligned(reinterpret_cast(dst), kAtomicWordSize)) { + Relaxed_Store(--dst, Relaxed_Load(--src)); + --bytes; + } + if (IsAligned(reinterpret_cast(src), kAtomicWordSize) && + IsAligned(reinterpret_cast(dst), kAtomicWordSize)) { + while (bytes >= kAtomicWordSize) { + dst -= kAtomicWordSize; + src -= kAtomicWordSize; + bytes -= kAtomicWordSize; + Relaxed_Store( + reinterpret_cast(dst), + Relaxed_Load(reinterpret_cast(src))); + } + } + while (bytes > 0) { + Relaxed_Store(--dst, Relaxed_Load(--src)); + --bytes; + } +} + +namespace helper { +inline int MemcmpNotEqualFundamental(Atomic8 u1, Atomic8 u2) { + DCHECK_NE(u1, u2); + return u1 < u2 ? -1 : 1; +} +inline int MemcmpNotEqualFundamental(AtomicWord u1, AtomicWord u2) { + DCHECK_NE(u1, u2); +#if defined(V8_TARGET_BIG_ENDIAN) + return u1 < u2 ? -1 : 1; +#else + for (size_t i = 0; i < sizeof(AtomicWord); ++i) { + uint8_t byte1 = u1 & 0xFF; + uint8_t byte2 = u2 & 0xFF; + if (byte1 != byte2) return byte1 < byte2 ? -1 : 1; + u1 >>= 8; + u2 >>= 8; + } + UNREACHABLE(); +#endif +} +} // namespace helper + +inline int Relaxed_Memcmp(volatile const Atomic8* s1, + volatile const Atomic8* s2, size_t len) { + constexpr size_t kAtomicWordSize = sizeof(AtomicWord); + while (len > 0 && + !(IsAligned(reinterpret_cast(s1), kAtomicWordSize) && + IsAligned(reinterpret_cast(s2), kAtomicWordSize))) { + Atomic8 u1 = Relaxed_Load(s1++); + Atomic8 u2 = Relaxed_Load(s2++); + if (u1 != u2) return helper::MemcmpNotEqualFundamental(u1, u2); + --len; + } + + if (IsAligned(reinterpret_cast(s1), kAtomicWordSize) && + IsAligned(reinterpret_cast(s2), kAtomicWordSize)) { + while (len >= kAtomicWordSize) { + AtomicWord u1 = + Relaxed_Load(reinterpret_cast(s1)); + AtomicWord u2 = + Relaxed_Load(reinterpret_cast(s2)); + if (u1 != u2) return helper::MemcmpNotEqualFundamental(u1, u2); + s1 += kAtomicWordSize; + s2 += kAtomicWordSize; + len -= kAtomicWordSize; + } + } + + while (len > 0) { + Atomic8 u1 = Relaxed_Load(s1++); + Atomic8 u2 = Relaxed_Load(s2++); + if (u1 != u2) return helper::MemcmpNotEqualFundamental(u1, u2); + --len; + } + + return 0; +} + +} // namespace base +} // namespace v8 + +// On some platforms we need additional declarations to make +// AtomicWord compatible with our other Atomic* types. +#if defined(V8_OS_MACOSX) || defined(V8_OS_OPENBSD) || defined(V8_OS_AIX) +#include "src/base/atomicops_internals_atomicword_compat.h" +#endif + +#endif // V8_BASE_ATOMICOPS_H_ diff --git a/Source/NativeScript/Inspector/src/base/atomicops_internals_atomicword_compat.h b/Source/NativeScript/Inspector/src/base/atomicops_internals_atomicword_compat.h new file mode 100644 index 0000000..5ed7d55 --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/atomicops_internals_atomicword_compat.h @@ -0,0 +1,89 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef V8_BASE_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_ +#define V8_BASE_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_ + +// AtomicWord is a synonym for intptr_t, and Atomic32 is a synonym for int32, +// which in turn means int. On some LP32 platforms, intptr_t is an int, but +// on others, it's a long. When AtomicWord and Atomic32 are based on different +// fundamental types, their pointers are incompatible. +// +// This file defines function overloads to allow both AtomicWord and Atomic32 +// data to be used with this interface. +// +// On LP64 platforms, AtomicWord and Atomic64 are both always long, +// so this problem doesn't occur. + +#if !defined(V8_HOST_ARCH_64_BIT) + +namespace v8 { +namespace base { + +inline AtomicWord Relaxed_CompareAndSwap(volatile AtomicWord* ptr, + AtomicWord old_value, + AtomicWord new_value) { + return Relaxed_CompareAndSwap(reinterpret_cast(ptr), + old_value, new_value); +} + +inline AtomicWord Relaxed_AtomicExchange(volatile AtomicWord* ptr, + AtomicWord new_value) { + return Relaxed_AtomicExchange(reinterpret_cast(ptr), + new_value); +} + +inline AtomicWord Relaxed_AtomicIncrement(volatile AtomicWord* ptr, + AtomicWord increment) { + return Relaxed_AtomicIncrement(reinterpret_cast(ptr), + increment); +} + +inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr, + AtomicWord old_value, + AtomicWord new_value) { + return v8::base::Acquire_CompareAndSwap( + reinterpret_cast(ptr), old_value, new_value); +} + +inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr, + AtomicWord old_value, + AtomicWord new_value) { + return v8::base::Release_CompareAndSwap( + reinterpret_cast(ptr), old_value, new_value); +} + +inline AtomicWord AcquireRelease_CompareAndSwap(volatile AtomicWord* ptr, + AtomicWord old_value, + AtomicWord new_value) { + return v8::base::AcquireRelease_CompareAndSwap( + reinterpret_cast(ptr), old_value, new_value); +} + +inline void Relaxed_Store(volatile AtomicWord* ptr, AtomicWord value) { + Relaxed_Store(reinterpret_cast(ptr), value); +} + +inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) { + return v8::base::Release_Store( + reinterpret_cast(ptr), value); +} + +inline AtomicWord Relaxed_Load(volatile const AtomicWord* ptr) { + return Relaxed_Load(reinterpret_cast(ptr)); +} + +inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) { + return v8::base::Acquire_Load( + reinterpret_cast(ptr)); +} + +} // namespace base +} // namespace v8 + +#endif // !defined(V8_HOST_ARCH_64_BIT) + +#endif // V8_BASE_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_ diff --git a/Source/NativeScript/Inspector/src/base/base-export.h b/Source/NativeScript/Inspector/src/base/base-export.h new file mode 100644 index 0000000..a2b3dac --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/base-export.h @@ -0,0 +1,31 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_BASE_BASE_EXPORT_H_ +#define V8_BASE_BASE_EXPORT_H_ + +#include "include/v8config.h" + +#if V8_OS_WIN + +#ifdef BUILDING_V8_BASE_SHARED +#define V8_BASE_EXPORT __declspec(dllexport) +#elif USING_V8_BASE_SHARED +#define V8_BASE_EXPORT __declspec(dllimport) +#else +#define V8_BASE_EXPORT +#endif // BUILDING_V8_BASE_SHARED + +#else // !V8_OS_WIN + +// Setup for Linux shared library export. +#ifdef BUILDING_V8_BASE_SHARED +#define V8_BASE_EXPORT __attribute__((visibility("default"))) +#else +#define V8_BASE_EXPORT +#endif + +#endif // V8_OS_WIN + +#endif // V8_BASE_BASE_EXPORT_H_ diff --git a/Source/NativeScript/Inspector/src/base/bits.h b/Source/NativeScript/Inspector/src/base/bits.h new file mode 100644 index 0000000..5c31add --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/bits.h @@ -0,0 +1,345 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_BASE_BITS_H_ +#define V8_BASE_BITS_H_ + +#include +#include + +#include "src/base/base-export.h" +#include "src/base/macros.h" +#if V8_CC_MSVC +#include +#endif +#if V8_OS_WIN32 +#include "src/base/win32-headers.h" +#endif + +namespace v8 { +namespace base { +namespace bits { + +// CountPopulation(value) returns the number of bits set in |value|. +template +constexpr inline + typename std::enable_if::value && sizeof(T) <= 8, + unsigned>::type + CountPopulation(T value) { + STATIC_ASSERT(sizeof(T) <= 8); +#if V8_HAS_BUILTIN_POPCOUNT + return sizeof(T) == 8 ? __builtin_popcountll(static_cast(value)) + : __builtin_popcount(static_cast(value)); +#else + // Fall back to divide-and-conquer popcount (see "Hacker's Delight" by Henry + // S. Warren, Jr.), chapter 5-1. + constexpr uint64_t mask[] = {0x5555555555555555, 0x3333333333333333, + 0x0f0f0f0f0f0f0f0f}; + // Start with 64 buckets of 1 bits, holding values from [0,1]. + value = ((value >> 1) & mask[0]) + (value & mask[0]); + // Having 32 buckets of 2 bits, holding values from [0,2] now. + value = ((value >> 2) & mask[1]) + (value & mask[1]); + // Having 16 buckets of 4 bits, holding values from [0,4] now. + value = ((value >> 4) & mask[2]) + (value & mask[2]); + // Having 8 buckets of 8 bits, holding values from [0,8] now. + // From this point on, the buckets are bigger than the number of bits + // required to hold the values, and the buckets are bigger the maximum + // result, so there's no need to mask value anymore, since there's no + // more risk of overflow between buckets. + if (sizeof(T) > 1) value = (value >> (sizeof(T) > 1 ? 8 : 0)) + value; + // Having 4 buckets of 16 bits, holding values from [0,16] now. + if (sizeof(T) > 2) value = (value >> (sizeof(T) > 2 ? 16 : 0)) + value; + // Having 2 buckets of 32 bits, holding values from [0,32] now. + if (sizeof(T) > 4) value = (value >> (sizeof(T) > 4 ? 32 : 0)) + value; + // Having 1 buckets of 64 bits, holding values from [0,64] now. + return static_cast(value & 0xff); +#endif +} + +// ReverseBits(value) returns |value| in reverse bit order. +template +T ReverseBits(T value) { + STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) || + (sizeof(value) == 4) || (sizeof(value) == 8)); + T result = 0; + for (unsigned i = 0; i < (sizeof(value) * 8); i++) { + result = (result << 1) | (value & 1); + value >>= 1; + } + return result; +} + +// CountLeadingZeros(value) returns the number of zero bits following the most +// significant 1 bit in |value| if |value| is non-zero, otherwise it returns +// {sizeof(T) * 8}. +template +inline constexpr + typename std::enable_if::value && sizeof(T) <= 8, + unsigned>::type + CountLeadingZeros(T value) { + static_assert(bits > 0, "invalid instantiation"); +#if V8_HAS_BUILTIN_CLZ + return value == 0 + ? bits + : bits == 64 + ? __builtin_clzll(static_cast(value)) + : __builtin_clz(static_cast(value)) - (32 - bits); +#else + // Binary search algorithm taken from "Hacker's Delight" (by Henry S. Warren, + // Jr.), figures 5-11 and 5-12. + if (bits == 1) return static_cast(value) ^ 1; + T upper_half = value >> (bits / 2); + T next_value = upper_half != 0 ? upper_half : value; + unsigned add = upper_half != 0 ? 0 : bits / 2; + constexpr unsigned next_bits = bits == 1 ? 1 : bits / 2; + return CountLeadingZeros(next_value) + add; +#endif +} + +inline constexpr unsigned CountLeadingZeros32(uint32_t value) { + return CountLeadingZeros(value); +} +inline constexpr unsigned CountLeadingZeros64(uint64_t value) { + return CountLeadingZeros(value); +} + +// CountTrailingZeros(value) returns the number of zero bits preceding the +// least significant 1 bit in |value| if |value| is non-zero, otherwise it +// returns {sizeof(T) * 8}. +// See CountTrailingZerosNonZero for an optimized version for the case that +// |value| is guaranteed to be non-zero. +template +inline constexpr + typename std::enable_if::value && sizeof(T) <= 8, + unsigned>::type + CountTrailingZeros(T value) { +#if V8_HAS_BUILTIN_CTZ + return value == 0 ? bits + : bits == 64 ? __builtin_ctzll(static_cast(value)) + : __builtin_ctz(static_cast(value)); +#else + // Fall back to popcount (see "Hacker's Delight" by Henry S. Warren, Jr.), + // chapter 5-4. On x64, since is faster than counting in a loop and faster + // than doing binary search. + using U = typename std::make_unsigned::type; + U u = value; + return CountPopulation(static_cast(~u & (u - 1u))); +#endif +} + +inline constexpr unsigned CountTrailingZeros32(uint32_t value) { + return CountTrailingZeros(value); +} +inline constexpr unsigned CountTrailingZeros64(uint64_t value) { + return CountTrailingZeros(value); +} + +// CountTrailingZerosNonZero(value) returns the number of zero bits preceding +// the least significant 1 bit in |value| if |value| is non-zero, otherwise the +// behavior is undefined. +// See CountTrailingZeros for an alternative version that allows |value| == 0. +template +inline constexpr + typename std::enable_if::value && sizeof(T) <= 8, + unsigned>::type + CountTrailingZerosNonZero(T value) { + DCHECK_NE(0, value); +#if V8_HAS_BUILTIN_CTZ + return bits == 64 ? __builtin_ctzll(static_cast(value)) + : __builtin_ctz(static_cast(value)); +#else + return CountTrailingZeros(value); +#endif +} + +// Returns true iff |value| is a power of 2. +template ::value || + std::is_enum::value>::type> +constexpr inline bool IsPowerOfTwo(T value) { + return value > 0 && (value & (value - 1)) == 0; +} + +// Identical to {CountTrailingZeros}, but only works for powers of 2. +template ::value>::type> +inline constexpr int WhichPowerOfTwo(T value) { + DCHECK(IsPowerOfTwo(value)); +#if V8_HAS_BUILTIN_CTZ + STATIC_ASSERT(sizeof(T) <= 8); + return sizeof(T) == 8 ? __builtin_ctzll(static_cast(value)) + : __builtin_ctz(static_cast(value)); +#else + // Fall back to popcount (see "Hacker's Delight" by Henry S. Warren, Jr.), + // chapter 5-4. On x64, since is faster than counting in a loop and faster + // than doing binary search. + using U = typename std::make_unsigned::type; + U u = value; + return CountPopulation(static_cast(u - 1)); +#endif +} + +// RoundUpToPowerOfTwo32(value) returns the smallest power of two which is +// greater than or equal to |value|. If you pass in a |value| that is already a +// power of two, it is returned as is. |value| must be less than or equal to +// 0x80000000u. Uses computation based on leading zeros if we have compiler +// support for that. Falls back to the implementation from "Hacker's Delight" by +// Henry S. Warren, Jr., figure 3-3, page 48, where the function is called clp2. +V8_BASE_EXPORT uint32_t RoundUpToPowerOfTwo32(uint32_t value); +// Same for 64 bit integers. |value| must be <= 2^63 +V8_BASE_EXPORT uint64_t RoundUpToPowerOfTwo64(uint64_t value); +// Same for size_t integers. +inline size_t RoundUpToPowerOfTwo(size_t value) { + if (sizeof(size_t) == sizeof(uint64_t)) { + return RoundUpToPowerOfTwo64(value); + } else { + // Without windows.h included this line triggers a truncation warning on + // 64-bit builds. Presumably windows.h disables the relevant warning. + return RoundUpToPowerOfTwo32(static_cast(value)); + } +} + +// RoundDownToPowerOfTwo32(value) returns the greatest power of two which is +// less than or equal to |value|. If you pass in a |value| that is already a +// power of two, it is returned as is. +inline uint32_t RoundDownToPowerOfTwo32(uint32_t value) { + if (value > 0x80000000u) return 0x80000000u; + uint32_t result = RoundUpToPowerOfTwo32(value); + if (result > value) result >>= 1; + return result; +} + + +// Precondition: 0 <= shift < 32 +inline constexpr uint32_t RotateRight32(uint32_t value, uint32_t shift) { + return (value >> shift) | (value << ((32 - shift) & 31)); +} + +// Precondition: 0 <= shift < 32 +inline constexpr uint32_t RotateLeft32(uint32_t value, uint32_t shift) { + return (value << shift) | (value >> ((32 - shift) & 31)); +} + +// Precondition: 0 <= shift < 64 +inline constexpr uint64_t RotateRight64(uint64_t value, uint64_t shift) { + return (value >> shift) | (value << ((64 - shift) & 63)); +} + +// Precondition: 0 <= shift < 64 +inline constexpr uint64_t RotateLeft64(uint64_t value, uint64_t shift) { + return (value << shift) | (value >> ((64 - shift) & 63)); +} + +// SignedAddOverflow32(lhs,rhs,val) performs a signed summation of |lhs| and +// |rhs| and stores the result into the variable pointed to by |val| and +// returns true if the signed summation resulted in an overflow. +inline bool SignedAddOverflow32(int32_t lhs, int32_t rhs, int32_t* val) { +#if V8_HAS_BUILTIN_SADD_OVERFLOW + return __builtin_sadd_overflow(lhs, rhs, val); +#else + uint32_t res = static_cast(lhs) + static_cast(rhs); + *val = bit_cast(res); + return ((res ^ lhs) & (res ^ rhs) & (1U << 31)) != 0; +#endif +} + + +// SignedSubOverflow32(lhs,rhs,val) performs a signed subtraction of |lhs| and +// |rhs| and stores the result into the variable pointed to by |val| and +// returns true if the signed subtraction resulted in an overflow. +inline bool SignedSubOverflow32(int32_t lhs, int32_t rhs, int32_t* val) { +#if V8_HAS_BUILTIN_SSUB_OVERFLOW + return __builtin_ssub_overflow(lhs, rhs, val); +#else + uint32_t res = static_cast(lhs) - static_cast(rhs); + *val = bit_cast(res); + return ((res ^ lhs) & (res ^ ~rhs) & (1U << 31)) != 0; +#endif +} + +// SignedMulOverflow32(lhs,rhs,val) performs a signed multiplication of |lhs| +// and |rhs| and stores the result into the variable pointed to by |val| and +// returns true if the signed multiplication resulted in an overflow. +V8_BASE_EXPORT bool SignedMulOverflow32(int32_t lhs, int32_t rhs, int32_t* val); + +// SignedAddOverflow64(lhs,rhs,val) performs a signed summation of |lhs| and +// |rhs| and stores the result into the variable pointed to by |val| and +// returns true if the signed summation resulted in an overflow. +inline bool SignedAddOverflow64(int64_t lhs, int64_t rhs, int64_t* val) { + uint64_t res = static_cast(lhs) + static_cast(rhs); + *val = bit_cast(res); + return ((res ^ lhs) & (res ^ rhs) & (1ULL << 63)) != 0; +} + + +// SignedSubOverflow64(lhs,rhs,val) performs a signed subtraction of |lhs| and +// |rhs| and stores the result into the variable pointed to by |val| and +// returns true if the signed subtraction resulted in an overflow. +inline bool SignedSubOverflow64(int64_t lhs, int64_t rhs, int64_t* val) { + uint64_t res = static_cast(lhs) - static_cast(rhs); + *val = bit_cast(res); + return ((res ^ lhs) & (res ^ ~rhs) & (1ULL << 63)) != 0; +} + +// SignedMulHigh32(lhs, rhs) multiplies two signed 32-bit values |lhs| and +// |rhs|, extracts the most significant 32 bits of the result, and returns +// those. +V8_BASE_EXPORT int32_t SignedMulHigh32(int32_t lhs, int32_t rhs); + +// SignedMulHighAndAdd32(lhs, rhs, acc) multiplies two signed 32-bit values +// |lhs| and |rhs|, extracts the most significant 32 bits of the result, and +// adds the accumulate value |acc|. +V8_BASE_EXPORT int32_t SignedMulHighAndAdd32(int32_t lhs, int32_t rhs, + int32_t acc); + +// SignedDiv32(lhs, rhs) divides |lhs| by |rhs| and returns the quotient +// truncated to int32. If |rhs| is zero, then zero is returned. If |lhs| +// is minint and |rhs| is -1, it returns minint. +V8_BASE_EXPORT int32_t SignedDiv32(int32_t lhs, int32_t rhs); + +// SignedMod32(lhs, rhs) divides |lhs| by |rhs| and returns the remainder +// truncated to int32. If either |rhs| is zero or |lhs| is minint and |rhs| +// is -1, it returns zero. +V8_BASE_EXPORT int32_t SignedMod32(int32_t lhs, int32_t rhs); + +// UnsignedAddOverflow32(lhs,rhs,val) performs an unsigned summation of |lhs| +// and |rhs| and stores the result into the variable pointed to by |val| and +// returns true if the unsigned summation resulted in an overflow. +inline bool UnsignedAddOverflow32(uint32_t lhs, uint32_t rhs, uint32_t* val) { +#if V8_HAS_BUILTIN_SADD_OVERFLOW + return __builtin_uadd_overflow(lhs, rhs, val); +#else + *val = lhs + rhs; + return *val < (lhs | rhs); +#endif +} + + +// UnsignedDiv32(lhs, rhs) divides |lhs| by |rhs| and returns the quotient +// truncated to uint32. If |rhs| is zero, then zero is returned. +inline uint32_t UnsignedDiv32(uint32_t lhs, uint32_t rhs) { + return rhs ? lhs / rhs : 0u; +} + + +// UnsignedMod32(lhs, rhs) divides |lhs| by |rhs| and returns the remainder +// truncated to uint32. If |rhs| is zero, then zero is returned. +inline uint32_t UnsignedMod32(uint32_t lhs, uint32_t rhs) { + return rhs ? lhs % rhs : 0u; +} + + +// SignedSaturatedAdd64(lhs, rhs) adds |lhs| and |rhs|, +// checks and returns the result. +V8_BASE_EXPORT int64_t SignedSaturatedAdd64(int64_t lhs, int64_t rhs); + +// SignedSaturatedSub64(lhs, rhs) subtracts |lhs| by |rhs|, +// checks and returns the result. +V8_BASE_EXPORT int64_t SignedSaturatedSub64(int64_t lhs, int64_t rhs); + +} // namespace bits +} // namespace base +} // namespace v8 + +#endif // V8_BASE_BITS_H_ diff --git a/Source/NativeScript/Inspector/src/base/build_config.h b/Source/NativeScript/Inspector/src/base/build_config.h new file mode 100644 index 0000000..3303916 --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/build_config.h @@ -0,0 +1,257 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_BASE_BUILD_CONFIG_H_ +#define V8_BASE_BUILD_CONFIG_H_ + +#include "include/v8config.h" + +// Processor architecture detection. For more info on what's defined, see: +// http://msdn.microsoft.com/en-us/library/b0084kay.aspx +// http://www.agner.org/optimize/calling_conventions.pdf +// or with gcc, run: "echo | gcc -E -dM -" +#if defined(_M_X64) || defined(__x86_64__) +#define V8_HOST_ARCH_X64 1 +#if defined(__x86_64__) && __SIZEOF_POINTER__ == 4 // Check for x32. +#define V8_HOST_ARCH_32_BIT 1 +#else +#define V8_HOST_ARCH_64_BIT 1 +#endif +#elif defined(_M_IX86) || defined(__i386__) +#define V8_HOST_ARCH_IA32 1 +#define V8_HOST_ARCH_32_BIT 1 +#elif defined(__AARCH64EL__) || defined(_M_ARM64) +#define V8_HOST_ARCH_ARM64 1 +#define V8_HOST_ARCH_64_BIT 1 +#elif defined(__ARMEL__) +#define V8_HOST_ARCH_ARM 1 +#define V8_HOST_ARCH_32_BIT 1 +#elif defined(__mips64) +#define V8_HOST_ARCH_MIPS64 1 +#define V8_HOST_ARCH_64_BIT 1 +#elif defined(__MIPSEB__) || defined(__MIPSEL__) +#define V8_HOST_ARCH_MIPS 1 +#define V8_HOST_ARCH_32_BIT 1 +#elif defined(__loongarch64) +#define V8_HOST_ARCH_LOONG64 1 +#define V8_HOST_ARCH_64_BIT 1 +#elif defined(__PPC64__) || defined(_ARCH_PPC64) +#define V8_HOST_ARCH_PPC64 1 +#define V8_HOST_ARCH_64_BIT 1 +#elif defined(__PPC__) || defined(_ARCH_PPC) +#define V8_HOST_ARCH_PPC 1 +#define V8_HOST_ARCH_32_BIT 1 +#elif defined(__s390__) || defined(__s390x__) +#define V8_HOST_ARCH_S390 1 +#if defined(__s390x__) +#define V8_HOST_ARCH_64_BIT 1 +#else +#define V8_HOST_ARCH_32_BIT 1 +#endif +#elif defined(__riscv) || defined(__riscv__) +#if __riscv_xlen == 64 +#define V8_HOST_ARCH_RISCV64 1 +#define V8_HOST_ARCH_64_BIT 1 +#else +#error "Cannot detect Riscv's bitwidth" +#endif +#else +#error "Host architecture was not detected as supported by v8" +#endif + +#if defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || \ + defined(__ARM_ARCH_7__) +#define CAN_USE_ARMV7_INSTRUCTIONS 1 +#ifdef __ARM_ARCH_EXT_IDIV__ +#define CAN_USE_SUDIV 1 +#endif +#ifndef CAN_USE_VFP3_INSTRUCTIONS +#define CAN_USE_VFP3_INSTRUCTIONS 1 +#endif +#endif + +#if defined(__ARM_ARCH_8A__) +#define CAN_USE_ARMV7_INSTRUCTIONS 1 +#define CAN_USE_SUDIV 1 +#define CAN_USE_ARMV8_INSTRUCTIONS 1 +#ifndef CAN_USE_VFP3_INSTRUCTIONS +#define CAN_USE_VFP3_INSTRUCTIONS 1 +#endif +#endif + +// Target architecture detection. This may be set externally. If not, detect +// in the same way as the host architecture, that is, target the native +// environment as presented by the compiler. +#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM && \ + !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64 && \ + !V8_TARGET_ARCH_PPC && !V8_TARGET_ARCH_PPC64 && !V8_TARGET_ARCH_S390 && \ + !V8_TARGET_ARCH_RISCV64 && !V8_TARGET_ARCH_LOONG64 +#if defined(_M_X64) || defined(__x86_64__) +#define V8_TARGET_ARCH_X64 1 +#elif defined(_M_IX86) || defined(__i386__) +#define V8_TARGET_ARCH_IA32 1 +#elif defined(__AARCH64EL__) || defined(_M_ARM64) +#define V8_TARGET_ARCH_ARM64 1 +#elif defined(__ARMEL__) +#define V8_TARGET_ARCH_ARM 1 +#elif defined(__mips64) +#define V8_TARGET_ARCH_MIPS64 1 +#elif defined(__MIPSEB__) || defined(__MIPSEL__) +#define V8_TARGET_ARCH_MIPS 1 +#elif defined(_ARCH_PPC64) +#define V8_TARGET_ARCH_PPC64 1 +#elif defined(_ARCH_PPC) +#define V8_TARGET_ARCH_PPC 1 +#elif defined(__riscv) || defined(__riscv__) +#if __riscv_xlen == 64 +#define V8_TARGET_ARCH_RISCV64 1 +#endif +#else +#error Target architecture was not detected as supported by v8 +#endif +#endif + +// Determine architecture pointer size. +#if V8_TARGET_ARCH_IA32 +#define V8_TARGET_ARCH_32_BIT 1 +#elif V8_TARGET_ARCH_X64 +#if !V8_TARGET_ARCH_32_BIT && !V8_TARGET_ARCH_64_BIT +#if defined(__x86_64__) && __SIZEOF_POINTER__ == 4 // Check for x32. +#define V8_TARGET_ARCH_32_BIT 1 +#else +#define V8_TARGET_ARCH_64_BIT 1 +#endif +#endif +#elif V8_TARGET_ARCH_ARM +#define V8_TARGET_ARCH_32_BIT 1 +#elif V8_TARGET_ARCH_ARM64 +#define V8_TARGET_ARCH_64_BIT 1 +#elif V8_TARGET_ARCH_MIPS +#define V8_TARGET_ARCH_32_BIT 1 +#elif V8_TARGET_ARCH_MIPS64 +#define V8_TARGET_ARCH_64_BIT 1 +#elif V8_TARGET_ARCH_LOONG64 +#define V8_TARGET_ARCH_64_BIT 1 +#elif V8_TARGET_ARCH_PPC +#define V8_TARGET_ARCH_32_BIT 1 +#elif V8_TARGET_ARCH_PPC64 +#define V8_TARGET_ARCH_64_BIT 1 +#elif V8_TARGET_ARCH_S390 +#if V8_TARGET_ARCH_S390X +#define V8_TARGET_ARCH_64_BIT 1 +#else +#define V8_TARGET_ARCH_32_BIT 1 +#endif +#elif V8_TARGET_ARCH_RISCV64 +#define V8_TARGET_ARCH_64_BIT 1 +#else +#error Unknown target architecture pointer size +#endif + +// Check for supported combinations of host and target architectures. +#if V8_TARGET_ARCH_IA32 && !V8_HOST_ARCH_IA32 +#error Target architecture ia32 is only supported on ia32 host +#endif +#if (V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_64_BIT && \ + !(V8_HOST_ARCH_X64 && V8_HOST_ARCH_64_BIT)) +#error Target architecture x64 is only supported on x64 host +#endif +#if (V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT && \ + !(V8_HOST_ARCH_X64 && V8_HOST_ARCH_32_BIT)) +#error Target architecture x32 is only supported on x64 host with x32 support +#endif +#if (V8_TARGET_ARCH_ARM && !(V8_HOST_ARCH_IA32 || V8_HOST_ARCH_ARM)) +#error Target architecture arm is only supported on arm and ia32 host +#endif +#if (V8_TARGET_ARCH_ARM64 && !(V8_HOST_ARCH_X64 || V8_HOST_ARCH_ARM64)) +#error Target architecture arm64 is only supported on arm64 and x64 host +#endif +#if (V8_TARGET_ARCH_MIPS && !(V8_HOST_ARCH_IA32 || V8_HOST_ARCH_MIPS)) +#error Target architecture mips is only supported on mips and ia32 host +#endif +#if (V8_TARGET_ARCH_MIPS64 && !(V8_HOST_ARCH_X64 || V8_HOST_ARCH_MIPS64)) +#error Target architecture mips64 is only supported on mips64 and x64 host +#endif +#if (V8_TARGET_ARCH_RISCV64 && !(V8_HOST_ARCH_X64 || V8_HOST_ARCH_RISCV64)) +#error Target architecture riscv64 is only supported on riscv64 and x64 host +#endif +#if (V8_TARGET_ARCH_LOONG64 && !(V8_HOST_ARCH_X64 || V8_HOST_ARCH_LOONG64)) +#error Target architecture loong64 is only supported on loong64 and x64 host +#endif + +// Determine architecture endianness. +#if V8_TARGET_ARCH_IA32 +#define V8_TARGET_LITTLE_ENDIAN 1 +#elif V8_TARGET_ARCH_X64 +#define V8_TARGET_LITTLE_ENDIAN 1 +#elif V8_TARGET_ARCH_ARM +#define V8_TARGET_LITTLE_ENDIAN 1 +#elif V8_TARGET_ARCH_ARM64 +#define V8_TARGET_LITTLE_ENDIAN 1 +#elif V8_TARGET_ARCH_LOONG64 +#define V8_TARGET_LITTLE_ENDIAN 1 +#elif V8_TARGET_ARCH_MIPS +#if defined(__MIPSEB__) +#define V8_TARGET_BIG_ENDIAN 1 +#else +#define V8_TARGET_LITTLE_ENDIAN 1 +#endif +#elif V8_TARGET_ARCH_MIPS64 +#if defined(__MIPSEB__) || defined(V8_TARGET_ARCH_MIPS64_BE) +#define V8_TARGET_BIG_ENDIAN 1 +#else +#define V8_TARGET_LITTLE_ENDIAN 1 +#endif +#elif __BIG_ENDIAN__ // FOR PPCGR on AIX +#define V8_TARGET_BIG_ENDIAN 1 +#elif V8_TARGET_ARCH_PPC_LE +#define V8_TARGET_LITTLE_ENDIAN 1 +#elif V8_TARGET_ARCH_PPC_BE +#define V8_TARGET_BIG_ENDIAN 1 +#elif V8_TARGET_ARCH_S390 +#if V8_TARGET_ARCH_S390_LE_SIM +#define V8_TARGET_LITTLE_ENDIAN 1 +#else +#define V8_TARGET_BIG_ENDIAN 1 +#endif +#elif V8_TARGET_ARCH_RISCV64 +#define V8_TARGET_LITTLE_ENDIAN 1 +#else +#error Unknown target architecture endianness +#endif + +// pthread_jit_write_protect is only available on arm64 Mac. +#if defined(V8_OS_MACOSX) && !defined(V8_OS_IOS) && defined(V8_HOST_ARCH_ARM64) +#define V8_HAS_PTHREAD_JIT_WRITE_PROTECT 1 +#else +#define V8_HAS_PTHREAD_JIT_WRITE_PROTECT 0 +#endif + +#if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_X64) +#define V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK true +#else +#define V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK false +#endif +constexpr int kReturnAddressStackSlotCount = + V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0; + +// Number of bits to represent the page size for paged spaces. +#if defined(V8_TARGET_ARCH_PPC) || defined(V8_TARGET_ARCH_PPC64) +// PPC has large (64KB) physical pages. +const int kPageSizeBits = 19; +#elif defined(ENABLE_HUGEPAGE) +// When enabling huge pages, adjust V8 page size to take up exactly one huge +// page. This avoids huge-page-internal fragmentation for unused address ranges. +const int kHugePageBits = 21; +const int kHugePageSize = (1U) << kHugePageBits; +const int kPageSizeBits = kHugePageBits; +#else +// Arm64 supports up to 64k OS pages on Linux, however 4k pages are more common +// so we keep the V8 page size at 256k. Nonetheless, we need to make sure we +// don't decrease it further in the future due to reserving 3 OS pages for every +// executable V8 page. +const int kPageSizeBits = 18; +#endif + +#endif // V8_BASE_BUILD_CONFIG_H_ diff --git a/Source/NativeScript/Inspector/src/base/compiler-specific.h b/Source/NativeScript/Inspector/src/base/compiler-specific.h new file mode 100644 index 0000000..0c37e56 --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/compiler-specific.h @@ -0,0 +1,138 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_BASE_COMPILER_SPECIFIC_H_ +#define V8_BASE_COMPILER_SPECIFIC_H_ + +#include "include/v8config.h" + +// Annotation to silence compiler warnings about unused +// types/functions/variables. Use like: +// +// using V8_ALLOW_UNUSED Bar = Foo; +// V8_ALLOW_UNUSED void foo() {} +#if V8_HAS_ATTRIBUTE_UNUSED +#define V8_ALLOW_UNUSED __attribute__((unused)) +#else +#define V8_ALLOW_UNUSED +#endif + +// Tell the compiler a function is using a printf-style format string. +// |format_param| is the one-based index of the format string parameter; +// |dots_param| is the one-based index of the "..." parameter. +// For v*printf functions (which take a va_list), pass 0 for dots_param. +// (This is undocumented but matches what the system C headers do.) +#if defined(__GNUC__) +#define PRINTF_FORMAT(format_param, dots_param) \ + __attribute__((format(printf, format_param, dots_param))) +#else +#define PRINTF_FORMAT(format_param, dots_param) +#endif + +// The C++ standard requires that static const members have an out-of-class +// definition (in a single compilation unit), but MSVC chokes on this (when +// language extensions, which are required, are enabled). (You're only likely to +// notice the need for a definition if you take the address of the member or, +// more commonly, pass it to a function that takes it as a reference argument -- +// probably an STL function.) This macro makes MSVC do the right thing. See +// http://msdn.microsoft.com/en-us/library/34h23df8(v=vs.100).aspx for more +// information. Use like: +// +// In .h file: +// struct Foo { +// static const int kBar = 5; +// }; +// +// In .cc file: +// STATIC_CONST_MEMBER_DEFINITION const int Foo::kBar; +#if V8_HAS_DECLSPEC_SELECTANY +#define STATIC_CONST_MEMBER_DEFINITION __declspec(selectany) +#else +#define STATIC_CONST_MEMBER_DEFINITION +#endif + +#if V8_CC_MSVC + +#include + +// Macros for suppressing and disabling warnings on MSVC. +// +// Warning numbers are enumerated at: +// http://msdn.microsoft.com/en-us/library/8x5x43k7(VS.80).aspx +// +// The warning pragma: +// http://msdn.microsoft.com/en-us/library/2c8f766e(VS.80).aspx +// +// Using __pragma instead of #pragma inside macros: +// http://msdn.microsoft.com/en-us/library/d9x1s805.aspx + +// MSVC_SUPPRESS_WARNING disables warning |n| for the remainder of the line and +// for the next line of the source file. +#define MSVC_SUPPRESS_WARNING(n) __pragma(warning(suppress : n)) + +// Allows exporting a class that inherits from a non-exported base class. +// This uses suppress instead of push/pop because the delimiter after the +// declaration (either "," or "{") has to be placed before the pop macro. +// +// Example usage: +// class EXPORT_API Foo : NON_EXPORTED_BASE(public Bar) { +// +// MSVC Compiler warning C4275: +// non dll-interface class 'Bar' used as base for dll-interface class 'Foo'. +// Note that this is intended to be used only when no access to the base class' +// static data is done through derived classes or inline methods. For more info, +// see http://msdn.microsoft.com/en-us/library/3tdb471s(VS.80).aspx +#define NON_EXPORTED_BASE(code) \ + MSVC_SUPPRESS_WARNING(4275) \ + code + +#else // Not MSVC + +#define MSVC_SUPPRESS_WARNING(n) +#define NON_EXPORTED_BASE(code) code + +#endif // V8_CC_MSVC + +// Allowing the use of noexcept by removing the keyword on older compilers that +// do not support adding noexcept to default members. +// Disabled on MSVC because constructors of standard containers are not noexcept +// there. +#if ((!defined(V8_CC_GNU) && !defined(V8_CC_MSVC) && \ + !defined(V8_TARGET_ARCH_MIPS) && !defined(V8_TARGET_ARCH_MIPS64) && \ + !defined(V8_TARGET_ARCH_PPC) && !defined(V8_TARGET_ARCH_PPC64) && \ + !defined(V8_TARGET_ARCH_RISCV64)) || \ + (defined(__clang__) && __cplusplus > 201300L)) +#define V8_NOEXCEPT noexcept +#else +#define V8_NOEXCEPT +#endif + +// Specify memory alignment for structs, classes, etc. +// Use like: +// class ALIGNAS(16) MyClass { ... } +// ALIGNAS(16) int array[4]; +// +// In most places you can use the C++11 keyword "alignas", which is preferred. +// +// But compilers have trouble mixing __attribute__((...)) syntax with +// alignas(...) syntax. +// +// Doesn't work in clang or gcc: +// struct alignas(16) __attribute__((packed)) S { char c; }; +// Works in clang but not gcc: +// struct __attribute__((packed)) alignas(16) S2 { char c; }; +// Works in clang and gcc: +// struct alignas(16) S3 { char c; } __attribute__((packed)); +// +// There are also some attributes that must be specified *before* a class +// definition: visibility (used for exporting functions/classes) is one of +// these attributes. This means that it is not possible to use alignas() with a +// class that is marked as exported. +#if defined(V8_CC_MSVC) +#define ALIGNAS(byte_alignment) __declspec(align(byte_alignment)) +#else +#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment))) +#endif + +#endif // V8_BASE_COMPILER_SPECIFIC_H_ diff --git a/Source/NativeScript/Inspector/src/base/enum-set.h b/Source/NativeScript/Inspector/src/base/enum-set.h new file mode 100644 index 0000000..ce49b39 --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/enum-set.h @@ -0,0 +1,92 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_BASE_ENUM_SET_H_ +#define V8_BASE_ENUM_SET_H_ + +#include + +#include "src/base/logging.h" + +namespace v8 { +namespace base { + +// A poor man's version of STL's bitset: A bit set of enums E (without explicit +// values), fitting into an integral type T. +template +class EnumSet { + static_assert(std::is_enum::value, "EnumSet can only be used with enums"); + + public: + constexpr EnumSet() = default; + + explicit constexpr EnumSet(std::initializer_list init) { + T bits = 0; + for (E e : init) bits |= Mask(e); + bits_ = bits; + } + + constexpr bool empty() const { return bits_ == 0; } + constexpr bool contains(E element) const { + return (bits_ & Mask(element)) != 0; + } + constexpr bool contains_any(EnumSet set) const { + return (bits_ & set.bits_) != 0; + } + void Add(E element) { bits_ |= Mask(element); } + void Add(EnumSet set) { bits_ |= set.bits_; } + void Remove(E element) { bits_ &= ~Mask(element); } + void Remove(EnumSet set) { bits_ &= ~set.bits_; } + void RemoveAll() { bits_ = 0; } + void Intersect(EnumSet set) { bits_ &= set.bits_; } + constexpr T ToIntegral() const { return bits_; } + + constexpr bool operator==(EnumSet set) const { return bits_ == set.bits_; } + constexpr bool operator!=(EnumSet set) const { return bits_ != set.bits_; } + + constexpr EnumSet operator|(EnumSet set) const { + return EnumSet(bits_ | set.bits_); + } + constexpr EnumSet operator&(EnumSet set) const { + return EnumSet(bits_ & set.bits_); + } + constexpr EnumSet operator-(EnumSet set) const { + return EnumSet(bits_ & ~set.bits_); + } + + EnumSet& operator|=(EnumSet set) { return *this = *this | set; } + EnumSet& operator&=(EnumSet set) { return *this = *this & set; } + EnumSet& operator-=(EnumSet set) { return *this = *this - set; } + + constexpr EnumSet operator|(E element) const { + return EnumSet(bits_ | Mask(element)); + } + constexpr EnumSet operator&(E element) const { + return EnumSet(bits_ & Mask(element)); + } + constexpr EnumSet operator-(E element) const { + return EnumSet(bits_ & ~Mask(element)); + } + + EnumSet& operator|=(E element) { return *this = *this | element; } + EnumSet& operator&=(E element) { return *this = *this & element; } + EnumSet& operator-=(E element) { return *this = *this - element; } + + static constexpr EnumSet FromIntegral(T bits) { return EnumSet{bits}; } + + private: + explicit constexpr EnumSet(T bits) : bits_(bits) {} + + static constexpr T Mask(E element) { + DCHECK_GT(sizeof(T) * 8, static_cast(element)); + return T{1} << static_cast::type>(element); + } + + T bits_ = 0; +}; + +} // namespace base +} // namespace v8 + +#endif // V8_BASE_ENUM_SET_H_ diff --git a/Source/NativeScript/Inspector/src/base/export-template.h b/Source/NativeScript/Inspector/src/base/export-template.h new file mode 100644 index 0000000..861cfe4 --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/export-template.h @@ -0,0 +1,163 @@ +// Copyright 2017 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_BASE_EXPORT_TEMPLATE_H_ +#define V8_BASE_EXPORT_TEMPLATE_H_ + +// Synopsis +// +// This header provides macros for using FOO_EXPORT macros with explicit +// template instantiation declarations and definitions. +// Generally, the FOO_EXPORT macros are used at declarations, +// and GCC requires them to be used at explicit instantiation declarations, +// but MSVC requires __declspec(dllexport) to be used at the explicit +// instantiation definitions instead. + +// Usage +// +// In a header file, write: +// +// extern template class EXPORT_TEMPLATE_DECLARE(FOO_EXPORT) foo; +// +// In a source file, write: +// +// template class EXPORT_TEMPLATE_DEFINE(FOO_EXPORT) foo; + +// Implementation notes +// +// The implementation of this header uses some subtle macro semantics to +// detect what the provided FOO_EXPORT value was defined as and then +// to dispatch to appropriate macro definitions. Unfortunately, +// MSVC's C preprocessor is rather non-compliant and requires special +// care to make it work. +// +// Issue 1. +// +// #define F(x) +// F() +// +// MSVC emits warning C4003 ("not enough actual parameters for macro +// 'F'), even though it's a valid macro invocation. This affects the +// macros below that take just an "export" parameter, because export +// may be empty. +// +// As a workaround, we can add a dummy parameter and arguments: +// +// #define F(x,_) +// F(,) +// +// Issue 2. +// +// #define F(x) G##x +// #define Gj() ok +// F(j()) +// +// The correct replacement for "F(j())" is "ok", but MSVC replaces it +// with "Gj()". As a workaround, we can pass the result to an +// identity macro to force MSVC to look for replacements again. (This +// is why EXPORT_TEMPLATE_STYLE_3 exists.) + +#define EXPORT_TEMPLATE_DECLARE(export) \ + EXPORT_TEMPLATE_INVOKE(DECLARE, EXPORT_TEMPLATE_STYLE(export, ), export) +#define EXPORT_TEMPLATE_DEFINE(export) \ + EXPORT_TEMPLATE_INVOKE(DEFINE, EXPORT_TEMPLATE_STYLE(export, ), export) + +// INVOKE is an internal helper macro to perform parameter replacements +// and token pasting to chain invoke another macro. E.g., +// EXPORT_TEMPLATE_INVOKE(DECLARE, DEFAULT, FOO_EXPORT) +// will export to call +// EXPORT_TEMPLATE_DECLARE_DEFAULT(FOO_EXPORT, ) +// (but with FOO_EXPORT expanded too). +#define EXPORT_TEMPLATE_INVOKE(which, style, export) \ + EXPORT_TEMPLATE_INVOKE_2(which, style, export) +#define EXPORT_TEMPLATE_INVOKE_2(which, style, export) \ + EXPORT_TEMPLATE_##which##_##style(export, ) + +// Default style is to apply the FOO_EXPORT macro at declaration sites. +#define EXPORT_TEMPLATE_DECLARE_DEFAULT(export, _) export +#define EXPORT_TEMPLATE_DEFINE_DEFAULT(export, _) + +// The "MSVC hack" style is used when FOO_EXPORT is defined +// as __declspec(dllexport), which MSVC requires to be used at +// definition sites instead. +#define EXPORT_TEMPLATE_DECLARE_MSVC_HACK(export, _) +#define EXPORT_TEMPLATE_DEFINE_MSVC_HACK(export, _) export + +// EXPORT_TEMPLATE_STYLE is an internal helper macro that identifies which +// export style needs to be used for the provided FOO_EXPORT macro definition. +// "", "__attribute__(...)", and "__declspec(dllimport)" are mapped +// to "DEFAULT"; while "__declspec(dllexport)" is mapped to "MSVC_HACK". +// +// It's implemented with token pasting to transform the __attribute__ and +// __declspec annotations into macro invocations. E.g., if FOO_EXPORT is +// defined as "__declspec(dllimport)", it undergoes the following sequence of +// macro substitutions: +// EXPORT_TEMPLATE_STYLE(FOO_EXPORT, ) +// EXPORT_TEMPLATE_STYLE_2(__declspec(dllimport), ) +// EXPORT_TEMPLATE_STYLE_3(EXPORT_TEMPLATE_STYLE_MATCH__declspec(dllimport)) +// EXPORT_TEMPLATE_STYLE_MATCH__declspec(dllimport) +// EXPORT_TEMPLATE_STYLE_MATCH_DECLSPEC_dllimport +// DEFAULT +#define EXPORT_TEMPLATE_STYLE(export, _) EXPORT_TEMPLATE_STYLE_2(export, ) +#define EXPORT_TEMPLATE_STYLE_2(export, _) \ + EXPORT_TEMPLATE_STYLE_3( \ + EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA##export) +#define EXPORT_TEMPLATE_STYLE_3(style) style + +// Internal helper macros for EXPORT_TEMPLATE_STYLE. +// +// XXX: C++ reserves all identifiers containing "__" for the implementation, +// but "__attribute__" and "__declspec" already contain "__" and the token-paste +// operator can only add characters; not remove them. To minimize the risk of +// conflict with implementations, we include "foj3FJo5StF0OvIzl7oMxA" (a random +// 128-bit string, encoded in Base64) in the macro name. +#define EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA DEFAULT +#define EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA__attribute__(...) \ + DEFAULT +#define EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA__declspec(arg) \ + EXPORT_TEMPLATE_STYLE_MATCH_DECLSPEC_##arg + +// Internal helper macros for EXPORT_TEMPLATE_STYLE. +#define EXPORT_TEMPLATE_STYLE_MATCH_DECLSPEC_dllexport MSVC_HACK +#define EXPORT_TEMPLATE_STYLE_MATCH_DECLSPEC_dllimport DEFAULT + +// Sanity checks. +// +// EXPORT_TEMPLATE_TEST uses the same macro invocation pattern as +// EXPORT_TEMPLATE_DECLARE and EXPORT_TEMPLATE_DEFINE do to check that they're +// working correctly. When they're working correctly, the sequence of macro +// replacements should go something like: +// +// EXPORT_TEMPLATE_TEST(DEFAULT, __declspec(dllimport)); +// +// static_assert(EXPORT_TEMPLATE_INVOKE(TEST_DEFAULT, +// EXPORT_TEMPLATE_STYLE(__declspec(dllimport), ), +// __declspec(dllimport)), "__declspec(dllimport)"); +// +// static_assert(EXPORT_TEMPLATE_INVOKE(TEST_DEFAULT, +// DEFAULT, __declspec(dllimport)), "__declspec(dllimport)"); +// +// static_assert(EXPORT_TEMPLATE_TEST_DEFAULT_DEFAULT( +// __declspec(dllimport)), "__declspec(dllimport)"); +// +// static_assert(true, "__declspec(dllimport)"); +// +// When they're not working correctly, a syntax error should occur instead. +#define EXPORT_TEMPLATE_TEST(want, export) \ + static_assert(EXPORT_TEMPLATE_INVOKE( \ + TEST_##want, EXPORT_TEMPLATE_STYLE(export, ), export), \ + #export) +#define EXPORT_TEMPLATE_TEST_DEFAULT_DEFAULT(...) true +#define EXPORT_TEMPLATE_TEST_MSVC_HACK_MSVC_HACK(...) true + +EXPORT_TEMPLATE_TEST(DEFAULT, ); +EXPORT_TEMPLATE_TEST(DEFAULT, __attribute__((visibility("default")))); +EXPORT_TEMPLATE_TEST(MSVC_HACK, __declspec(dllexport)); +EXPORT_TEMPLATE_TEST(DEFAULT, __declspec(dllimport)); + +#undef EXPORT_TEMPLATE_TEST +#undef EXPORT_TEMPLATE_TEST_DEFAULT_DEFAULT +#undef EXPORT_TEMPLATE_TEST_MSVC_HACK_MSVC_HACK + +#endif // V8_BASE_EXPORT_TEMPLATE_H_ diff --git a/Source/NativeScript/Inspector/src/base/flags.h b/Source/NativeScript/Inspector/src/base/flags.h new file mode 100644 index 0000000..2a36ca7 --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/flags.h @@ -0,0 +1,130 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_BASE_FLAGS_H_ +#define V8_BASE_FLAGS_H_ + +#include + +#include "src/base/compiler-specific.h" + +namespace v8 { +namespace base { + +// The Flags class provides a type-safe way of storing OR-combinations of enum +// values. The Flags class is a template class, where T is an enum type, +// and S is the underlying storage type (usually int). +// +// The traditional C++ approach for storing OR-combinations of enum values is to +// use an int or unsigned int variable. The inconvenience with this approach is +// that there's no type checking at all; any enum value can be OR'd with any +// other enum value and passed on to a function that takes an int or unsigned +// int. +template +class Flags final { + public: + using flag_type = T; + using mask_type = S; + + constexpr Flags() : mask_(0) {} + constexpr Flags(flag_type flag) // NOLINT(runtime/explicit) + : mask_(static_cast(flag)) {} + constexpr explicit Flags(mask_type mask) : mask_(static_cast(mask)) {} + + constexpr bool operator==(flag_type flag) const { + return mask_ == static_cast(flag); + } + constexpr bool operator!=(flag_type flag) const { + return mask_ != static_cast(flag); + } + + Flags& operator&=(const Flags& flags) { + mask_ &= flags.mask_; + return *this; + } + Flags& operator|=(const Flags& flags) { + mask_ |= flags.mask_; + return *this; + } + Flags& operator^=(const Flags& flags) { + mask_ ^= flags.mask_; + return *this; + } + + constexpr Flags operator&(const Flags& flags) const { + return Flags(mask_ & flags.mask_); + } + constexpr Flags operator|(const Flags& flags) const { + return Flags(mask_ | flags.mask_); + } + constexpr Flags operator^(const Flags& flags) const { + return Flags(mask_ ^ flags.mask_); + } + + Flags& operator&=(flag_type flag) { return operator&=(Flags(flag)); } + Flags& operator|=(flag_type flag) { return operator|=(Flags(flag)); } + Flags& operator^=(flag_type flag) { return operator^=(Flags(flag)); } + + constexpr Flags operator&(flag_type flag) const { + return operator&(Flags(flag)); + } + constexpr Flags operator|(flag_type flag) const { + return operator|(Flags(flag)); + } + constexpr Flags operator^(flag_type flag) const { + return operator^(Flags(flag)); + } + + constexpr Flags operator~() const { return Flags(~mask_); } + + constexpr operator mask_type() const { return mask_; } + constexpr bool operator!() const { return !mask_; } + + Flags without(flag_type flag) const { return *this & (~Flags(flag)); } + + friend size_t hash_value(const Flags& flags) { return flags.mask_; } + + private: + mask_type mask_; +}; + +#define DEFINE_OPERATORS_FOR_FLAGS(Type) \ + V8_ALLOW_UNUSED V8_WARN_UNUSED_RESULT inline constexpr Type operator&( \ + Type::flag_type lhs, Type::flag_type rhs) { \ + return Type(lhs) & rhs; \ + } \ + V8_ALLOW_UNUSED V8_WARN_UNUSED_RESULT inline constexpr Type operator&( \ + Type::flag_type lhs, const Type& rhs) { \ + return rhs & lhs; \ + } \ + V8_ALLOW_UNUSED inline void operator&(Type::flag_type lhs, \ + Type::mask_type rhs) {} \ + V8_ALLOW_UNUSED V8_WARN_UNUSED_RESULT inline constexpr Type operator|( \ + Type::flag_type lhs, Type::flag_type rhs) { \ + return Type(lhs) | rhs; \ + } \ + V8_ALLOW_UNUSED V8_WARN_UNUSED_RESULT inline constexpr Type operator|( \ + Type::flag_type lhs, const Type& rhs) { \ + return rhs | lhs; \ + } \ + V8_ALLOW_UNUSED inline void operator|(Type::flag_type lhs, \ + Type::mask_type rhs) {} \ + V8_ALLOW_UNUSED V8_WARN_UNUSED_RESULT inline constexpr Type operator^( \ + Type::flag_type lhs, Type::flag_type rhs) { \ + return Type(lhs) ^ rhs; \ + } \ + V8_ALLOW_UNUSED V8_WARN_UNUSED_RESULT inline constexpr Type operator^( \ + Type::flag_type lhs, const Type& rhs) { \ + return rhs ^ lhs; \ + } \ + V8_ALLOW_UNUSED inline void operator^(Type::flag_type lhs, \ + Type::mask_type rhs) {} \ + V8_ALLOW_UNUSED inline constexpr Type operator~(Type::flag_type val) { \ + return ~Type(val); \ + } + +} // namespace base +} // namespace v8 + +#endif // V8_BASE_FLAGS_H_ diff --git a/Source/NativeScript/Inspector/src/base/immediate-crash.h b/Source/NativeScript/Inspector/src/base/immediate-crash.h new file mode 100644 index 0000000..ef1f922 --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/immediate-crash.h @@ -0,0 +1,162 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_BASE_IMMEDIATE_CRASH_H_ +#define V8_BASE_IMMEDIATE_CRASH_H_ + +#include "include/v8config.h" +#include "src/base/build_config.h" + +// Crashes in the fastest possible way with no attempt at logging. +// There are several constraints; see http://crbug.com/664209 for more context. +// +// - TRAP_SEQUENCE_() must be fatal. It should not be possible to ignore the +// resulting exception or simply hit 'continue' to skip over it in a debugger. +// - Different instances of TRAP_SEQUENCE_() must not be folded together, to +// ensure crash reports are debuggable. Unlike __builtin_trap(), asm volatile +// blocks will not be folded together. +// Note: TRAP_SEQUENCE_() previously required an instruction with a unique +// nonce since unlike clang, GCC folds together identical asm volatile +// blocks. +// - TRAP_SEQUENCE_() must produce a signal that is distinct from an invalid +// memory access. +// - TRAP_SEQUENCE_() must be treated as a set of noreturn instructions. +// __builtin_unreachable() is used to provide that hint here. clang also uses +// this as a heuristic to pack the instructions in the function epilogue to +// improve code density. +// +// Additional properties that are nice to have: +// - TRAP_SEQUENCE_() should be as compact as possible. +// - The first instruction of TRAP_SEQUENCE_() should not change, to avoid +// shifting crash reporting clusters. As a consequence of this, explicit +// assembly is preferred over intrinsics. +// Note: this last bullet point may no longer be true, and may be removed in +// the future. + +// Note: TRAP_SEQUENCE Is currently split into two macro helpers due to the fact +// that clang emits an actual instruction for __builtin_unreachable() on certain +// platforms (see https://crbug.com/958675). In addition, the int3/bkpt/brk will +// be removed in followups, so splitting it up like this now makes it easy to +// land the followups. + +#if V8_CC_GNU + +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 + +// TODO(https://crbug.com/958675): In theory, it should be possible to use just +// int3. However, there are a number of crashes with SIGILL as the exception +// code, so it seems likely that there's a signal handler that allows execution +// to continue after SIGTRAP. +#define TRAP_SEQUENCE1_() asm volatile("int3") + +#if V8_OS_MACOSX +// Intentionally empty: __builtin_unreachable() is always part of the sequence +// (see IMMEDIATE_CRASH below) and already emits a ud2 on Mac. +#define TRAP_SEQUENCE2_() asm volatile("") +#else +#define TRAP_SEQUENCE2_() asm volatile("ud2") +#endif // V8_OS_MACOSX + +#elif V8_HOST_ARCH_ARM + +// bkpt will generate a SIGBUS when running on armv7 and a SIGTRAP when running +// as a 32 bit userspace app on arm64. There doesn't seem to be any way to +// cause a SIGTRAP from userspace without using a syscall (which would be a +// problem for sandboxing). +// TODO(https://crbug.com/958675): Remove bkpt from this sequence. +#define TRAP_SEQUENCE1_() asm volatile("bkpt #0") +#define TRAP_SEQUENCE2_() asm volatile("udf #0") + +#elif V8_HOST_ARCH_ARM64 + +// This will always generate a SIGTRAP on arm64. +// TODO(https://crbug.com/958675): Remove brk from this sequence. +#define TRAP_SEQUENCE1_() asm volatile("brk #0") +#define TRAP_SEQUENCE2_() asm volatile("hlt #0") + +#else + +// Crash report accuracy will not be guaranteed on other architectures, but at +// least this will crash as expected. +#define TRAP_SEQUENCE1_() __builtin_trap() +#define TRAP_SEQUENCE2_() asm volatile("") + +#endif // V8_HOST_ARCH_* + +#elif V8_CC_MSVC + +#if !defined(__clang__) + +// MSVC x64 doesn't support inline asm, so use the MSVC intrinsic. +#define TRAP_SEQUENCE1_() __debugbreak() +#define TRAP_SEQUENCE2_() + +#elif V8_HOST_ARCH_ARM64 + +// Windows ARM64 uses "BRK #F000" as its breakpoint instruction, and +// __debugbreak() generates that in both VC++ and clang. +#define TRAP_SEQUENCE1_() __debugbreak() +// Intentionally empty: __builtin_unreachable() is always part of the sequence +// (see IMMEDIATE_CRASH below) and already emits a ud2 on Win64, +// https://crbug.com/958373 +#define TRAP_SEQUENCE2_() __asm volatile("") + +#else + +#define TRAP_SEQUENCE1_() asm volatile("int3") +#define TRAP_SEQUENCE2_() asm volatile("ud2") + +#endif // __clang__ + +#else + +#error No supported trap sequence! + +#endif // V8_CC_GNU + +#define TRAP_SEQUENCE_() \ + do { \ + TRAP_SEQUENCE1_(); \ + TRAP_SEQUENCE2_(); \ + } while (false) + +// CHECK() and the trap sequence can be invoked from a constexpr function. +// This could make compilation fail on GCC, as it forbids directly using inline +// asm inside a constexpr function. However, it allows calling a lambda +// expression including the same asm. +// The side effect is that the top of the stacktrace will not point to the +// calling function, but to this anonymous lambda. This is still useful as the +// full name of the lambda will typically include the name of the function that +// calls CHECK() and the debugger will still break at the right line of code. +#if !V8_CC_GNU + +#define WRAPPED_TRAP_SEQUENCE_() TRAP_SEQUENCE_() + +#else + +#define WRAPPED_TRAP_SEQUENCE_() \ + do { \ + [] { TRAP_SEQUENCE_(); }(); \ + } while (false) + +#endif // !V8_CC_GCC + +#if defined(__clang__) || V8_CC_GCC + +// __builtin_unreachable() hints to the compiler that this is noreturn and can +// be packed in the function epilogue. +#define IMMEDIATE_CRASH() \ + ({ \ + WRAPPED_TRAP_SEQUENCE_(); \ + __builtin_unreachable(); \ + }) + +#else + +// This is supporting build with MSVC where there is no __builtin_unreachable(). +#define IMMEDIATE_CRASH() WRAPPED_TRAP_SEQUENCE_() + +#endif // defined(__clang__) || defined(COMPILER_GCC) + +#endif // V8_BASE_IMMEDIATE_CRASH_H_ diff --git a/Source/NativeScript/Inspector/src/base/lazy-instance.h b/Source/NativeScript/Inspector/src/base/lazy-instance.h new file mode 100644 index 0000000..75e5b06 --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/lazy-instance.h @@ -0,0 +1,258 @@ +// Copyright 2012 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The LazyInstance class manages a single instance of Type, +// which will be lazily created on the first time it's accessed. This class is +// useful for places you would normally use a function-level static, but you +// need to have guaranteed thread-safety. The Type constructor will only ever +// be called once, even if two threads are racing to create the object. Get() +// and Pointer() will always return the same, completely initialized instance. +// +// LazyInstance is completely thread safe, assuming that you create it safely. +// The class was designed to be POD initialized, so it shouldn't require a +// static constructor. It really only makes sense to declare a LazyInstance as +// a global variable using the LAZY_INSTANCE_INITIALIZER initializer. +// +// LazyInstance is similar to Singleton, except it does not have the singleton +// property. You can have multiple LazyInstance's of the same type, and each +// will manage a unique instance. It also preallocates the space for Type, as +// to avoid allocating the Type instance on the heap. This may help with the +// performance of creating the instance, and reducing heap fragmentation. This +// requires that Type be a complete type so we can determine the size. See +// notes for advanced users below for more explanations. +// +// Example usage: +// static LazyInstance::type my_instance = LAZY_INSTANCE_INITIALIZER; +// void SomeMethod() { +// my_instance.Get().SomeMethod(); // MyClass::SomeMethod() +// +// MyClass* ptr = my_instance.Pointer(); +// ptr->DoDoDo(); // MyClass::DoDoDo +// } +// +// Additionally you can override the way your instance is constructed by +// providing your own trait: +// Example usage: +// struct MyCreateTrait { +// static void Construct(void* allocated_ptr) { +// new (allocated_ptr) MyClass(/* extra parameters... */); +// } +// }; +// static LazyInstance::type my_instance = +// LAZY_INSTANCE_INITIALIZER; +// +// WARNINGS: +// - This implementation of LazyInstance IS THREAD-SAFE by default. See +// SingleThreadInitOnceTrait if you don't care about thread safety. +// - Lazy initialization comes with a cost. Make sure that you don't use it on +// critical path. Consider adding your initialization code to a function +// which is explicitly called once. +// +// Notes for advanced users: +// LazyInstance can actually be used in two different ways: +// +// - "Static mode" which is the default mode since it is the most efficient +// (no extra heap allocation). In this mode, the instance is statically +// allocated (stored in the global data section at compile time). +// The macro LAZY_STATIC_INSTANCE_INITIALIZER (= LAZY_INSTANCE_INITIALIZER) +// must be used to initialize static lazy instances. +// +// - "Dynamic mode". In this mode, the instance is dynamically allocated and +// constructed (using new) by default. This mode is useful if you have to +// deal with some code already allocating the instance for you (e.g. +// OS::Mutex() which returns a new private OS-dependent subclass of Mutex). +// The macro LAZY_DYNAMIC_INSTANCE_INITIALIZER must be used to initialize +// dynamic lazy instances. + +#ifndef V8_BASE_LAZY_INSTANCE_H_ +#define V8_BASE_LAZY_INSTANCE_H_ + +#include + +#include "src/base/macros.h" +#include "src/base/once.h" + +namespace v8 { +namespace base { + +#define LAZY_STATIC_INSTANCE_INITIALIZER { V8_ONCE_INIT, { {} } } +#define LAZY_DYNAMIC_INSTANCE_INITIALIZER { V8_ONCE_INIT, 0 } + +// Default to static mode. +#define LAZY_INSTANCE_INITIALIZER LAZY_STATIC_INSTANCE_INITIALIZER + + +template +struct LeakyInstanceTrait { + static void Destroy(T* /* instance */) {} +}; + + +// Traits that define how an instance is allocated and accessed. + + +template +struct StaticallyAllocatedInstanceTrait { + using StorageType = + typename std::aligned_storage::type; + + static T* MutableInstance(StorageType* storage) { + return reinterpret_cast(storage); + } + + template + static void InitStorageUsingTrait(StorageType* storage) { + ConstructTrait::Construct(storage); + } +}; + + +template +struct DynamicallyAllocatedInstanceTrait { + using StorageType = T*; + + static T* MutableInstance(StorageType* storage) { + return *storage; + } + + template + static void InitStorageUsingTrait(StorageType* storage) { + *storage = CreateTrait::Create(); + } +}; + + +template +struct DefaultConstructTrait { + // Constructs the provided object which was already allocated. + static void Construct(void* allocated_ptr) { new (allocated_ptr) T(); } +}; + + +template +struct DefaultCreateTrait { + static T* Create() { + return new T(); + } +}; + + +struct ThreadSafeInitOnceTrait { + template + static void Init(OnceType* once, Function function, Storage storage) { + CallOnce(once, function, storage); + } +}; + + +// Initialization trait for users who don't care about thread-safety. +struct SingleThreadInitOnceTrait { + template + static void Init(OnceType* once, Function function, Storage storage) { + if (*once == ONCE_STATE_UNINITIALIZED) { + function(storage); + *once = ONCE_STATE_DONE; + } + } +}; + + +// TODO(pliard): Handle instances destruction (using global destructors). +template +struct LazyInstanceImpl { + public: + using StorageType = typename AllocationTrait::StorageType; + + private: + static void InitInstance(void* storage) { + AllocationTrait::template InitStorageUsingTrait( + static_cast(storage)); + } + + void Init() const { + InitOnceTrait::Init(&once_, &InitInstance, static_cast(&storage_)); + } + + public: + T* Pointer() { + Init(); + return AllocationTrait::MutableInstance(&storage_); + } + + const T& Get() const { + Init(); + return *AllocationTrait::MutableInstance(&storage_); + } + + mutable OnceType once_; + // Note that the previous field, OnceType, is an AtomicWord which guarantees + // 4-byte alignment of the storage field below. If compiling with GCC (>4.2), + // the LAZY_ALIGN macro above will guarantee correctness for any alignment. + mutable StorageType storage_; +}; + + +template , + typename InitOnceTrait = ThreadSafeInitOnceTrait, + typename DestroyTrait = LeakyInstanceTrait > +struct LazyStaticInstance { + using type = LazyInstanceImpl, + CreateTrait, InitOnceTrait, DestroyTrait>; +}; + + +template , + typename InitOnceTrait = ThreadSafeInitOnceTrait, + typename DestroyTrait = LeakyInstanceTrait > +struct LazyInstance { + // A LazyInstance is a LazyStaticInstance. + using type = typename LazyStaticInstance::type; +}; + + +template , + typename InitOnceTrait = ThreadSafeInitOnceTrait, + typename DestroyTrait = LeakyInstanceTrait > +struct LazyDynamicInstance { + using type = LazyInstanceImpl, + CreateTrait, InitOnceTrait, DestroyTrait>; +}; + +// LeakyObject wraps an object of type T, which is initialized in the +// constructor but never destructed. Thus LeakyObject is trivially +// destructible and can be used in static (lazily initialized) variables. +template +class LeakyObject { + public: + template + explicit LeakyObject(Args&&... args) { + new (&storage_) T(std::forward(args)...); + } + + LeakyObject(const LeakyObject&) = delete; + LeakyObject& operator=(const LeakyObject&) = delete; + + T* get() { return reinterpret_cast(&storage_); } + + private: + typename std::aligned_storage::type storage_; +}; + +// Define a function which returns a pointer to a lazily initialized and never +// destructed object of type T. +#define DEFINE_LAZY_LEAKY_OBJECT_GETTER(T, FunctionName, ...) \ + T* FunctionName() { \ + static ::v8::base::LeakyObject object{__VA_ARGS__}; \ + return object.get(); \ + } + +} // namespace base +} // namespace v8 + +#endif // V8_BASE_LAZY_INSTANCE_H_ diff --git a/Source/NativeScript/Inspector/src/base/logging.h b/Source/NativeScript/Inspector/src/base/logging.h new file mode 100644 index 0000000..08db24a --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/logging.h @@ -0,0 +1,417 @@ +// Copyright 2012 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_BASE_LOGGING_H_ +#define V8_BASE_LOGGING_H_ + +#include +#include +#include + +#include "src/base/base-export.h" +#include "src/base/build_config.h" +#include "src/base/compiler-specific.h" +#include "src/base/immediate-crash.h" +#include "src/base/template-utils.h" + +V8_BASE_EXPORT V8_NOINLINE void V8_Dcheck(const char* file, int line, + const char* message); + +#ifdef DEBUG +// In debug, include file, line, and full error message for all +// FATAL() calls. +[[noreturn]] PRINTF_FORMAT(3, 4) V8_BASE_EXPORT V8_NOINLINE + void V8_Fatal(const char* file, int line, const char* format, ...); +#define FATAL(...) V8_Fatal(__FILE__, __LINE__, __VA_ARGS__) + +#else +[[noreturn]] PRINTF_FORMAT(1, 2) V8_BASE_EXPORT V8_NOINLINE + void V8_Fatal(const char* format, ...); +#if !defined(OFFICIAL_BUILD) +// In non-official release, include full error message, but drop file & line +// numbers. It saves binary size to drop the |file| & |line| as opposed to just +// passing in "", 0 for them. +#define FATAL(...) V8_Fatal(__VA_ARGS__) +#else +// FATAL(msg) -> IMMEDIATE_CRASH() +// FATAL(msg, ...) -> V8_Fatal(msg, ...) +#define FATAL_HELPER(_7, _6, _5, _4, _3, _2, _1, _0, ...) _0 +#define FATAL_DISCARD_ARG(arg) IMMEDIATE_CRASH() +#define FATAL(...) \ + FATAL_HELPER(__VA_ARGS__, V8_Fatal, V8_Fatal, V8_Fatal, V8_Fatal, V8_Fatal, \ + V8_Fatal, FATAL_DISCARD_ARG) \ + (__VA_ARGS__) +#endif // !defined(OFFICIAL_BUILD) +#endif // DEBUG + +#define UNIMPLEMENTED() FATAL("unimplemented code") +#define UNREACHABLE() FATAL("unreachable code") + +namespace v8 { +namespace base { + +class CheckMessageStream : public std::ostringstream {}; + +// Overwrite the default function that prints a stack trace. +V8_BASE_EXPORT void SetPrintStackTrace(void (*print_stack_trace_)()); + +// Override the default function that handles DCHECKs. +V8_BASE_EXPORT void SetDcheckFunction(void (*dcheck_Function)(const char*, int, + const char*)); + +// In official builds, assume all check failures can be debugged given just the +// stack trace. +#if !defined(DEBUG) && defined(OFFICIAL_BUILD) +#define CHECK_FAILED_HANDLER(message) FATAL("ignored") +#else +#define CHECK_FAILED_HANDLER(message) FATAL("Check failed: %s.", message) +#endif + +// CHECK dies with a fatal error if condition is not true. It is *not* +// controlled by DEBUG, so the check will be executed regardless of +// compilation mode. +// +// We make sure CHECK et al. always evaluates their arguments, as +// doing CHECK(FunctionWithSideEffect()) is a common idiom. +#define CHECK_WITH_MSG(condition, message) \ + do { \ + if (V8_UNLIKELY(!(condition))) { \ + CHECK_FAILED_HANDLER(message); \ + } \ + } while (false) +#define CHECK(condition) CHECK_WITH_MSG(condition, #condition) + +#ifdef DEBUG + +#define DCHECK_WITH_MSG(condition, message) \ + do { \ + if (V8_UNLIKELY(!(condition))) { \ + V8_Dcheck(__FILE__, __LINE__, message); \ + } \ + } while (false) +#define DCHECK(condition) DCHECK_WITH_MSG(condition, #condition) + +// Helper macro for binary operators. +// Don't use this macro directly in your code, use CHECK_EQ et al below. +#define CHECK_OP(name, op, lhs, rhs) \ + do { \ + if (std::string* _msg = ::v8::base::Check##name##Impl< \ + typename ::v8::base::pass_value_or_ref::type, \ + typename ::v8::base::pass_value_or_ref::type>( \ + (lhs), (rhs), #lhs " " #op " " #rhs)) { \ + FATAL("Check failed: %s.", _msg->c_str()); \ + delete _msg; \ + } \ + } while (false) + +#define DCHECK_OP(name, op, lhs, rhs) \ + do { \ + if (std::string* _msg = ::v8::base::Check##name##Impl< \ + typename ::v8::base::pass_value_or_ref::type, \ + typename ::v8::base::pass_value_or_ref::type>( \ + (lhs), (rhs), #lhs " " #op " " #rhs)) { \ + V8_Dcheck(__FILE__, __LINE__, _msg->c_str()); \ + delete _msg; \ + } \ + } while (false) + +#else + +// Make all CHECK functions discard their log strings to reduce code +// bloat for official release builds. + +#define CHECK_OP(name, op, lhs, rhs) \ + do { \ + bool _cmp = ::v8::base::Cmp##name##Impl< \ + typename ::v8::base::pass_value_or_ref::type, \ + typename ::v8::base::pass_value_or_ref::type>((lhs), \ + (rhs)); \ + CHECK_WITH_MSG(_cmp, #lhs " " #op " " #rhs); \ + } while (false) + +#define DCHECK_WITH_MSG(condition, msg) void(0); + +#endif + +namespace detail { +template +std::string PrintToString(Ts&&... ts) { + CheckMessageStream oss; + int unused_results[]{((oss << std::forward(ts)), 0)...}; + (void)unused_results; // Avoid "unused variable" warning. + return oss.str(); +} + +template +auto GetUnderlyingEnumTypeForPrinting(T val) { + using underlying_t = typename std::underlying_type::type; + // For single-byte enums, return a 16-bit integer to avoid printing the value + // as a character. + using int_t = typename std::conditional_t< + sizeof(underlying_t) != 1, underlying_t, + std::conditional_t::value, int16_t, + uint16_t> >; + return static_cast(static_cast(val)); +} +} // namespace detail + +// Define PrintCheckOperand for each T which defines operator<< for ostream. +template +typename std::enable_if< + !std::is_function::type>::value && + !std::is_enum::value && + has_output_operator::value, + std::string>::type +PrintCheckOperand(T val) { + return detail::PrintToString(std::forward(val)); +} + +// Provide an overload for functions and function pointers. Function pointers +// don't implicitly convert to void* but do implicitly convert to bool, so +// without this function pointers are always printed as 1 or 0. (MSVC isn't +// standards-conforming here and converts function pointers to regular +// pointers, so this is a no-op for MSVC.) +template +typename std::enable_if< + std::is_function::type>::value, + std::string>::type +PrintCheckOperand(T val) { + return PrintCheckOperand(reinterpret_cast(val)); +} + +// Define PrintCheckOperand for enums with an output operator. +template +typename std::enable_if::value && + has_output_operator::value, + std::string>::type +PrintCheckOperand(T val) { + std::string val_str = detail::PrintToString(val); + std::string int_str = + detail::PrintToString(detail::GetUnderlyingEnumTypeForPrinting(val)); + // Printing the original enum might have printed a single non-printable + // character. Ignore it in that case. Also ignore if it printed the same as + // the integral representation. + // TODO(clemensb): Can we somehow statically find out if the output operator + // is the default one, printing the integral value? + if ((val_str.length() == 1 && !std::isprint(val_str[0])) || + val_str == int_str) { + return int_str; + } + return detail::PrintToString(val_str, " (", int_str, ")"); +} + +// Define PrintCheckOperand for enums without an output operator. +template +typename std::enable_if::value && + !has_output_operator::value, + std::string>::type +PrintCheckOperand(T val) { + return detail::PrintToString(detail::GetUnderlyingEnumTypeForPrinting(val)); +} + +// Define default PrintCheckOperand for non-printable types. +template +typename std::enable_if::value && + !std::is_enum::value, + std::string>::type +PrintCheckOperand(T val) { + return ""; +} + +// Define specializations for character types, defined in logging.cc. +#define DEFINE_PRINT_CHECK_OPERAND_CHAR(type) \ + template <> \ + V8_BASE_EXPORT std::string PrintCheckOperand(type ch); \ + template <> \ + V8_BASE_EXPORT std::string PrintCheckOperand(type * cstr); \ + template <> \ + V8_BASE_EXPORT std::string PrintCheckOperand(const type* cstr); + +DEFINE_PRINT_CHECK_OPERAND_CHAR(char) +DEFINE_PRINT_CHECK_OPERAND_CHAR(signed char) +DEFINE_PRINT_CHECK_OPERAND_CHAR(unsigned char) +#undef DEFINE_PRINT_CHECK_OPERAND_CHAR + +// Build the error message string. This is separate from the "Impl" +// function template because it is not performance critical and so can +// be out of line, while the "Impl" code should be inline. Caller +// takes ownership of the returned string. +template +V8_NOINLINE std::string* MakeCheckOpString(Lhs lhs, Rhs rhs, char const* msg) { + std::string lhs_str = PrintCheckOperand(lhs); + std::string rhs_str = PrintCheckOperand(rhs); + CheckMessageStream ss; + ss << msg; + constexpr size_t kMaxInlineLength = 50; + if (lhs_str.size() <= kMaxInlineLength && + rhs_str.size() <= kMaxInlineLength) { + ss << " (" << lhs_str << " vs. " << rhs_str << ")"; + } else { + ss << "\n " << lhs_str << "\n vs.\n " << rhs_str << "\n"; + } + return new std::string(ss.str()); +} + +// Commonly used instantiations of MakeCheckOpString<>. Explicitly instantiated +// in logging.cc. +#define EXPLICIT_CHECK_OP_INSTANTIATION(type) \ + extern template V8_BASE_EXPORT std::string* MakeCheckOpString( \ + type, type, char const*); \ + extern template V8_BASE_EXPORT std::string PrintCheckOperand(type); + +EXPLICIT_CHECK_OP_INSTANTIATION(int) +EXPLICIT_CHECK_OP_INSTANTIATION(long) // NOLINT(runtime/int) +EXPLICIT_CHECK_OP_INSTANTIATION(long long) // NOLINT(runtime/int) +EXPLICIT_CHECK_OP_INSTANTIATION(unsigned int) +EXPLICIT_CHECK_OP_INSTANTIATION(unsigned long) // NOLINT(runtime/int) +EXPLICIT_CHECK_OP_INSTANTIATION(unsigned long long) // NOLINT(runtime/int) +EXPLICIT_CHECK_OP_INSTANTIATION(void const*) +#undef EXPLICIT_CHECK_OP_INSTANTIATION + +// comparison_underlying_type provides the underlying integral type of an enum, +// or std::decay::type if T is not an enum. Booleans are converted to +// "unsigned int", to allow "unsigned int == bool" comparisons. +template +struct comparison_underlying_type { + // std::underlying_type must only be used with enum types, thus use this + // {Dummy} type if the given type is not an enum. + enum Dummy {}; + using decay = typename std::decay::type; + static constexpr bool is_enum = std::is_enum::value; + using underlying = typename std::underlying_type< + typename std::conditional::type>::type; + using type_or_bool = + typename std::conditional::type; + using type = + typename std::conditional::value, + unsigned int, type_or_bool>::type; +}; +// Cast a value to its underlying type +#define MAKE_UNDERLYING(Type, value) \ + static_cast::type>(value) + +// is_signed_vs_unsigned::value is true if both types are integral, Lhs is +// signed, and Rhs is unsigned. False in all other cases. +template +struct is_signed_vs_unsigned { + using lhs_underlying = typename comparison_underlying_type::type; + using rhs_underlying = typename comparison_underlying_type::type; + static constexpr bool value = std::is_integral::value && + std::is_integral::value && + std::is_signed::value && + std::is_unsigned::value; +}; +// Same thing, other way around: Lhs is unsigned, Rhs signed. +template +struct is_unsigned_vs_signed : public is_signed_vs_unsigned {}; + +// Specialize the compare functions for signed vs. unsigned comparisons. +// std::enable_if ensures that this template is only instantiable if both Lhs +// and Rhs are integral types, and their signedness does not match. +#define MAKE_UNSIGNED(Type, value) \ + static_cast::type>::type>(value) +#define DEFINE_SIGNED_MISMATCH_COMP(CHECK, NAME, IMPL) \ + template \ + V8_INLINE constexpr \ + typename std::enable_if::value, bool>::type \ + Cmp##NAME##Impl(Lhs lhs, Rhs rhs) { \ + return IMPL; \ + } +DEFINE_SIGNED_MISMATCH_COMP(is_signed_vs_unsigned, EQ, + lhs >= 0 && MAKE_UNSIGNED(Lhs, lhs) == + MAKE_UNDERLYING(Rhs, rhs)) +DEFINE_SIGNED_MISMATCH_COMP(is_signed_vs_unsigned, LT, + lhs < 0 || MAKE_UNSIGNED(Lhs, lhs) < + MAKE_UNDERLYING(Rhs, rhs)) +DEFINE_SIGNED_MISMATCH_COMP(is_signed_vs_unsigned, LE, + lhs <= 0 || MAKE_UNSIGNED(Lhs, lhs) <= + MAKE_UNDERLYING(Rhs, rhs)) +DEFINE_SIGNED_MISMATCH_COMP(is_signed_vs_unsigned, NE, !CmpEQImpl(lhs, rhs)) +DEFINE_SIGNED_MISMATCH_COMP(is_signed_vs_unsigned, GT, !CmpLEImpl(lhs, rhs)) +DEFINE_SIGNED_MISMATCH_COMP(is_signed_vs_unsigned, GE, !CmpLTImpl(lhs, rhs)) +DEFINE_SIGNED_MISMATCH_COMP(is_unsigned_vs_signed, EQ, CmpEQImpl(rhs, lhs)) +DEFINE_SIGNED_MISMATCH_COMP(is_unsigned_vs_signed, NE, CmpNEImpl(rhs, lhs)) +DEFINE_SIGNED_MISMATCH_COMP(is_unsigned_vs_signed, LT, CmpGTImpl(rhs, lhs)) +DEFINE_SIGNED_MISMATCH_COMP(is_unsigned_vs_signed, LE, CmpGEImpl(rhs, lhs)) +DEFINE_SIGNED_MISMATCH_COMP(is_unsigned_vs_signed, GT, CmpLTImpl(rhs, lhs)) +DEFINE_SIGNED_MISMATCH_COMP(is_unsigned_vs_signed, GE, CmpLEImpl(rhs, lhs)) +#undef MAKE_UNSIGNED +#undef DEFINE_SIGNED_MISMATCH_COMP + +// Helper functions for CHECK_OP macro. +// The (float, float) and (double, double) instantiations are explicitly +// externalized to ensure proper 32/64-bit comparisons on x86. +// The Cmp##NAME##Impl function is only instantiable if one of the two types is +// not integral or their signedness matches (i.e. whenever no specialization is +// required, see above). Otherwise it is disabled by the enable_if construct, +// and the compiler will pick a specialization from above. +#define DEFINE_CHECK_OP_IMPL(NAME, op) \ + template \ + V8_INLINE constexpr \ + typename std::enable_if::value && \ + !is_unsigned_vs_signed::value, \ + bool>::type Cmp##NAME##Impl(Lhs lhs, Rhs rhs) { \ + return lhs op rhs; \ + } \ + template \ + V8_INLINE constexpr std::string* Check##NAME##Impl(Lhs lhs, Rhs rhs, \ + char const* msg) { \ + using LhsPassT = typename pass_value_or_ref::type; \ + using RhsPassT = typename pass_value_or_ref::type; \ + bool cmp = Cmp##NAME##Impl(lhs, rhs); \ + return V8_LIKELY(cmp) \ + ? nullptr \ + : MakeCheckOpString(lhs, rhs, msg); \ + } +DEFINE_CHECK_OP_IMPL(EQ, ==) +DEFINE_CHECK_OP_IMPL(NE, !=) +DEFINE_CHECK_OP_IMPL(LE, <=) +DEFINE_CHECK_OP_IMPL(LT, < ) +DEFINE_CHECK_OP_IMPL(GE, >=) +DEFINE_CHECK_OP_IMPL(GT, > ) +#undef DEFINE_CHECK_OP_IMPL + +#define CHECK_EQ(lhs, rhs) CHECK_OP(EQ, ==, lhs, rhs) +#define CHECK_NE(lhs, rhs) CHECK_OP(NE, !=, lhs, rhs) +#define CHECK_LE(lhs, rhs) CHECK_OP(LE, <=, lhs, rhs) +#define CHECK_LT(lhs, rhs) CHECK_OP(LT, <, lhs, rhs) +#define CHECK_GE(lhs, rhs) CHECK_OP(GE, >=, lhs, rhs) +#define CHECK_GT(lhs, rhs) CHECK_OP(GT, >, lhs, rhs) +#define CHECK_NULL(val) CHECK((val) == nullptr) +#define CHECK_NOT_NULL(val) CHECK((val) != nullptr) +#define CHECK_IMPLIES(lhs, rhs) \ + CHECK_WITH_MSG(!(lhs) || (rhs), #lhs " implies " #rhs) + +} // namespace base +} // namespace v8 + + +// The DCHECK macro is equivalent to CHECK except that it only +// generates code in debug builds. +#ifdef DEBUG +#define DCHECK_EQ(lhs, rhs) DCHECK_OP(EQ, ==, lhs, rhs) +#define DCHECK_NE(lhs, rhs) DCHECK_OP(NE, !=, lhs, rhs) +#define DCHECK_GT(lhs, rhs) DCHECK_OP(GT, >, lhs, rhs) +#define DCHECK_GE(lhs, rhs) DCHECK_OP(GE, >=, lhs, rhs) +#define DCHECK_LT(lhs, rhs) DCHECK_OP(LT, <, lhs, rhs) +#define DCHECK_LE(lhs, rhs) DCHECK_OP(LE, <=, lhs, rhs) +#define DCHECK_NULL(val) DCHECK((val) == nullptr) +#define DCHECK_NOT_NULL(val) DCHECK((val) != nullptr) +#define DCHECK_IMPLIES(lhs, rhs) \ + DCHECK_WITH_MSG(!(lhs) || (rhs), #lhs " implies " #rhs) +#else +#define DCHECK(condition) ((void) 0) +#define DCHECK_EQ(v1, v2) ((void) 0) +#define DCHECK_NE(v1, v2) ((void) 0) +#define DCHECK_GT(v1, v2) ((void) 0) +#define DCHECK_GE(v1, v2) ((void) 0) +#define DCHECK_LT(v1, v2) ((void) 0) +#define DCHECK_LE(v1, v2) ((void) 0) +#define DCHECK_NULL(val) ((void) 0) +#define DCHECK_NOT_NULL(val) ((void) 0) +#define DCHECK_IMPLIES(v1, v2) ((void) 0) +#endif + +#endif // V8_BASE_LOGGING_H_ diff --git a/Source/NativeScript/Inspector/src/base/macros.h b/Source/NativeScript/Inspector/src/base/macros.h new file mode 100644 index 0000000..3a73afc --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/macros.h @@ -0,0 +1,442 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_BASE_MACROS_H_ +#define V8_BASE_MACROS_H_ + +#include +#include + +#include "src/base/compiler-specific.h" +#include "src/base/logging.h" +#include "src/base/platform/wrappers.h" + +// No-op macro which is used to work around MSVC's funky VA_ARGS support. +#define EXPAND(x) x + +// This macro does nothing. That's all. +#define NOTHING(...) + +#define CONCAT_(a, b) a##b +#define CONCAT(a, b) CONCAT_(a, b) +// Creates an unique identifier. Useful for scopes to avoid shadowing names. +#define UNIQUE_IDENTIFIER(base) CONCAT(base, __COUNTER__) + +// TODO(all) Replace all uses of this macro with C++'s offsetof. To do that, we +// have to make sure that only standard-layout types and simple field +// designators are used. +#define OFFSET_OF(type, field) \ + (reinterpret_cast(&(reinterpret_cast(16)->field)) - 16) + + +// The arraysize(arr) macro returns the # of elements in an array arr. +// The expression is a compile-time constant, and therefore can be +// used in defining new arrays, for example. If you use arraysize on +// a pointer by mistake, you will get a compile-time error. +#define arraysize(array) (sizeof(ArraySizeHelper(array))) + + +// This template function declaration is used in defining arraysize. +// Note that the function doesn't need an implementation, as we only +// use its type. +template +char (&ArraySizeHelper(T (&array)[N]))[N]; + + +#if !V8_CC_MSVC +// That gcc wants both of these prototypes seems mysterious. VC, for +// its part, can't decide which to use (another mystery). Matching of +// template overloads: the final frontier. +template +char (&ArraySizeHelper(const T (&array)[N]))[N]; +#endif + +// bit_cast is a template function that implements the +// equivalent of "*reinterpret_cast(&source)". We need this in +// very low-level functions like the protobuf library and fast math +// support. +// +// float f = 3.14159265358979; +// int i = bit_cast(f); +// // i = 0x40490fdb +// +// The classical address-casting method is: +// +// // WRONG +// float f = 3.14159265358979; // WRONG +// int i = * reinterpret_cast(&f); // WRONG +// +// The address-casting method actually produces undefined behavior +// according to ISO C++ specification section 3.10 -15 -. Roughly, this +// section says: if an object in memory has one type, and a program +// accesses it with a different type, then the result is undefined +// behavior for most values of "different type". +// +// This is true for any cast syntax, either *(int*)&f or +// *reinterpret_cast(&f). And it is particularly true for +// conversions between integral lvalues and floating-point lvalues. +// +// The purpose of 3.10 -15- is to allow optimizing compilers to assume +// that expressions with different types refer to different memory. gcc +// 4.0.1 has an optimizer that takes advantage of this. So a +// non-conforming program quietly produces wildly incorrect output. +// +// The problem is not the use of reinterpret_cast. The problem is type +// punning: holding an object in memory of one type and reading its bits +// back using a different type. +// +// The C++ standard is more subtle and complex than this, but that +// is the basic idea. +// +// Anyways ... +// +// bit_cast<> calls memcpy() which is blessed by the standard, +// especially by the example in section 3.9 . Also, of course, +// bit_cast<> wraps up the nasty logic in one place. +// +// Fortunately memcpy() is very fast. In optimized mode, with a +// constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline +// code with the minimal amount of data movement. On a 32-bit system, +// memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8) +// compiles to two loads and two stores. +// +// I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1. +// +// WARNING: if Dest or Source is a non-POD type, the result of the memcpy +// is likely to surprise you. +template +V8_INLINE Dest bit_cast(Source const& source) { + static_assert(sizeof(Dest) == sizeof(Source), + "source and dest must be same size"); + Dest dest; + memcpy(&dest, &source, sizeof(dest)); + return dest; +} + +// Explicitly declare the assignment operator as deleted. +// Note: This macro is deprecated and will be removed soon. Please explicitly +// delete the assignment operator instead. +#define DISALLOW_ASSIGN(TypeName) TypeName& operator=(const TypeName&) = delete + +// Explicitly declare all implicit constructors as deleted, namely the +// default constructor, copy constructor and operator= functions. +// This is especially useful for classes containing only static methods. +#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ + TypeName() = delete; \ + TypeName(const TypeName&) = delete; \ + DISALLOW_ASSIGN(TypeName) + +// Disallow copying a type, but provide default construction, move construction +// and move assignment. Especially useful for move-only structs. +#define MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(TypeName) \ + TypeName() = default; \ + MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(TypeName) + +// Disallow copying a type, and only provide move construction and move +// assignment. Especially useful for move-only structs. +#define MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(TypeName) \ + TypeName(TypeName&&) V8_NOEXCEPT = default; \ + TypeName& operator=(TypeName&&) V8_NOEXCEPT = default; \ + TypeName(const TypeName&) = delete; \ + DISALLOW_ASSIGN(TypeName) + +// A macro to disallow the dynamic allocation. +// This should be used in the private: declarations for a class +// Declaring operator new and delete as deleted is not spec compliant. +// Extract from 3.2.2 of C++11 spec: +// [...] A non-placement deallocation function for a class is +// odr-used by the definition of the destructor of that class, [...] +#define DISALLOW_NEW_AND_DELETE() \ + void* operator new(size_t) { v8::base::OS::Abort(); } \ + void* operator new[](size_t) { v8::base::OS::Abort(); } \ + void operator delete(void*, size_t) { v8::base::OS::Abort(); } \ + void operator delete[](void*, size_t) { v8::base::OS::Abort(); } + +// Define V8_USE_ADDRESS_SANITIZER macro. +#if defined(__has_feature) +#if __has_feature(address_sanitizer) +#define V8_USE_ADDRESS_SANITIZER 1 +#endif +#endif + +// Define V8_USE_MEMORY_SANITIZER macro. +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +#define V8_USE_MEMORY_SANITIZER 1 +#endif +#endif + +// Define V8_USE_UNDEFINED_BEHAVIOR_SANITIZER macro. +#if defined(__has_feature) +#if __has_feature(undefined_behavior_sanitizer) +#define V8_USE_UNDEFINED_BEHAVIOR_SANITIZER 1 +#endif +#endif + +// DISABLE_CFI_PERF -- Disable Control Flow Integrity checks for Perf reasons. +#define DISABLE_CFI_PERF V8_CLANG_NO_SANITIZE("cfi") + +// DISABLE_CFI_ICALL -- Disable Control Flow Integrity indirect call checks, +// useful because calls into JITed code can not be CFI verified. +#ifdef V8_OS_WIN +// On Windows, also needs __declspec(guard(nocf)) for CFG. +#define DISABLE_CFI_ICALL \ + V8_CLANG_NO_SANITIZE("cfi-icall") \ + __declspec(guard(nocf)) +#else +#define DISABLE_CFI_ICALL V8_CLANG_NO_SANITIZE("cfi-icall") +#endif + +// A convenience wrapper around static_assert without a string message argument. +// Once C++17 becomes the default, this macro can be removed in favor of the +// new static_assert(condition) overload. +#define STATIC_ASSERT(test) static_assert(test, #test) + +namespace v8 { +namespace base { + +// Note that some implementations of std::is_trivially_copyable mandate that at +// least one of the copy constructor, move constructor, copy assignment or move +// assignment is non-deleted, while others do not. Be aware that also +// base::is_trivially_copyable will differ for these cases. +template +struct is_trivially_copyable { +#if V8_CC_MSVC + // Unfortunately, MSVC 2015 is broken in that std::is_trivially_copyable can + // be false even though it should be true according to the standard. + // (status at 2018-02-26, observed on the msvc waterfall bot). + // Interestingly, the lower-level primitives used below are working as + // intended, so we reimplement this according to the standard. + // See also https://developercommunity.visualstudio.com/content/problem/ + // 170883/msvc-type-traits-stdis-trivial-is-bugged.html. + static constexpr bool value = + // Copy constructor is trivial or deleted. + (std::is_trivially_copy_constructible::value || + !std::is_copy_constructible::value) && + // Copy assignment operator is trivial or deleted. + (std::is_trivially_copy_assignable::value || + !std::is_copy_assignable::value) && + // Move constructor is trivial or deleted. + (std::is_trivially_move_constructible::value || + !std::is_move_constructible::value) && + // Move assignment operator is trivial or deleted. + (std::is_trivially_move_assignable::value || + !std::is_move_assignable::value) && + // (Some implementations mandate that one of the above is non-deleted, but + // the standard does not, so let's skip this check.) + // Trivial non-deleted destructor. + std::is_trivially_destructible::value; +#else + static constexpr bool value = std::is_trivially_copyable::value; +#endif +}; +#define ASSERT_TRIVIALLY_COPYABLE(T) \ + static_assert(::v8::base::is_trivially_copyable::value, \ + #T " should be trivially copyable") +#define ASSERT_NOT_TRIVIALLY_COPYABLE(T) \ + static_assert(!::v8::base::is_trivially_copyable::value, \ + #T " should not be trivially copyable") + +// The USE(x, ...) template is used to silence C++ compiler warnings +// issued for (yet) unused variables (typically parameters). +// The arguments are guaranteed to be evaluated from left to right. +struct Use { + template + Use(T&&) {} // NOLINT(runtime/explicit) +}; +#define USE(...) \ + do { \ + ::v8::base::Use unused_tmp_array_for_use_macro[]{__VA_ARGS__}; \ + (void)unused_tmp_array_for_use_macro; \ + } while (false) + +// Evaluate the instantiations of an expression with parameter packs. +// Since USE has left-to-right evaluation order of it's arguments, +// the parameter pack is iterated from left to right and side effects +// have defined behavior. +#define ITERATE_PACK(...) USE(0, ((__VA_ARGS__), 0)...) + +} // namespace base +} // namespace v8 + +// implicit_cast(x) triggers an implicit cast from {x} to type {A}. This is +// useful in situations where static_cast(x) would do too much. +// Only use this for cheap-to-copy types, or use move semantics explicitly. +template +V8_INLINE A implicit_cast(A x) { + return x; +} + +// Define our own macros for writing 64-bit constants. This is less fragile +// than defining __STDC_CONSTANT_MACROS before including , and it +// works on compilers that don't have it (like MSVC). +#if V8_CC_MSVC +# if V8_HOST_ARCH_64_BIT +# define V8_PTR_PREFIX "ll" +# else +# define V8_PTR_PREFIX "" +# endif // V8_HOST_ARCH_64_BIT +#elif V8_CC_MINGW64 +# define V8_PTR_PREFIX "I64" +#elif V8_HOST_ARCH_64_BIT +# define V8_PTR_PREFIX "l" +#else +#if V8_OS_AIX +#define V8_PTR_PREFIX "l" +#else +# define V8_PTR_PREFIX "" +#endif +#endif + +#define V8PRIxPTR V8_PTR_PREFIX "x" +#define V8PRIdPTR V8_PTR_PREFIX "d" +#define V8PRIuPTR V8_PTR_PREFIX "u" + +#if V8_TARGET_ARCH_64_BIT +#define V8_PTR_HEX_DIGITS 12 +#define V8PRIxPTR_FMT "0x%012" V8PRIxPTR +#else +#define V8_PTR_HEX_DIGITS 8 +#define V8PRIxPTR_FMT "0x%08" V8PRIxPTR +#endif + +// ptrdiff_t is 't' according to the standard, but MSVC uses 'I'. +#if V8_CC_MSVC +#define V8PRIxPTRDIFF "Ix" +#define V8PRIdPTRDIFF "Id" +#define V8PRIuPTRDIFF "Iu" +#else +#define V8PRIxPTRDIFF "tx" +#define V8PRIdPTRDIFF "td" +#define V8PRIuPTRDIFF "tu" +#endif + +// Fix for Mac OS X defining uintptr_t as "unsigned long": +#if V8_OS_MACOSX +#undef V8PRIxPTR +#define V8PRIxPTR "lx" +#undef V8PRIdPTR +#define V8PRIdPTR "ld" +#undef V8PRIuPTR +#define V8PRIuPTR "lxu" +#endif + +// Make a uint64 from two uint32_t halves. +inline uint64_t make_uint64(uint32_t high, uint32_t low) { + return (uint64_t{high} << 32) + low; +} + +// Return the largest multiple of m which is <= x. +template +inline T RoundDown(T x, intptr_t m) { + STATIC_ASSERT(std::is_integral::value); + // m must be a power of two. + DCHECK(m != 0 && ((m & (m - 1)) == 0)); + return x & static_cast(-m); +} +template +constexpr inline T RoundDown(T x) { + STATIC_ASSERT(std::is_integral::value); + // m must be a power of two. + STATIC_ASSERT(m != 0 && ((m & (m - 1)) == 0)); + return x & static_cast(-m); +} + +// Return the smallest multiple of m which is >= x. +template +inline T RoundUp(T x, intptr_t m) { + STATIC_ASSERT(std::is_integral::value); + return RoundDown(static_cast(x + m - 1), m); +} +template +constexpr inline T RoundUp(T x) { + STATIC_ASSERT(std::is_integral::value); + return RoundDown(static_cast(x + (m - 1))); +} + +template +constexpr inline bool IsAligned(T value, U alignment) { + return (value & (alignment - 1)) == 0; +} + +inline void* AlignedAddress(void* address, size_t alignment) { + // The alignment must be a power of two. + DCHECK_EQ(alignment & (alignment - 1), 0u); + return reinterpret_cast(reinterpret_cast(address) & + ~static_cast(alignment - 1)); +} + +// Bounds checks for float to integer conversions, which does truncation. Hence, +// the range of legal values is (min - 1, max + 1). +template +bool is_inbounds(float_t v) { + static_assert(sizeof(int_t) < sizeof(biggest_int_t), + "int_t can't be bounds checked by the compiler"); + constexpr float_t kLowerBound = + static_cast(std::numeric_limits::min()) - 1; + constexpr float_t kUpperBound = + static_cast(std::numeric_limits::max()) + 1; + constexpr bool kLowerBoundIsMin = + static_cast(kLowerBound) == + static_cast(std::numeric_limits::min()); + constexpr bool kUpperBoundIsMax = + static_cast(kUpperBound) == + static_cast(std::numeric_limits::max()); + // Using USE(var) is only a workaround for a GCC 8.1 bug. + USE(kLowerBoundIsMin); + USE(kUpperBoundIsMax); + return (kLowerBoundIsMin ? (kLowerBound <= v) : (kLowerBound < v)) && + (kUpperBoundIsMax ? (v <= kUpperBound) : (v < kUpperBound)); +} + +#ifdef V8_OS_WIN + +// Setup for Windows shared library export. +#ifdef BUILDING_V8_SHARED +#define V8_EXPORT_PRIVATE __declspec(dllexport) +#elif USING_V8_SHARED +#define V8_EXPORT_PRIVATE __declspec(dllimport) +#else +#define V8_EXPORT_PRIVATE +#endif // BUILDING_V8_SHARED + +#else // V8_OS_WIN + +// Setup for Linux shared library export. +#if V8_HAS_ATTRIBUTE_VISIBILITY +#ifdef BUILDING_V8_SHARED +#define V8_EXPORT_PRIVATE __attribute__((visibility("default"))) +#else +#define V8_EXPORT_PRIVATE +#endif +#else +#define V8_EXPORT_PRIVATE +#endif + +#endif // V8_OS_WIN + +// Defines IF_WASM, to be used in macro lists for elements that should only be +// there if WebAssembly is enabled. +#if V8_ENABLE_WEBASSEMBLY +// EXPAND is needed to work around MSVC's broken __VA_ARGS__ expansion. +#define IF_WASM(V, ...) EXPAND(V(__VA_ARGS__)) +#else +#define IF_WASM(V, ...) +#endif // V8_ENABLE_WEBASSEMBLY + +// Defines IF_TSAN, to be used in macro lists for elements that should only be +// there if TSAN is enabled. +#ifdef V8_IS_TSAN +// EXPAND is needed to work around MSVC's broken __VA_ARGS__ expansion. +#define IF_TSAN(V, ...) EXPAND(V(__VA_ARGS__)) +#else +#define IF_TSAN(V, ...) +#endif // V8_ENABLE_WEBASSEMBLY + +#ifdef GOOGLE3 +// Disable FRIEND_TEST macro in Google3. +#define FRIEND_TEST(test_case_name, test_name) +#endif + +#endif // V8_BASE_MACROS_H_ diff --git a/Source/NativeScript/Inspector/src/base/memory.h b/Source/NativeScript/Inspector/src/base/memory.h new file mode 100644 index 0000000..db6a9ea --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/memory.h @@ -0,0 +1,89 @@ +// Copyright 2011 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_BASE_MEMORY_H_ +#define V8_BASE_MEMORY_H_ + +#include "src/base/macros.h" +#include "src/base/platform/wrappers.h" + +namespace v8 { +namespace base { + +using Address = uintptr_t; +using byte = uint8_t; + +// Memory provides an interface to 'raw' memory. It encapsulates the casts +// that typically are needed when incompatible pointer types are used. +// Note that this class currently relies on undefined behaviour. There is a +// proposal (http://wg21.link/p0593r2) to make it defined behaviour though. +template +inline T& Memory(Address addr) { + DCHECK(IsAligned(addr, alignof(T))); + return *reinterpret_cast(addr); +} +template +inline T& Memory(byte* addr) { + return Memory(reinterpret_cast
(addr)); +} + +template +static inline V ReadUnalignedValue(Address p) { + ASSERT_TRIVIALLY_COPYABLE(V); + V r; + memcpy(&r, reinterpret_cast(p), sizeof(V)); + return r; +} + +template +static inline void WriteUnalignedValue(Address p, V value) { + ASSERT_TRIVIALLY_COPYABLE(V); + memcpy(reinterpret_cast(p), &value, sizeof(V)); +} + +template +static inline V ReadLittleEndianValue(Address p) { +#if defined(V8_TARGET_LITTLE_ENDIAN) + return ReadUnalignedValue(p); +#elif defined(V8_TARGET_BIG_ENDIAN) + V ret{}; + const byte* src = reinterpret_cast(p); + byte* dst = reinterpret_cast(&ret); + for (size_t i = 0; i < sizeof(V); i++) { + dst[i] = src[sizeof(V) - i - 1]; + } + return ret; +#endif // V8_TARGET_LITTLE_ENDIAN +} + +template +static inline void WriteLittleEndianValue(Address p, V value) { +#if defined(V8_TARGET_LITTLE_ENDIAN) + WriteUnalignedValue(p, value); +#elif defined(V8_TARGET_BIG_ENDIAN) + byte* src = reinterpret_cast(&value); + byte* dst = reinterpret_cast(p); + for (size_t i = 0; i < sizeof(V); i++) { + dst[i] = src[sizeof(V) - i - 1]; + } +#endif // V8_TARGET_LITTLE_ENDIAN +} + +template +static inline V ReadLittleEndianValue(V* p) { + return ReadLittleEndianValue(reinterpret_cast
(p)); +} + +template +static inline void WriteLittleEndianValue(V* p, V value) { + static_assert( + !std::is_array::value, + "Passing an array decays to pointer, causing unexpected results."); + WriteLittleEndianValue(reinterpret_cast
(p), value); +} + +} // namespace base +} // namespace v8 + +#endif // V8_BASE_MEMORY_H_ diff --git a/Source/NativeScript/Inspector/src/base/once.h b/Source/NativeScript/Inspector/src/base/once.h new file mode 100644 index 0000000..c4224e8 --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/once.h @@ -0,0 +1,108 @@ +// Copyright 2012 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// emulates google3/base/once.h +// +// This header is intended to be included only by v8's internal code. Users +// should not use this directly. +// +// This is basically a portable version of pthread_once(). +// +// This header declares: +// * A type called OnceType. +// * A macro V8_DECLARE_ONCE() which declares a (global) variable of type +// OnceType. +// * A function CallOnce(OnceType* once, void (*init_func)()). +// This function, when invoked multiple times given the same OnceType object, +// will invoke init_func on the first call only, and will make sure none of +// the calls return before that first call to init_func has finished. +// +// Additionally, the following features are supported: +// * A macro V8_ONCE_INIT which is expanded into the expression used to +// initialize a OnceType. This is only useful when clients embed a OnceType +// into a structure of their own and want to initialize it statically. +// * The user can provide a parameter which CallOnce() forwards to the +// user-provided function when it is called. Usage example: +// CallOnce(&my_once, &MyFunctionExpectingIntArgument, 10); +// * This implementation guarantees that OnceType is a POD (i.e. no static +// initializer generated). +// +// This implements a way to perform lazy initialization. It's more efficient +// than using mutexes as no lock is needed if initialization has already +// happened. +// +// Example usage: +// void Init(); +// V8_DECLARE_ONCE(once_init); +// +// // Calls Init() exactly once. +// void InitOnce() { +// CallOnce(&once_init, &Init); +// } +// +// Note that if CallOnce() is called before main() has begun, it must +// only be called by the thread that will eventually call main() -- that is, +// the thread that performs dynamic initialization. In general this is a safe +// assumption since people don't usually construct threads before main() starts, +// but it is technically not guaranteed. Unfortunately, Win32 provides no way +// whatsoever to statically-initialize its synchronization primitives, so our +// only choice is to assume that dynamic initialization is single-threaded. + +#ifndef V8_BASE_ONCE_H_ +#define V8_BASE_ONCE_H_ + +#include + +#include +#include + +#include "src/base/base-export.h" +#include "src/base/template-utils.h" + +namespace v8 { +namespace base { + +using OnceType = std::atomic; + +#define V8_ONCE_INIT \ + { 0 } + +#define V8_DECLARE_ONCE(NAME) ::v8::base::OnceType NAME + +enum : uint8_t { + ONCE_STATE_UNINITIALIZED = 0, + ONCE_STATE_EXECUTING_FUNCTION = 1, + ONCE_STATE_DONE = 2 +}; + +using PointerArgFunction = void (*)(void* arg); + +template +struct FunctionWithArgs { + using type = void (*)(Args...); +}; + +V8_BASE_EXPORT void CallOnceImpl(OnceType* once, + std::function init_func); + +inline void CallOnce(OnceType* once, std::function init_func) { + if (once->load(std::memory_order_acquire) != ONCE_STATE_DONE) { + CallOnceImpl(once, init_func); + } +} + +template ...>::value>> +inline void CallOnce(OnceType* once, + typename FunctionWithArgs::type init_func, + Args... args) { + if (once->load(std::memory_order_acquire) != ONCE_STATE_DONE) { + CallOnceImpl(once, [=]() { init_func(args...); }); + } +} + +} // namespace base +} // namespace v8 + +#endif // V8_BASE_ONCE_H_ diff --git a/Source/NativeScript/Inspector/src/base/optional.h b/Source/NativeScript/Inspector/src/base/optional.h new file mode 100644 index 0000000..31fe9a9 --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/optional.h @@ -0,0 +1,882 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file is a clone of "base/optional.h" in chromium. +// Keep in sync, especially when fixing bugs. +// Copyright 2017 the V8 project authors. All rights reserved. + +#ifndef V8_BASE_OPTIONAL_H_ +#define V8_BASE_OPTIONAL_H_ + +#include +#include + +#include "src/base/logging.h" + +namespace v8 { +namespace base { + +// Specification: +// http://en.cppreference.com/w/cpp/utility/optional/in_place_t +struct in_place_t {}; + +// Specification: +// http://en.cppreference.com/w/cpp/utility/optional/nullopt_t +struct nullopt_t { + constexpr explicit nullopt_t(int) {} +}; + +// Specification: +// http://en.cppreference.com/w/cpp/utility/optional/in_place +constexpr in_place_t in_place = {}; + +// Specification: +// http://en.cppreference.com/w/cpp/utility/optional/nullopt +constexpr nullopt_t nullopt(0); + +// Forward declaration, which is referred by following helpers. +template +class Optional; + +namespace internal { + +template ::value> +struct OptionalStorageBase { + // Initializing |empty_| here instead of using default member initializing + // to avoid errors in g++ 4.8. + constexpr OptionalStorageBase() : empty_('\0') {} + + template + constexpr explicit OptionalStorageBase(in_place_t, Args&&... args) + : is_populated_(true), value_(std::forward(args)...) {} + + // When T is not trivially destructible we must call its + // destructor before deallocating its memory. + // Note that this hides the (implicitly declared) move constructor, which + // would be used for constexpr move constructor in OptionalStorage. + // It is needed iff T is trivially move constructible. However, the current + // is_trivially_{copy,move}_constructible implementation requires + // is_trivially_destructible (which looks a bug, cf: + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 and + // http://cplusplus.github.io/LWG/lwg-active.html#2116), so it is not + // necessary for this case at the moment. Please see also the destructor + // comment in "is_trivially_destructible = true" specialization below. + ~OptionalStorageBase() { + if (is_populated_) value_.~T(); + } + + template + void Init(Args&&... args) { + DCHECK(!is_populated_); + ::new (&value_) T(std::forward(args)...); + is_populated_ = true; + } + + bool is_populated_ = false; + union { + // |empty_| exists so that the union will always be initialized, even when + // it doesn't contain a value. Union members must be initialized for the + // constructor to be 'constexpr'. + char empty_; + T value_; + }; +}; + +template +struct OptionalStorageBase { + // Initializing |empty_| here instead of using default member initializing + // to avoid errors in g++ 4.8. + constexpr OptionalStorageBase() : empty_('\0') {} + + template + constexpr explicit OptionalStorageBase(in_place_t, Args&&... args) + : is_populated_(true), value_(std::forward(args)...) {} + + // When T is trivially destructible (i.e. its destructor does nothing) there + // is no need to call it. Implicitly defined destructor is trivial, because + // both members (bool and union containing only variants which are trivially + // destructible) are trivially destructible. + // Explicitly-defaulted destructor is also trivial, but do not use it here, + // because it hides the implicit move constructor. It is needed to implement + // constexpr move constructor in OptionalStorage iff T is trivially move + // constructible. Note that, if T is trivially move constructible, the move + // constructor of OptionalStorageBase is also implicitly defined and it is + // trivially move constructor. If T is not trivially move constructible, + // "not declaring move constructor without destructor declaration" here means + // "delete move constructor", which works because any move constructor of + // OptionalStorage will not refer to it in that case. + + template + void Init(Args&&... args) { + DCHECK(!is_populated_); + ::new (&value_) T(std::forward(args)...); + is_populated_ = true; + } + + bool is_populated_ = false; + union { + // |empty_| exists so that the union will always be initialized, even when + // it doesn't contain a value. Union members must be initialized for the + // constructor to be 'constexpr'. + char empty_; + T value_; + }; +}; + +// Implement conditional constexpr copy and move constructors. These are +// constexpr if is_trivially_{copy,move}_constructible::value is true +// respectively. If each is true, the corresponding constructor is defined as +// "= default;", which generates a constexpr constructor (In this case, +// the condition of constexpr-ness is satisfied because the base class also has +// compiler generated constexpr {copy,move} constructors). Note that +// placement-new is prohibited in constexpr. +template ::value, + bool = std::is_trivially_move_constructible::value> +struct OptionalStorage : OptionalStorageBase { + // This is no trivially {copy,move} constructible case. Other cases are + // defined below as specializations. + + // Accessing the members of template base class requires explicit + // declaration. + using OptionalStorageBase::is_populated_; + using OptionalStorageBase::value_; + using OptionalStorageBase::Init; + + // Inherit constructors (specifically, the in_place constructor). + using OptionalStorageBase::OptionalStorageBase; + + // User defined constructor deletes the default constructor. + // Define it explicitly. + OptionalStorage() = default; + + OptionalStorage(const OptionalStorage& other) V8_NOEXCEPT { + if (other.is_populated_) Init(other.value_); + } + + OptionalStorage(OptionalStorage&& other) V8_NOEXCEPT { + if (other.is_populated_) Init(std::move(other.value_)); + } +}; + +template +struct OptionalStorage + : OptionalStorageBase { + using OptionalStorageBase::is_populated_; + using OptionalStorageBase::value_; + using OptionalStorageBase::Init; + using OptionalStorageBase::OptionalStorageBase; + + OptionalStorage() = default; + OptionalStorage(const OptionalStorage& other) V8_NOEXCEPT = default; + + OptionalStorage(OptionalStorage&& other) V8_NOEXCEPT { + if (other.is_populated_) Init(std::move(other.value_)); + } +}; + +template +struct OptionalStorage + : OptionalStorageBase { + using OptionalStorageBase::is_populated_; + using OptionalStorageBase::value_; + using OptionalStorageBase::Init; + using OptionalStorageBase::OptionalStorageBase; + + OptionalStorage() = default; + OptionalStorage(OptionalStorage&& other) V8_NOEXCEPT = default; + + OptionalStorage(const OptionalStorage& other) V8_NOEXCEPT { + if (other.is_populated_) Init(other.value_); + } +}; + +template +struct OptionalStorage + : OptionalStorageBase { + // If both trivially {copy,move} constructible are true, it is not necessary + // to use user-defined constructors. So, just inheriting constructors + // from the base class works. + using OptionalStorageBase::OptionalStorageBase; +}; + +// Base class to support conditionally usable copy-/move- constructors +// and assign operators. +template +class OptionalBase { + // This class provides implementation rather than public API, so everything + // should be hidden. Often we use composition, but we cannot in this case + // because of C++ language restriction. + protected: + constexpr OptionalBase() = default; + constexpr OptionalBase(const OptionalBase& other) V8_NOEXCEPT = default; + constexpr OptionalBase(OptionalBase&& other) V8_NOEXCEPT = default; + + template + constexpr explicit OptionalBase(in_place_t, Args&&... args) + : storage_(in_place, std::forward(args)...) {} + + // Implementation of converting constructors. + template + explicit OptionalBase(const OptionalBase& other) V8_NOEXCEPT { + if (other.storage_.is_populated_) storage_.Init(other.storage_.value_); + } + + template + explicit OptionalBase(OptionalBase&& other) V8_NOEXCEPT { + if (other.storage_.is_populated_) + storage_.Init(std::move(other.storage_.value_)); + } + + ~OptionalBase() = default; + + OptionalBase& operator=(const OptionalBase& other) V8_NOEXCEPT { + CopyAssign(other); + return *this; + } + + OptionalBase& operator=(OptionalBase&& other) V8_NOEXCEPT { + MoveAssign(std::move(other)); + return *this; + } + + template + void CopyAssign(const OptionalBase& other) { + if (other.storage_.is_populated_) + InitOrAssign(other.storage_.value_); + else + FreeIfNeeded(); + } + + template + void MoveAssign(OptionalBase&& other) { + if (other.storage_.is_populated_) + InitOrAssign(std::move(other.storage_.value_)); + else + FreeIfNeeded(); + } + + template + void InitOrAssign(U&& value) { + if (storage_.is_populated_) + storage_.value_ = std::forward(value); + else + storage_.Init(std::forward(value)); + } + + void FreeIfNeeded() { + if (!storage_.is_populated_) return; + storage_.value_.~T(); + storage_.is_populated_ = false; + } + + // For implementing conversion, allow access to other typed OptionalBase + // class. + template + friend class OptionalBase; + + OptionalStorage storage_; +}; + +// The following {Copy,Move}{Constructible,Assignable} structs are helpers to +// implement constructor/assign-operator overloading. Specifically, if T is +// is not movable but copyable, Optional's move constructor should not +// participate in overload resolution. This inheritance trick implements that. +template +struct CopyConstructible {}; + +template <> +struct CopyConstructible { + constexpr CopyConstructible() = default; + constexpr CopyConstructible(const CopyConstructible&) V8_NOEXCEPT = delete; + constexpr CopyConstructible(CopyConstructible&&) V8_NOEXCEPT = default; + CopyConstructible& operator=(const CopyConstructible&) V8_NOEXCEPT = default; + CopyConstructible& operator=(CopyConstructible&&) V8_NOEXCEPT = default; +}; + +template +struct MoveConstructible {}; + +template <> +struct MoveConstructible { + constexpr MoveConstructible() = default; + constexpr MoveConstructible(const MoveConstructible&) V8_NOEXCEPT = default; + constexpr MoveConstructible(MoveConstructible&&) V8_NOEXCEPT = delete; + MoveConstructible& operator=(const MoveConstructible&) V8_NOEXCEPT = default; + MoveConstructible& operator=(MoveConstructible&&) V8_NOEXCEPT = default; +}; + +template +struct CopyAssignable {}; + +template <> +struct CopyAssignable { + constexpr CopyAssignable() = default; + constexpr CopyAssignable(const CopyAssignable&) V8_NOEXCEPT = default; + constexpr CopyAssignable(CopyAssignable&&) V8_NOEXCEPT = default; + CopyAssignable& operator=(const CopyAssignable&) V8_NOEXCEPT = delete; + CopyAssignable& operator=(CopyAssignable&&) V8_NOEXCEPT = default; +}; + +template +struct MoveAssignable {}; + +template <> +struct MoveAssignable { + constexpr MoveAssignable() = default; + constexpr MoveAssignable(const MoveAssignable&) V8_NOEXCEPT = default; + constexpr MoveAssignable(MoveAssignable&&) V8_NOEXCEPT = default; + MoveAssignable& operator=(const MoveAssignable&) V8_NOEXCEPT = default; + MoveAssignable& operator=(MoveAssignable&&) V8_NOEXCEPT = delete; +}; + +// Helper to conditionally enable converting constructors and assign operators. +template +struct IsConvertibleFromOptional + : std::integral_constant< + bool, std::is_constructible&>::value || + std::is_constructible&>::value || + std::is_constructible&&>::value || + std::is_constructible&&>::value || + std::is_convertible&, T>::value || + std::is_convertible&, T>::value || + std::is_convertible&&, T>::value || + std::is_convertible&&, T>::value> {}; + +template +struct IsAssignableFromOptional + : std::integral_constant< + bool, IsConvertibleFromOptional::value || + std::is_assignable&>::value || + std::is_assignable&>::value || + std::is_assignable&&>::value || + std::is_assignable&&>::value> {}; + +// Forward compatibility for C++17. +// Introduce one more deeper nested namespace to avoid leaking using std::swap. +namespace swappable_impl { +using std::swap; + +struct IsSwappableImpl { + // Tests if swap can be called. Check(0) returns true_type iff swap + // is available for T. Otherwise, Check's overload resolution falls back + // to Check(...) declared below thanks to SFINAE, so returns false_type. + template + static auto Check(int i) + -> decltype(swap(std::declval(), std::declval()), std::true_type()); + + template + static std::false_type Check(...); +}; +} // namespace swappable_impl + +template +struct IsSwappable : decltype(swappable_impl::IsSwappableImpl::Check(0)) {}; + +// Forward compatibility for C++20. +template +using RemoveCvRefT = + typename std::remove_cv::type>::type; + +} // namespace internal + +// On Windows, by default, empty-base class optimization does not work, +// which means even if the base class is empty struct, it still consumes one +// byte for its body. __declspec(empty_bases) enables the optimization. +// cf) +// https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/ +#ifdef OS_WIN +#define OPTIONAL_DECLSPEC_EMPTY_BASES __declspec(empty_bases) +#else +#define OPTIONAL_DECLSPEC_EMPTY_BASES +#endif + +// base::Optional is a Chromium version of the C++17 optional class: +// std::optional documentation: +// http://en.cppreference.com/w/cpp/utility/optional +// Chromium documentation: +// https://chromium.googlesource.com/chromium/src/+/master/docs/optional.md +// +// These are the differences between the specification and the implementation: +// - Constructors do not use 'constexpr' as it is a C++14 extension. +// - 'constexpr' might be missing in some places for reasons specified locally. +// - No exceptions are thrown, because they are banned from Chromium. +// All copy/move constructors or assignment operators are marked V8_NOEXCEPT. +// - All the non-members are in the 'base' namespace instead of 'std'. +// +// Note that T cannot have a constructor T(Optional) etc. Optional checks +// T's constructor (specifically via IsConvertibleFromOptional), and in the +// check whether T can be constructible from Optional, which is recursive +// so it does not work. As of Feb 2018, std::optional C++17 implementation in +// both clang and gcc has same limitation. MSVC SFINAE looks to have different +// behavior, but anyway it reports an error, too. +template +class OPTIONAL_DECLSPEC_EMPTY_BASES Optional + : public internal::OptionalBase, + public internal::CopyConstructible::value>, + public internal::MoveConstructible::value>, + public internal::CopyAssignable::value && + std::is_copy_assignable::value>, + public internal::MoveAssignable::value && + std::is_move_assignable::value> { + public: +#undef OPTIONAL_DECLSPEC_EMPTY_BASES + using value_type = T; + + // Defer default/copy/move constructor implementation to OptionalBase. + constexpr Optional() = default; + constexpr Optional(const Optional& other) V8_NOEXCEPT = default; + constexpr Optional(Optional&& other) V8_NOEXCEPT = default; + + constexpr Optional(nullopt_t) {} // NOLINT(runtime/explicit) + + // Converting copy constructor. "explicit" only if + // std::is_convertible::value is false. It is implemented by + // declaring two almost same constructors, but that condition in enable_if + // is different, so that either one is chosen, thanks to SFINAE. + template ::value && + !internal::IsConvertibleFromOptional::value && + std::is_convertible::value, + bool>::type = false> + Optional(const Optional& other) V8_NOEXCEPT + : internal::OptionalBase(other) {} + + template ::value && + !internal::IsConvertibleFromOptional::value && + !std::is_convertible::value, + bool>::type = false> + explicit Optional(const Optional& other) V8_NOEXCEPT + : internal::OptionalBase(other) {} + + // Converting move constructor. Similar to converting copy constructor, + // declaring two (explicit and non-explicit) constructors. + template ::value && + !internal::IsConvertibleFromOptional::value && + std::is_convertible::value, + bool>::type = false> + Optional(Optional&& other) V8_NOEXCEPT + : internal::OptionalBase(std::move(other)) {} + + template ::value && + !internal::IsConvertibleFromOptional::value && + !std::is_convertible::value, + bool>::type = false> + explicit Optional(Optional&& other) V8_NOEXCEPT + : internal::OptionalBase(std::move(other)) {} + + template + constexpr explicit Optional(in_place_t, Args&&... args) + : internal::OptionalBase(in_place, std::forward(args)...) {} + + template &, Args...>::value>::type> + constexpr explicit Optional(in_place_t, std::initializer_list il, + Args&&... args) + : internal::OptionalBase(in_place, il, std::forward(args)...) {} + + // Forward value constructor. Similar to converting constructors, + // conditionally explicit. + template < + typename U = value_type, + typename std::enable_if< + std::is_constructible::value && + !std::is_same, in_place_t>::value && + !std::is_same, Optional>::value && + std::is_convertible::value, + bool>::type = false> + constexpr Optional(U&& value) // NOLINT(runtime/explicit) + : internal::OptionalBase(in_place, std::forward(value)) {} + + template < + typename U = value_type, + typename std::enable_if< + std::is_constructible::value && + !std::is_same, in_place_t>::value && + !std::is_same, Optional>::value && + !std::is_convertible::value, + bool>::type = false> + constexpr explicit Optional(U&& value) + : internal::OptionalBase(in_place, std::forward(value)) {} + + ~Optional() = default; + + // Defer copy-/move- assign operator implementation to OptionalBase. + Optional& operator=(const Optional& other) V8_NOEXCEPT = default; + Optional& operator=(Optional&& other) V8_NOEXCEPT = default; + + Optional& operator=(nullopt_t) { + FreeIfNeeded(); + return *this; + } + + // Perfect-forwarded assignment. + template + typename std::enable_if< + !std::is_same, Optional>::value && + std::is_constructible::value && + std::is_assignable::value && + (!std::is_scalar::value || + !std::is_same::type, T>::value), + Optional&>::type + operator=(U&& value) V8_NOEXCEPT { + InitOrAssign(std::forward(value)); + return *this; + } + + // Copy assign the state of other. + template + typename std::enable_if::value && + std::is_constructible::value && + std::is_assignable::value, + Optional&>::type + operator=(const Optional& other) V8_NOEXCEPT { + CopyAssign(other); + return *this; + } + + // Move assign the state of other. + template + typename std::enable_if::value && + std::is_constructible::value && + std::is_assignable::value, + Optional&>::type + operator=(Optional&& other) V8_NOEXCEPT { + MoveAssign(std::move(other)); + return *this; + } + + constexpr const T* operator->() const { + DCHECK(storage_.is_populated_); + return &storage_.value_; + } + + constexpr T* operator->() { + DCHECK(storage_.is_populated_); + return &storage_.value_; + } + + constexpr const T& operator*() const& { + DCHECK(storage_.is_populated_); + return storage_.value_; + } + + constexpr T& operator*() & { + DCHECK(storage_.is_populated_); + return storage_.value_; + } + + constexpr const T&& operator*() const&& { + DCHECK(storage_.is_populated_); + return std::move(storage_.value_); + } + + constexpr T&& operator*() && { + DCHECK(storage_.is_populated_); + return std::move(storage_.value_); + } + + constexpr explicit operator bool() const { return storage_.is_populated_; } + + constexpr bool has_value() const { return storage_.is_populated_; } + + T& value() & { + CHECK(storage_.is_populated_); + return storage_.value_; + } + + const T& value() const & { + CHECK(storage_.is_populated_); + return storage_.value_; + } + + T&& value() && { + CHECK(storage_.is_populated_); + return std::move(storage_.value_); + } + + const T&& value() const && { + CHECK(storage_.is_populated_); + return std::move(storage_.value_); + } + + template + constexpr T value_or(U&& default_value) const & { + // TODO(mlamouri): add the following assert when possible: + // static_assert(std::is_copy_constructible::value, + // "T must be copy constructible"); + static_assert(std::is_convertible::value, + "U must be convertible to T"); + return storage_.is_populated_ + ? storage_.value_ + : static_cast(std::forward(default_value)); + } + + template + T value_or(U&& default_value) && { + // TODO(mlamouri): add the following assert when possible: + // static_assert(std::is_move_constructible::value, + // "T must be move constructible"); + static_assert(std::is_convertible::value, + "U must be convertible to T"); + return storage_.is_populated_ + ? std::move(storage_.value_) + : static_cast(std::forward(default_value)); + } + + void swap(Optional& other) { + if (!storage_.is_populated_ && !other.storage_.is_populated_) return; + + if (storage_.is_populated_ != other.storage_.is_populated_) { + if (storage_.is_populated_) { + other.storage_.Init(std::move(storage_.value_)); + FreeIfNeeded(); + } else { + storage_.Init(std::move(other.storage_.value_)); + other.FreeIfNeeded(); + } + return; + } + + DCHECK(storage_.is_populated_ && other.storage_.is_populated_); + using std::swap; + swap(**this, *other); + } + + void reset() { FreeIfNeeded(); } + + template + T& emplace(Args&&... args) { + FreeIfNeeded(); + storage_.Init(std::forward(args)...); + return storage_.value_; + } + + template + typename std::enable_if< + std::is_constructible&, Args&&...>::value, + T&>::type + emplace(std::initializer_list il, Args&&... args) { + FreeIfNeeded(); + storage_.Init(il, std::forward(args)...); + return storage_.value_; + } + + private: + // Accessing template base class's protected member needs explicit + // declaration to do so. + using internal::OptionalBase::CopyAssign; + using internal::OptionalBase::FreeIfNeeded; + using internal::OptionalBase::InitOrAssign; + using internal::OptionalBase::MoveAssign; + using internal::OptionalBase::storage_; +}; + +// Here after defines comparation operators. The definition follows +// http://en.cppreference.com/w/cpp/utility/optional/operator_cmp +// while bool() casting is replaced by has_value() to meet the chromium +// style guide. +template +bool operator==(const Optional& lhs, const Optional& rhs) { + if (lhs.has_value() != rhs.has_value()) return false; + if (!lhs.has_value()) return true; + return *lhs == *rhs; +} + +template +bool operator!=(const Optional& lhs, const Optional& rhs) { + if (lhs.has_value() != rhs.has_value()) return true; + if (!lhs.has_value()) return false; + return *lhs != *rhs; +} + +template +bool operator<(const Optional& lhs, const Optional& rhs) { + if (!rhs.has_value()) return false; + if (!lhs.has_value()) return true; + return *lhs < *rhs; +} + +template +bool operator<=(const Optional& lhs, const Optional& rhs) { + if (!lhs.has_value()) return true; + if (!rhs.has_value()) return false; + return *lhs <= *rhs; +} + +template +bool operator>(const Optional& lhs, const Optional& rhs) { + if (!lhs.has_value()) return false; + if (!rhs.has_value()) return true; + return *lhs > *rhs; +} + +template +bool operator>=(const Optional& lhs, const Optional& rhs) { + if (!rhs.has_value()) return true; + if (!lhs.has_value()) return false; + return *lhs >= *rhs; +} + +template +constexpr bool operator==(const Optional& opt, nullopt_t) { + return !opt; +} + +template +constexpr bool operator==(nullopt_t, const Optional& opt) { + return !opt; +} + +template +constexpr bool operator!=(const Optional& opt, nullopt_t) { + return opt.has_value(); +} + +template +constexpr bool operator!=(nullopt_t, const Optional& opt) { + return opt.has_value(); +} + +template +constexpr bool operator<(const Optional& opt, nullopt_t) { + return false; +} + +template +constexpr bool operator<(nullopt_t, const Optional& opt) { + return opt.has_value(); +} + +template +constexpr bool operator<=(const Optional& opt, nullopt_t) { + return !opt; +} + +template +constexpr bool operator<=(nullopt_t, const Optional& opt) { + return true; +} + +template +constexpr bool operator>(const Optional& opt, nullopt_t) { + return opt.has_value(); +} + +template +constexpr bool operator>(nullopt_t, const Optional& opt) { + return false; +} + +template +constexpr bool operator>=(const Optional& opt, nullopt_t) { + return true; +} + +template +constexpr bool operator>=(nullopt_t, const Optional& opt) { + return !opt; +} + +template +constexpr bool operator==(const Optional& opt, const U& value) { + return opt.has_value() ? *opt == value : false; +} + +template +constexpr bool operator==(const U& value, const Optional& opt) { + return opt.has_value() ? value == *opt : false; +} + +template +constexpr bool operator!=(const Optional& opt, const U& value) { + return opt.has_value() ? *opt != value : true; +} + +template +constexpr bool operator!=(const U& value, const Optional& opt) { + return opt.has_value() ? value != *opt : true; +} + +template +constexpr bool operator<(const Optional& opt, const U& value) { + return opt.has_value() ? *opt < value : true; +} + +template +constexpr bool operator<(const U& value, const Optional& opt) { + return opt.has_value() ? value < *opt : false; +} + +template +constexpr bool operator<=(const Optional& opt, const U& value) { + return opt.has_value() ? *opt <= value : true; +} + +template +constexpr bool operator<=(const U& value, const Optional& opt) { + return opt.has_value() ? value <= *opt : false; +} + +template +constexpr bool operator>(const Optional& opt, const U& value) { + return opt.has_value() ? *opt > value : false; +} + +template +constexpr bool operator>(const U& value, const Optional& opt) { + return opt.has_value() ? value > *opt : true; +} + +template +constexpr bool operator>=(const Optional& opt, const U& value) { + return opt.has_value() ? *opt >= value : false; +} + +template +constexpr bool operator>=(const U& value, const Optional& opt) { + return opt.has_value() ? value >= *opt : true; +} + +template +constexpr Optional::type> make_optional(T&& value) { + return Optional::type>(std::forward(value)); +} + +template +constexpr Optional make_optional(Args&&... args) { + return Optional(in_place, std::forward(args)...); +} + +template +constexpr Optional make_optional(std::initializer_list il, + Args&&... args) { + return Optional(in_place, il, std::forward(args)...); +} + +// Partial specialization for a function template is not allowed. Also, it is +// not allowed to add overload function to std namespace, while it is allowed +// to specialize the template in std. Thus, swap() (kind of) overloading is +// defined in base namespace, instead. +template +typename std::enable_if::value && + internal::IsSwappable::value>::type +swap(Optional& lhs, Optional& rhs) { + lhs.swap(rhs); +} + +} // namespace base +} // namespace v8 + +#endif // V8_BASE_OPTIONAL_H_ diff --git a/Source/NativeScript/Inspector/src/base/platform/mutex.h b/Source/NativeScript/Inspector/src/base/platform/mutex.h new file mode 100644 index 0000000..5fefa25 --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/platform/mutex.h @@ -0,0 +1,375 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_BASE_PLATFORM_MUTEX_H_ +#define V8_BASE_PLATFORM_MUTEX_H_ + +#include "src/base/base-export.h" +#include "src/base/lazy-instance.h" +#include "src/base/optional.h" +#if V8_OS_WIN +#include "src/base/win32-headers.h" +#endif +#include "src/base/logging.h" + +#if V8_OS_POSIX +#include +#endif + +#if V8_OS_STARBOARD +#include "starboard/common/mutex.h" +#include "starboard/common/recursive_mutex.h" +#include "starboard/common/rwlock.h" +#endif + +namespace v8 { +namespace base { + +// ---------------------------------------------------------------------------- +// Mutex - a replacement for std::mutex +// +// This class is a synchronization primitive that can be used to protect shared +// data from being simultaneously accessed by multiple threads. A mutex offers +// exclusive, non-recursive ownership semantics: +// - A calling thread owns a mutex from the time that it successfully calls +// either |Lock()| or |TryLock()| until it calls |Unlock()|. +// - When a thread owns a mutex, all other threads will block (for calls to +// |Lock()|) or receive a |false| return value (for |TryLock()|) if they +// attempt to claim ownership of the mutex. +// A calling thread must not own the mutex prior to calling |Lock()| or +// |TryLock()|. The behavior of a program is undefined if a mutex is destroyed +// while still owned by some thread. The Mutex class is non-copyable. + +class V8_BASE_EXPORT Mutex final { + public: + Mutex(); + Mutex(const Mutex&) = delete; + Mutex& operator=(const Mutex&) = delete; + ~Mutex(); + + // Locks the given mutex. If the mutex is currently unlocked, it becomes + // locked and owned by the calling thread, and immediately. If the mutex + // is already locked by another thread, suspends the calling thread until + // the mutex is unlocked. + void Lock(); + + // Unlocks the given mutex. The mutex is assumed to be locked and owned by + // the calling thread on entrance. + void Unlock(); + + // Tries to lock the given mutex. Returns whether the mutex was + // successfully locked. + bool TryLock() V8_WARN_UNUSED_RESULT; + + // The implementation-defined native handle type. +#if V8_OS_POSIX + using NativeHandle = pthread_mutex_t; +#elif V8_OS_WIN + using NativeHandle = V8_SRWLOCK; +#elif V8_OS_STARBOARD + using NativeHandle = SbMutex; +#endif + + NativeHandle& native_handle() { + return native_handle_; + } + const NativeHandle& native_handle() const { + return native_handle_; + } + + V8_INLINE void AssertHeld() const { DCHECK_EQ(1, level_); } + V8_INLINE void AssertUnheld() const { DCHECK_EQ(0, level_); } + + private: + NativeHandle native_handle_; +#ifdef DEBUG + int level_; +#endif + + V8_INLINE void AssertHeldAndUnmark() { +#ifdef DEBUG + DCHECK_EQ(1, level_); + level_--; +#endif + } + + V8_INLINE void AssertUnheldAndMark() { +#ifdef DEBUG + DCHECK_EQ(0, level_); + level_++; +#endif + } + + friend class ConditionVariable; +}; + +// POD Mutex initialized lazily (i.e. the first time Pointer() is called). +// Usage: +// static LazyMutex my_mutex = LAZY_MUTEX_INITIALIZER; +// +// void my_function() { +// MutexGuard guard(my_mutex.Pointer()); +// // Do something. +// } +// +using LazyMutex = LazyStaticInstance, + ThreadSafeInitOnceTrait>::type; + +#define LAZY_MUTEX_INITIALIZER LAZY_STATIC_INSTANCE_INITIALIZER + +// ----------------------------------------------------------------------------- +// RecursiveMutex - a replacement for std::recursive_mutex +// +// This class is a synchronization primitive that can be used to protect shared +// data from being simultaneously accessed by multiple threads. A recursive +// mutex offers exclusive, recursive ownership semantics: +// - A calling thread owns a recursive mutex for a period of time that starts +// when it successfully calls either |Lock()| or |TryLock()|. During this +// period, the thread may make additional calls to |Lock()| or |TryLock()|. +// The period of ownership ends when the thread makes a matching number of +// calls to |Unlock()|. +// - When a thread owns a recursive mutex, all other threads will block (for +// calls to |Lock()|) or receive a |false| return value (for |TryLock()|) if +// they attempt to claim ownership of the recursive mutex. +// - The maximum number of times that a recursive mutex may be locked is +// unspecified, but after that number is reached, calls to |Lock()| will +// probably abort the process and calls to |TryLock()| return false. +// The behavior of a program is undefined if a recursive mutex is destroyed +// while still owned by some thread. The RecursiveMutex class is non-copyable. + +class V8_BASE_EXPORT RecursiveMutex final { + public: + RecursiveMutex(); + RecursiveMutex(const RecursiveMutex&) = delete; + RecursiveMutex& operator=(const RecursiveMutex&) = delete; + ~RecursiveMutex(); + + // Locks the mutex. If another thread has already locked the mutex, a call to + // |Lock()| will block execution until the lock is acquired. A thread may call + // |Lock()| on a recursive mutex repeatedly. Ownership will only be released + // after the thread makes a matching number of calls to |Unlock()|. + // The behavior is undefined if the mutex is not unlocked before being + // destroyed, i.e. some thread still owns it. + void Lock(); + + // Unlocks the mutex if its level of ownership is 1 (there was exactly one + // more call to |Lock()| than there were calls to unlock() made by this + // thread), reduces the level of ownership by 1 otherwise. The mutex must be + // locked by the current thread of execution, otherwise, the behavior is + // undefined. + void Unlock(); + + // Tries to lock the given mutex. Returns whether the mutex was + // successfully locked. + bool TryLock() V8_WARN_UNUSED_RESULT; + + V8_INLINE void AssertHeld() const { DCHECK_LT(0, level_); } + + private: + // The implementation-defined native handle type. +#if V8_OS_POSIX + using NativeHandle = pthread_mutex_t; +#elif V8_OS_WIN + using NativeHandle = V8_CRITICAL_SECTION; +#elif V8_OS_STARBOARD + using NativeHandle = starboard::RecursiveMutex; +#endif + + NativeHandle native_handle_; +#ifdef DEBUG + int level_; +#endif +}; + + +// POD RecursiveMutex initialized lazily (i.e. the first time Pointer() is +// called). +// Usage: +// static LazyRecursiveMutex my_mutex = LAZY_RECURSIVE_MUTEX_INITIALIZER; +// +// void my_function() { +// LockGuard guard(my_mutex.Pointer()); +// // Do something. +// } +// +using LazyRecursiveMutex = + LazyStaticInstance, + ThreadSafeInitOnceTrait>::type; + +#define LAZY_RECURSIVE_MUTEX_INITIALIZER LAZY_STATIC_INSTANCE_INITIALIZER + +// ---------------------------------------------------------------------------- +// SharedMutex - a replacement for std::shared_mutex +// +// This class is a synchronization primitive that can be used to protect shared +// data from being simultaneously accessed by multiple threads. In contrast to +// other mutex types which facilitate exclusive access, a shared_mutex has two +// levels of access: +// - shared: several threads can share ownership of the same mutex. +// - exclusive: only one thread can own the mutex. +// Shared mutexes are usually used in situations when multiple readers can +// access the same resource at the same time without causing data races, but +// only one writer can do so. +// The SharedMutex class is non-copyable. + +class V8_BASE_EXPORT SharedMutex final { + public: + SharedMutex(); + SharedMutex(const SharedMutex&) = delete; + SharedMutex& operator=(const SharedMutex&) = delete; + ~SharedMutex(); + + // Acquires shared ownership of the {SharedMutex}. If another thread is + // holding the mutex in exclusive ownership, a call to {LockShared()} will + // block execution until shared ownership can be acquired. + // If {LockShared()} is called by a thread that already owns the mutex in any + // mode (exclusive or shared), the behavior is undefined and outright fails + // with dchecks on. + void LockShared(); + + // Locks the SharedMutex. If another thread has already locked the mutex, a + // call to {LockExclusive()} will block execution until the lock is acquired. + // If {LockExclusive()} is called by a thread that already owns the mutex in + // any mode (shared or exclusive), the behavior is undefined and outright + // fails with dchecks on. + void LockExclusive(); + + // Releases the {SharedMutex} from shared ownership by the calling thread. + // The mutex must be locked by the current thread of execution in shared mode, + // otherwise, the behavior is undefined and outright fails with dchecks on. + void UnlockShared(); + + // Unlocks the {SharedMutex}. It must be locked by the current thread of + // execution, otherwise, the behavior is undefined and outright fails with + // dchecks on. + void UnlockExclusive(); + + // Tries to lock the {SharedMutex} in shared mode. Returns immediately. On + // successful lock acquisition returns true, otherwise returns false. + // This function is allowed to fail spuriously and return false even if the + // mutex is not currenly exclusively locked by any other thread. + // If it is called by a thread that already owns the mutex in any mode + // (shared or exclusive), the behavior is undefined, and outright fails with + // dchecks on. + bool TryLockShared() V8_WARN_UNUSED_RESULT; + + // Tries to lock the {SharedMutex}. Returns immediately. On successful lock + // acquisition returns true, otherwise returns false. + // This function is allowed to fail spuriously and return false even if the + // mutex is not currently locked by any other thread. + // If it is called by a thread that already owns the mutex in any mode + // (shared or exclusive), the behavior is undefined, and outright fails with + // dchecks on. + bool TryLockExclusive() V8_WARN_UNUSED_RESULT; + + private: + // The implementation-defined native handle type. +#if V8_OS_MACOSX + // pthread_rwlock_t is broken on MacOS when signals are being sent to the + // process (see https://crbug.com/v8/11399). Until Apple fixes that in the OS, + // we have to fall back to a non-shared mutex. + using NativeHandle = pthread_mutex_t; +#elif V8_OS_POSIX + using NativeHandle = pthread_rwlock_t; +#elif V8_OS_WIN + using NativeHandle = V8_SRWLOCK; +#elif V8_OS_STARBOARD + using NativeHandle = starboard::RWLock; +#endif + + NativeHandle native_handle_; +}; + +// ----------------------------------------------------------------------------- +// LockGuard +// +// This class is a mutex wrapper that provides a convenient RAII-style mechanism +// for owning a mutex for the duration of a scoped block. +// When a LockGuard object is created, it attempts to take ownership of the +// mutex it is given. When control leaves the scope in which the LockGuard +// object was created, the LockGuard is destructed and the mutex is released. +// The LockGuard class is non-copyable. + +// Controls whether a LockGuard always requires a valid Mutex or will just +// ignore it if it's nullptr. +enum class NullBehavior { kRequireNotNull, kIgnoreIfNull }; + +template +class V8_NODISCARD LockGuard final { + public: + explicit LockGuard(Mutex* mutex) : mutex_(mutex) { + if (has_mutex()) mutex_->Lock(); + } + LockGuard(const LockGuard&) = delete; + LockGuard& operator=(const LockGuard&) = delete; + ~LockGuard() { + if (has_mutex()) mutex_->Unlock(); + } + + private: + Mutex* const mutex_; + + bool V8_INLINE has_mutex() const { + DCHECK_IMPLIES(Behavior == NullBehavior::kRequireNotNull, + mutex_ != nullptr); + return Behavior == NullBehavior::kRequireNotNull || mutex_ != nullptr; + } +}; + +using MutexGuard = LockGuard; +using RecursiveMutexGuard = LockGuard; + +enum MutexSharedType : bool { kShared = true, kExclusive = false }; + +template +class V8_NODISCARD SharedMutexGuard final { + public: + explicit SharedMutexGuard(SharedMutex* mutex) : mutex_(mutex) { + if (!has_mutex()) return; + if (kIsShared) { + mutex_->LockShared(); + } else { + mutex_->LockExclusive(); + } + } + SharedMutexGuard(const SharedMutexGuard&) = delete; + SharedMutexGuard& operator=(const SharedMutexGuard&) = delete; + ~SharedMutexGuard() { + if (!has_mutex()) return; + if (kIsShared) { + mutex_->UnlockShared(); + } else { + mutex_->UnlockExclusive(); + } + } + + private: + SharedMutex* const mutex_; + + bool V8_INLINE has_mutex() const { + DCHECK_IMPLIES(Behavior == NullBehavior::kRequireNotNull, + mutex_ != nullptr); + return Behavior == NullBehavior::kRequireNotNull || mutex_ != nullptr; + } +}; + +template +class V8_NODISCARD SharedMutexGuardIf final { + public: + SharedMutexGuardIf(SharedMutex* mutex, bool enable_mutex) { + if (enable_mutex) mutex_.emplace(mutex); + } + SharedMutexGuardIf(const SharedMutexGuardIf&) = delete; + SharedMutexGuardIf& operator=(const SharedMutexGuardIf&) = delete; + + private: + base::Optional> mutex_; +}; + +} // namespace base +} // namespace v8 + +#endif // V8_BASE_PLATFORM_MUTEX_H_ diff --git a/Source/NativeScript/Inspector/src/base/platform/platform.h b/Source/NativeScript/Inspector/src/base/platform/platform.h new file mode 100644 index 0000000..53a7267 --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/platform/platform.h @@ -0,0 +1,600 @@ +// Copyright 2012 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This module contains the platform-specific code. This make the rest of the +// code less dependent on operating system, compilers and runtime libraries. +// This module does specifically not deal with differences between different +// processor architecture. +// The platform classes have the same definition for all platforms. The +// implementation for a particular platform is put in platform_.cc. +// The build system then uses the implementation for the target platform. +// +// This design has been chosen because it is simple and fast. Alternatively, +// the platform dependent classes could have been implemented using abstract +// superclasses with virtual methods and having specializations for each +// platform. This design was rejected because it was more complicated and +// slower. It would require factory methods for selecting the right +// implementation and the overhead of virtual methods for performance +// sensitive like mutex locking/unlocking. + +#ifndef V8_BASE_PLATFORM_PLATFORM_H_ +#define V8_BASE_PLATFORM_PLATFORM_H_ + +#include +#include +#include +#include + +#include "src/base/base-export.h" +#include "src/base/build_config.h" +#include "src/base/compiler-specific.h" +#include "src/base/optional.h" +#include "src/base/platform/mutex.h" +#include "src/base/platform/semaphore.h" + +#if V8_OS_QNX +#include "src/base/qnx-math.h" +#endif + +#if V8_OS_FUCHSIA +#include +#endif // V8_OS_FUCHSIA + +#ifdef V8_USE_ADDRESS_SANITIZER +#include +#endif // V8_USE_ADDRESS_SANITIZER + +#ifndef V8_NO_FAST_TLS +#if V8_CC_MSVC && V8_HOST_ARCH_IA32 +// __readfsdword is supposed to be declared in intrin.h but it is missing from +// some versions of that file. See https://bugs.llvm.org/show_bug.cgi?id=51188 +// And, intrin.h is a very expensive header that we want to avoid here, and +// the cheaper intrin0.h is not available for all build configurations. That is +// why we declare this intrinsic. +extern "C" unsigned long __readfsdword(unsigned long); // NOLINT(runtime/int) +#endif // V8_CC_MSVC && V8_HOST_ARCH_IA32 +#endif // V8_NO_FAST_TLS + +namespace v8 { + +namespace base { + +// ---------------------------------------------------------------------------- +// Fast TLS support + +#ifndef V8_NO_FAST_TLS + +#if V8_CC_MSVC && V8_HOST_ARCH_IA32 + +#define V8_FAST_TLS_SUPPORTED 1 + +V8_INLINE intptr_t InternalGetExistingThreadLocal(intptr_t index); + +inline intptr_t InternalGetExistingThreadLocal(intptr_t index) { + const intptr_t kTibInlineTlsOffset = 0xE10; + const intptr_t kTibExtraTlsOffset = 0xF94; + const intptr_t kMaxInlineSlots = 64; + const intptr_t kMaxSlots = kMaxInlineSlots + 1024; + const intptr_t kSystemPointerSize = sizeof(void*); + DCHECK(0 <= index && index < kMaxSlots); + USE(kMaxSlots); + if (index < kMaxInlineSlots) { + return static_cast( + __readfsdword(kTibInlineTlsOffset + kSystemPointerSize * index)); + } + intptr_t extra = static_cast(__readfsdword(kTibExtraTlsOffset)); + DCHECK_NE(extra, 0); + return *reinterpret_cast(extra + kSystemPointerSize * + (index - kMaxInlineSlots)); +} + +#elif defined(__APPLE__) && (V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64) + +// tvOS simulator does not use intptr_t as TLS key. +#if !defined(V8_OS_STARBOARD) || !defined(TARGET_OS_SIMULATOR) + +#define V8_FAST_TLS_SUPPORTED 1 + +extern V8_BASE_EXPORT intptr_t kMacTlsBaseOffset; + +V8_INLINE intptr_t InternalGetExistingThreadLocal(intptr_t index); + +inline intptr_t InternalGetExistingThreadLocal(intptr_t index) { + intptr_t result; +#if V8_HOST_ARCH_IA32 + asm("movl %%gs:(%1,%2,4), %0;" + :"=r"(result) // Output must be a writable register. + :"r"(kMacTlsBaseOffset), "r"(index)); +#else + asm("movq %%gs:(%1,%2,8), %0;" + :"=r"(result) + :"r"(kMacTlsBaseOffset), "r"(index)); +#endif + return result; +} + +#endif // !defined(V8_OS_STARBOARD) || !defined(TARGET_OS_SIMULATOR) + +#endif + +#endif // V8_NO_FAST_TLS + +class AddressSpaceReservation; +class PageAllocator; +class TimezoneCache; +class VirtualAddressSpace; +class VirtualAddressSubspace; + +// ---------------------------------------------------------------------------- +// OS +// +// This class has static methods for the different platform specific +// functions. Add methods here to cope with differences between the +// supported platforms. + +class V8_BASE_EXPORT OS { + public: + // Initialize the OS class. + // - hard_abort: If true, OS::Abort() will crash instead of aborting. + // - gc_fake_mmap: Name of the file for fake gc mmap used in ll_prof. + static void Initialize(bool hard_abort, const char* const gc_fake_mmap); + +#if V8_OS_WIN + // On Windows, ensure the newer memory API is loaded if available. This + // includes function like VirtualAlloc2 and MapViewOfFile3. + // TODO(chromium:1218005) this should probably happen as part of Initialize, + // but that is currently invoked too late, after the virtual memory cage + // is initialized. However, eventually the virtual memory cage initialization + // will happen as part of V8::Initialize, at which point this function can + // probably be merged into OS::Initialize. + static void EnsureWin32MemoryAPILoaded(); +#endif + + // Returns the accumulated user time for thread. This routine + // can be used for profiling. The implementation should + // strive for high-precision timer resolution, preferable + // micro-second resolution. + static int GetUserTime(uint32_t* secs, uint32_t* usecs); + + // Returns current time as the number of milliseconds since + // 00:00:00 UTC, January 1, 1970. + static double TimeCurrentMillis(); + + static TimezoneCache* CreateTimezoneCache(); + + // Returns last OS error. + static int GetLastError(); + + static FILE* FOpen(const char* path, const char* mode); + static bool Remove(const char* path); + + static char DirectorySeparator(); + static bool isDirectorySeparator(const char ch); + + // Opens a temporary file, the file is auto removed on close. + static FILE* OpenTemporaryFile(); + + // Log file open mode is platform-dependent due to line ends issues. + static const char* const LogFileOpenMode; + + // Print output to console. This is mostly used for debugging output. + // On platforms that has standard terminal output, the output + // should go to stdout. + static PRINTF_FORMAT(1, 2) void Print(const char* format, ...); + static PRINTF_FORMAT(1, 0) void VPrint(const char* format, va_list args); + + // Print output to a file. This is mostly used for debugging output. + static PRINTF_FORMAT(2, 3) void FPrint(FILE* out, const char* format, ...); + static PRINTF_FORMAT(2, 0) void VFPrint(FILE* out, const char* format, + va_list args); + + // Print error output to console. This is mostly used for error message + // output. On platforms that has standard terminal output, the output + // should go to stderr. + static PRINTF_FORMAT(1, 2) void PrintError(const char* format, ...); + static PRINTF_FORMAT(1, 0) void VPrintError(const char* format, va_list args); + + // Memory permissions. These should be kept in sync with the ones in + // v8::PageAllocator. + enum class MemoryPermission { + kNoAccess, + kRead, + kReadWrite, + // TODO(hpayer): Remove this flag. Memory should never be rwx. + kReadWriteExecute, + kReadExecute, + // TODO(jkummerow): Remove this when Wasm has a platform-independent + // w^x implementation. + kNoAccessWillJitLater + }; + + static bool HasLazyCommits(); + + // Sleep for a specified time interval. + static void Sleep(TimeDelta interval); + + // Abort the current process. + [[noreturn]] static void Abort(); + + // Debug break. + static void DebugBreak(); + + // Walk the stack. + static const int kStackWalkError = -1; + static const int kStackWalkMaxNameLen = 256; + static const int kStackWalkMaxTextLen = 256; + struct StackFrame { + void* address; + char text[kStackWalkMaxTextLen]; + }; + + class V8_BASE_EXPORT MemoryMappedFile { + public: + enum class FileMode { kReadOnly, kReadWrite }; + + virtual ~MemoryMappedFile() = default; + virtual void* memory() const = 0; + virtual size_t size() const = 0; + + static MemoryMappedFile* open(const char* name, + FileMode mode = FileMode::kReadWrite); + static MemoryMappedFile* create(const char* name, size_t size, + void* initial); + }; + + // Safe formatting print. Ensures that str is always null-terminated. + // Returns the number of chars written, or -1 if output was truncated. + static PRINTF_FORMAT(3, 4) int SNPrintF(char* str, int length, + const char* format, ...); + static PRINTF_FORMAT(3, 0) int VSNPrintF(char* str, int length, + const char* format, va_list args); + + static void StrNCpy(char* dest, int length, const char* src, size_t n); + + // Support for the profiler. Can do nothing, in which case ticks + // occurring in shared libraries will not be properly accounted for. + struct SharedLibraryAddress { + SharedLibraryAddress(const std::string& library_path, uintptr_t start, + uintptr_t end) + : library_path(library_path), start(start), end(end), aslr_slide(0) {} + SharedLibraryAddress(const std::string& library_path, uintptr_t start, + uintptr_t end, intptr_t aslr_slide) + : library_path(library_path), + start(start), + end(end), + aslr_slide(aslr_slide) {} + + std::string library_path; + uintptr_t start; + uintptr_t end; + intptr_t aslr_slide; + }; + + static std::vector GetSharedLibraryAddresses(); + + // Support for the profiler. Notifies the external profiling + // process that a code moving garbage collection starts. Can do + // nothing, in which case the code objects must not move (e.g., by + // using --never-compact) if accurate profiling is desired. + static void SignalCodeMovingGC(); + + // Support runtime detection of whether the hard float option of the + // EABI is used. + static bool ArmUsingHardFloat(); + + // Returns the activation frame alignment constraint or zero if + // the platform doesn't care. Guaranteed to be a power of two. + static int ActivationFrameAlignment(); + + static int GetCurrentProcessId(); + + static int GetCurrentThreadId(); + + static void AdjustSchedulingParams(); + + using Address = uintptr_t; + + struct MemoryRange { + uintptr_t start = 0; + uintptr_t end = 0; + }; + + // Find gaps between existing virtual memory ranges that have enough space + // to place a region with minimum_size within (boundary_start, boundary_end) + static std::vector GetFreeMemoryRangesWithin( + Address boundary_start, Address boundary_end, size_t minimum_size, + size_t alignment); + + [[noreturn]] static void ExitProcess(int exit_code); + + private: + // These classes use the private memory management API below. + friend class AddressSpaceReservation; + friend class MemoryMappedFile; + friend class PosixMemoryMappedFile; + friend class v8::base::PageAllocator; + friend class v8::base::VirtualAddressSpace; + friend class v8::base::VirtualAddressSubspace; + + static size_t AllocatePageSize(); + + static size_t CommitPageSize(); + + static void SetRandomMmapSeed(int64_t seed); + + static void* GetRandomMmapAddr(); + + V8_WARN_UNUSED_RESULT static void* Allocate(void* address, size_t size, + size_t alignment, + MemoryPermission access); + + V8_WARN_UNUSED_RESULT static void* AllocateShared(size_t size, + MemoryPermission access); + + V8_WARN_UNUSED_RESULT static void* RemapShared(void* old_address, + void* new_address, + size_t size); + + V8_WARN_UNUSED_RESULT static bool Free(void* address, const size_t size); + + V8_WARN_UNUSED_RESULT static bool Release(void* address, size_t size); + + V8_WARN_UNUSED_RESULT static bool SetPermissions(void* address, size_t size, + MemoryPermission access); + + V8_WARN_UNUSED_RESULT static bool DiscardSystemPages(void* address, + size_t size); + + V8_WARN_UNUSED_RESULT static bool DecommitPages(void* address, size_t size); + + V8_WARN_UNUSED_RESULT static bool CanReserveAddressSpace(); + + V8_WARN_UNUSED_RESULT static Optional + CreateAddressSpaceReservation(void* hint, size_t size, size_t alignment, + MemoryPermission max_permission); + + V8_WARN_UNUSED_RESULT static bool FreeAddressSpaceReservation( + AddressSpaceReservation reservation); + + static const int msPerSecond = 1000; + +#if V8_OS_POSIX + static const char* GetGCFakeMMapFile(); +#endif + + DISALLOW_IMPLICIT_CONSTRUCTORS(OS); +}; + +#if (defined(_WIN32) || defined(_WIN64)) +V8_BASE_EXPORT void EnsureConsoleOutputWin32(); +#endif // (defined(_WIN32) || defined(_WIN64)) + +inline void EnsureConsoleOutput() { +#if (defined(_WIN32) || defined(_WIN64)) + // Windows requires extra calls to send assert output to the console + // rather than a dialog box. + EnsureConsoleOutputWin32(); +#endif // (defined(_WIN32) || defined(_WIN64)) +} + +// ---------------------------------------------------------------------------- +// AddressSpaceReservation +// +// This class provides the same memory management functions as OS but operates +// inside a previously reserved contiguous region of virtual address space. +class V8_BASE_EXPORT AddressSpaceReservation { + public: + using Address = uintptr_t; + + void* base() const { return base_; } + size_t size() const { return size_; } + + bool Contains(void* region_addr, size_t region_size) const { + Address base = reinterpret_cast
(base_); + Address region_base = reinterpret_cast
(region_addr); + return (region_base >= base) && + ((region_base + region_size) <= (base + size_)); + } + + V8_WARN_UNUSED_RESULT bool Allocate(void* address, size_t size, + OS::MemoryPermission access); + + V8_WARN_UNUSED_RESULT bool Free(void* address, size_t size); + + V8_WARN_UNUSED_RESULT bool SetPermissions(void* address, size_t size, + OS::MemoryPermission access); + + V8_WARN_UNUSED_RESULT bool DiscardSystemPages(void* address, size_t size); + + V8_WARN_UNUSED_RESULT bool DecommitPages(void* address, size_t size); + + V8_WARN_UNUSED_RESULT Optional CreateSubReservation( + void* address, size_t size, OS::MemoryPermission max_permission); + + V8_WARN_UNUSED_RESULT static bool FreeSubReservation( + AddressSpaceReservation reservation); + +#if V8_OS_WIN + // On Windows, the placeholder mappings backing address space reservations + // need to be split and merged as page allocations can only replace an entire + // placeholder mapping, not parts of it. This must be done by the users of + // this API as it requires a RegionAllocator (or equivalent) to keep track of + // sub-regions and decide when to split and when to coalesce multiple free + // regions into a single one. + V8_WARN_UNUSED_RESULT bool SplitPlaceholder(void* address, size_t size); + V8_WARN_UNUSED_RESULT bool MergePlaceholders(void* address, size_t size); +#endif // V8_OS_WIN + + private: + friend class OS; + +#if V8_OS_FUCHSIA + AddressSpaceReservation(void* base, size_t size, zx_handle_t vmar) + : base_(base), size_(size), vmar_(vmar) {} +#else + AddressSpaceReservation(void* base, size_t size) : base_(base), size_(size) {} +#endif // V8_OS_FUCHSIA + + void* base_ = nullptr; + size_t size_ = 0; + +#if V8_OS_FUCHSIA + // On Fuchsia, address space reservations are backed by VMARs. + zx_handle_t vmar_ = ZX_HANDLE_INVALID; +#endif // V8_OS_FUCHSIA +}; + +// ---------------------------------------------------------------------------- +// Thread +// +// Thread objects are used for creating and running threads. When the start() +// method is called the new thread starts running the run() method in the new +// thread. The Thread object should not be deallocated before the thread has +// terminated. + +class V8_BASE_EXPORT Thread { + public: + // Opaque data type for thread-local storage keys. +#if V8_OS_STARBOARD + using LocalStorageKey = SbThreadLocalKey; +#else + using LocalStorageKey = int32_t; +#endif + + class Options { + public: + Options() : name_("v8:"), stack_size_(0) {} + explicit Options(const char* name, int stack_size = 0) + : name_(name), stack_size_(stack_size) {} + + const char* name() const { return name_; } + int stack_size() const { return stack_size_; } + + private: + const char* name_; + int stack_size_; + }; + + // Create new thread. + explicit Thread(const Options& options); + Thread(const Thread&) = delete; + Thread& operator=(const Thread&) = delete; + virtual ~Thread(); + + // Start new thread by calling the Run() method on the new thread. + V8_WARN_UNUSED_RESULT bool Start(); + + // Start new thread and wait until Run() method is called on the new thread. + bool StartSynchronously() { + start_semaphore_ = new Semaphore(0); + if (!Start()) return false; + start_semaphore_->Wait(); + delete start_semaphore_; + start_semaphore_ = nullptr; + return true; + } + + // Wait until thread terminates. + void Join(); + + inline const char* name() const { + return name_; + } + + // Abstract method for run handler. + virtual void Run() = 0; + + // Thread-local storage. + static LocalStorageKey CreateThreadLocalKey(); + static void DeleteThreadLocalKey(LocalStorageKey key); + static void* GetThreadLocal(LocalStorageKey key); + static void SetThreadLocal(LocalStorageKey key, void* value); + static bool HasThreadLocal(LocalStorageKey key) { + return GetThreadLocal(key) != nullptr; + } + +#ifdef V8_FAST_TLS_SUPPORTED + static inline void* GetExistingThreadLocal(LocalStorageKey key) { + void* result = reinterpret_cast( + InternalGetExistingThreadLocal(static_cast(key))); + DCHECK(result == GetThreadLocal(key)); + return result; + } +#else + static inline void* GetExistingThreadLocal(LocalStorageKey key) { + return GetThreadLocal(key); + } +#endif + + // The thread name length is limited to 16 based on Linux's implementation of + // prctl(). + static const int kMaxThreadNameLength = 16; + + class PlatformData; + PlatformData* data() { return data_; } + + void NotifyStartedAndRun() { + if (start_semaphore_) start_semaphore_->Signal(); + Run(); + } + + private: + void set_name(const char* name); + + PlatformData* data_; + + char name_[kMaxThreadNameLength]; + int stack_size_; + Semaphore* start_semaphore_; +}; + +// TODO(v8:10354): Make use of the stack utilities here in V8. +class V8_BASE_EXPORT Stack { + public: + // Convenience wrapper to use stack slots as unsigned values or void* + // pointers. + struct StackSlot { + // NOLINTNEXTLINE + StackSlot(void* value) : value(reinterpret_cast(value)) {} + StackSlot(uintptr_t value) : value(value) {} // NOLINT + + // NOLINTNEXTLINE + operator void*() const { return reinterpret_cast(value); } + operator uintptr_t() const { return value; } // NOLINT + + uintptr_t value; + }; + + // Gets the start of the stack of the current thread. + static StackSlot GetStackStart(); + + // Returns the current stack top. Works correctly with ASAN and SafeStack. + // GetCurrentStackPosition() should not be inlined, because it works on stack + // frames if it were inlined into a function with a huge stack frame it would + // return an address significantly above the actual current stack position. + static V8_NOINLINE StackSlot GetCurrentStackPosition(); + + // Returns the real stack frame if slot is part of a fake frame, and slot + // otherwise. + static StackSlot GetRealStackAddressForSlot(StackSlot slot) { +#ifdef V8_USE_ADDRESS_SANITIZER + // ASAN fetches the real stack deeper in the __asan_addr_is_in_fake_stack() + // call (precisely, deeper in __asan_stack_malloc_()), which results in a + // real frame that could be outside of stack bounds. Adjust for this + // impreciseness here. + constexpr size_t kAsanRealFrameOffsetBytes = 32; + void* real_frame = __asan_addr_is_in_fake_stack( + __asan_get_current_fake_stack(), slot, nullptr, nullptr); + return real_frame + ? (static_cast(real_frame) + kAsanRealFrameOffsetBytes) + : slot; +#endif // V8_USE_ADDRESS_SANITIZER + return slot; + } +}; + +} // namespace base +} // namespace v8 + +#endif // V8_BASE_PLATFORM_PLATFORM_H_ diff --git a/Source/NativeScript/Inspector/src/base/platform/semaphore.h b/Source/NativeScript/Inspector/src/base/platform/semaphore.h new file mode 100644 index 0000000..ec107bd --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/platform/semaphore.h @@ -0,0 +1,108 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_BASE_PLATFORM_SEMAPHORE_H_ +#define V8_BASE_PLATFORM_SEMAPHORE_H_ + +#include "src/base/base-export.h" +#include "src/base/lazy-instance.h" +#if V8_OS_WIN +#include "src/base/win32-headers.h" +#endif + +#if V8_OS_MACOSX +#include +#elif V8_OS_POSIX +#include +#endif + +#if V8_OS_STARBOARD +#include "starboard/common/semaphore.h" +#endif + +namespace v8 { +namespace base { + +// Forward declarations. +class TimeDelta; + +// ---------------------------------------------------------------------------- +// Semaphore +// +// A semaphore object is a synchronization object that maintains a count. The +// count is decremented each time a thread completes a wait for the semaphore +// object and incremented each time a thread signals the semaphore. When the +// count reaches zero, threads waiting for the semaphore blocks until the +// count becomes non-zero. + +class V8_BASE_EXPORT Semaphore final { + public: + explicit Semaphore(int count); + Semaphore(const Semaphore&) = delete; + Semaphore& operator=(const Semaphore&) = delete; + ~Semaphore(); + + // Increments the semaphore counter. + void Signal(); + + // Decrements the semaphore counter if it is positive, or blocks until it + // becomes positive and then decrements the counter. + void Wait(); + + // Like Wait() but returns after rel_time time has passed. If the timeout + // happens the return value is false and the counter is unchanged. Otherwise + // the semaphore counter is decremented and true is returned. + bool WaitFor(const TimeDelta& rel_time) V8_WARN_UNUSED_RESULT; + +#if V8_OS_MACOSX + using NativeHandle = dispatch_semaphore_t; +#elif V8_OS_POSIX + using NativeHandle = sem_t; +#elif V8_OS_WIN + using NativeHandle = HANDLE; +#elif V8_OS_STARBOARD + using NativeHandle = starboard::Semaphore; +#endif + + NativeHandle& native_handle() { + return native_handle_; + } + const NativeHandle& native_handle() const { + return native_handle_; + } + + private: + NativeHandle native_handle_; +}; + + +// POD Semaphore initialized lazily (i.e. the first time Pointer() is called). +// Usage: +// // The following semaphore starts at 0. +// static LazySemaphore<0>::type my_semaphore = LAZY_SEMAPHORE_INITIALIZER; +// +// void my_function() { +// // Do something with my_semaphore.Pointer(). +// } +// + +template +struct CreateSemaphoreTrait { + static Semaphore* Create() { + return new Semaphore(N); + } +}; + +template +struct LazySemaphore { + using typename LazyDynamicInstance, + ThreadSafeInitOnceTrait>::type; +}; + +#define LAZY_SEMAPHORE_INITIALIZER LAZY_DYNAMIC_INSTANCE_INITIALIZER + +} // namespace base +} // namespace v8 + +#endif // V8_BASE_PLATFORM_SEMAPHORE_H_ diff --git a/Source/NativeScript/Inspector/src/base/platform/time.h b/Source/NativeScript/Inspector/src/base/platform/time.h new file mode 100644 index 0000000..2fc7859 --- /dev/null +++ b/Source/NativeScript/Inspector/src/base/platform/time.h @@ -0,0 +1,513 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_BASE_PLATFORM_TIME_H_ +#define V8_BASE_PLATFORM_TIME_H_ + +#include + +#include +#include +#include + +#include "src/base/base-export.h" +#include "src/base/bits.h" +#include "src/base/macros.h" +#include "src/base/safe_conversions.h" +#if V8_OS_WIN +#include "src/base/win32-headers.h" +#endif + +// Forward declarations. +extern "C" { +struct _FILETIME; +struct mach_timespec; +struct timespec; +struct timeval; +} + +namespace v8 { +namespace base { + +class Time; +class TimeDelta; +class TimeTicks; + +namespace time_internal { +template +class TimeBase; +} // namespace time_internal + +class TimeConstants { + public: + static constexpr int64_t kHoursPerDay = 24; + static constexpr int64_t kMillisecondsPerSecond = 1000; + static constexpr int64_t kMillisecondsPerDay = + kMillisecondsPerSecond * 60 * 60 * kHoursPerDay; + static constexpr int64_t kMicrosecondsPerMillisecond = 1000; + static constexpr int64_t kMicrosecondsPerSecond = + kMicrosecondsPerMillisecond * kMillisecondsPerSecond; + static constexpr int64_t kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60; + static constexpr int64_t kMicrosecondsPerHour = kMicrosecondsPerMinute * 60; + static constexpr int64_t kMicrosecondsPerDay = + kMicrosecondsPerHour * kHoursPerDay; + static constexpr int64_t kMicrosecondsPerWeek = kMicrosecondsPerDay * 7; + static constexpr int64_t kNanosecondsPerMicrosecond = 1000; + static constexpr int64_t kNanosecondsPerSecond = + kNanosecondsPerMicrosecond * kMicrosecondsPerSecond; +}; + +// ----------------------------------------------------------------------------- +// TimeDelta +// +// This class represents a duration of time, internally represented in +// microseonds. + +class V8_BASE_EXPORT TimeDelta final { + public: + constexpr TimeDelta() : delta_(0) {} + + // Converts units of time to TimeDeltas. + static constexpr TimeDelta FromDays(int days) { + return TimeDelta(days * TimeConstants::kMicrosecondsPerDay); + } + static constexpr TimeDelta FromHours(int hours) { + return TimeDelta(hours * TimeConstants::kMicrosecondsPerHour); + } + static constexpr TimeDelta FromMinutes(int minutes) { + return TimeDelta(minutes * TimeConstants::kMicrosecondsPerMinute); + } + static constexpr TimeDelta FromSeconds(int64_t seconds) { + return TimeDelta(seconds * TimeConstants::kMicrosecondsPerSecond); + } + static constexpr TimeDelta FromMilliseconds(int64_t milliseconds) { + return TimeDelta(milliseconds * TimeConstants::kMicrosecondsPerMillisecond); + } + static constexpr TimeDelta FromMicroseconds(int64_t microseconds) { + return TimeDelta(microseconds); + } + static constexpr TimeDelta FromNanoseconds(int64_t nanoseconds) { + return TimeDelta(nanoseconds / TimeConstants::kNanosecondsPerMicrosecond); + } + + static TimeDelta FromSecondsD(double seconds) { + return FromDouble(seconds * TimeConstants::kMicrosecondsPerSecond); + } + static TimeDelta FromMillisecondsD(double milliseconds) { + return FromDouble(milliseconds * + TimeConstants::kMicrosecondsPerMillisecond); + } + + // Returns the maximum time delta, which should be greater than any reasonable + // time delta we might compare it to. Adding or subtracting the maximum time + // delta to a time or another time delta has an undefined result. + static constexpr TimeDelta Max(); + + // Returns the minimum time delta, which should be less than than any + // reasonable time delta we might compare it to. Adding or subtracting the + // minimum time delta to a time or another time delta has an undefined result. + static constexpr TimeDelta Min(); + + // Returns true if the time delta is zero. + constexpr bool IsZero() const { return delta_ == 0; } + + // Returns true if the time delta is the maximum/minimum time delta. + constexpr bool IsMax() const { + return delta_ == std::numeric_limits::max(); + } + constexpr bool IsMin() const { + return delta_ == std::numeric_limits::min(); + } + + // Returns the time delta in some unit. The F versions return a floating + // point value, the "regular" versions return a rounded-down value. + // + // InMillisecondsRoundedUp() instead returns an integer that is rounded up + // to the next full millisecond. + int InDays() const; + int InHours() const; + int InMinutes() const; + double InSecondsF() const; + int64_t InSeconds() const; + double InMillisecondsF() const; + int64_t InMilliseconds() const; + int64_t InMillisecondsRoundedUp() const; + int64_t InMicroseconds() const; + int64_t InNanoseconds() const; + + // Converts to/from Mach time specs. + static TimeDelta FromMachTimespec(struct mach_timespec ts); + struct mach_timespec ToMachTimespec() const; + + // Converts to/from POSIX time specs. + static TimeDelta FromTimespec(struct timespec ts); + struct timespec ToTimespec() const; + + // Computations with other deltas. + TimeDelta operator+(const TimeDelta& other) const { + return TimeDelta(delta_ + other.delta_); + } + TimeDelta operator-(const TimeDelta& other) const { + return TimeDelta(delta_ - other.delta_); + } + + TimeDelta& operator+=(const TimeDelta& other) { + delta_ += other.delta_; + return *this; + } + TimeDelta& operator-=(const TimeDelta& other) { + delta_ -= other.delta_; + return *this; + } + constexpr TimeDelta operator-() const { return TimeDelta(-delta_); } + + double TimesOf(const TimeDelta& other) const { + return static_cast(delta_) / static_cast(other.delta_); + } + double PercentOf(const TimeDelta& other) const { + return TimesOf(other) * 100.0; + } + + // Computations with ints, note that we only allow multiplicative operations + // with ints, and additive operations with other deltas. + TimeDelta operator*(int64_t a) const { + return TimeDelta(delta_ * a); + } + TimeDelta operator/(int64_t a) const { + return TimeDelta(delta_ / a); + } + TimeDelta& operator*=(int64_t a) { + delta_ *= a; + return *this; + } + TimeDelta& operator/=(int64_t a) { + delta_ /= a; + return *this; + } + int64_t operator/(const TimeDelta& other) const { + return delta_ / other.delta_; + } + + // Comparison operators. + constexpr bool operator==(const TimeDelta& other) const { + return delta_ == other.delta_; + } + constexpr bool operator!=(const TimeDelta& other) const { + return delta_ != other.delta_; + } + constexpr bool operator<(const TimeDelta& other) const { + return delta_ < other.delta_; + } + constexpr bool operator<=(const TimeDelta& other) const { + return delta_ <= other.delta_; + } + constexpr bool operator>(const TimeDelta& other) const { + return delta_ > other.delta_; + } + constexpr bool operator>=(const TimeDelta& other) const { + return delta_ >= other.delta_; + } + + private: + // TODO(v8:10620): constexpr requires constexpr saturated_cast. + static inline TimeDelta FromDouble(double value); + + template friend class time_internal::TimeBase; + // Constructs a delta given the duration in microseconds. This is private + // to avoid confusion by callers with an integer constructor. Use + // FromSeconds, FromMilliseconds, etc. instead. + explicit constexpr TimeDelta(int64_t delta) : delta_(delta) {} + + // Delta in microseconds. + int64_t delta_; +}; + +// static +TimeDelta TimeDelta::FromDouble(double value) { + return TimeDelta(saturated_cast(value)); +} + +// static +constexpr TimeDelta TimeDelta::Max() { + return TimeDelta(std::numeric_limits::max()); +} + +// static +constexpr TimeDelta TimeDelta::Min() { + return TimeDelta(std::numeric_limits::min()); +} + +namespace time_internal { + +// TimeBase-------------------------------------------------------------------- + +// Provides value storage and comparison/math operations common to all time +// classes. Each subclass provides for strong type-checking to ensure +// semantically meaningful comparison/math of time values from the same clock +// source or timeline. +template +class TimeBase : public TimeConstants { + public: +#if V8_OS_WIN + // To avoid overflow in QPC to Microseconds calculations, since we multiply + // by kMicrosecondsPerSecond, then the QPC value should not exceed + // (2^63 - 1) / 1E6. If it exceeds that threshold, we divide then multiply. + static constexpr int64_t kQPCOverflowThreshold = INT64_C(0x8637BD05AF7); +#endif + + // Returns true if this object has not been initialized. + // + // Warning: Be careful when writing code that performs math on time values, + // since it's possible to produce a valid "zero" result that should not be + // interpreted as a "null" value. + constexpr bool IsNull() const { return us_ == 0; } + + // Returns the maximum/minimum times, which should be greater/less than any + // reasonable time with which we might compare it. + static TimeClass Max() { + return TimeClass(std::numeric_limits::max()); + } + static TimeClass Min() { + return TimeClass(std::numeric_limits::min()); + } + + // Returns true if this object represents the maximum/minimum time. + constexpr bool IsMax() const { + return us_ == std::numeric_limits::max(); + } + constexpr bool IsMin() const { + return us_ == std::numeric_limits::min(); + } + + // For serializing only. Use FromInternalValue() to reconstitute. Please don't + // use this and do arithmetic on it, as it is more error prone than using the + // provided operators. + int64_t ToInternalValue() const { return us_; } + + // The amount of time since the origin (or "zero") point. This is a syntactic + // convenience to aid in code readability, mainly for debugging/testing use + // cases. + // + // Warning: While the Time subclass has a fixed origin point, the origin for + // the other subclasses can vary each time the application is restarted. + constexpr TimeDelta since_origin() const { + return TimeDelta::FromMicroseconds(us_); + } + + TimeClass& operator=(TimeClass other) { + us_ = other.us_; + return *(static_cast(this)); + } + + // Compute the difference between two times. + TimeDelta operator-(TimeClass other) const { + return TimeDelta::FromMicroseconds(us_ - other.us_); + } + + // Return a new time modified by some delta. + TimeClass operator+(TimeDelta delta) const { + return TimeClass(bits::SignedSaturatedAdd64(delta.delta_, us_)); + } + TimeClass operator-(TimeDelta delta) const { + return TimeClass(-bits::SignedSaturatedSub64(delta.delta_, us_)); + } + + // Modify by some time delta. + TimeClass& operator+=(TimeDelta delta) { + return static_cast(*this = (*this + delta)); + } + TimeClass& operator-=(TimeDelta delta) { + return static_cast(*this = (*this - delta)); + } + + // Comparison operators + bool operator==(TimeClass other) const { + return us_ == other.us_; + } + bool operator!=(TimeClass other) const { + return us_ != other.us_; + } + bool operator<(TimeClass other) const { + return us_ < other.us_; + } + bool operator<=(TimeClass other) const { + return us_ <= other.us_; + } + bool operator>(TimeClass other) const { + return us_ > other.us_; + } + bool operator>=(TimeClass other) const { + return us_ >= other.us_; + } + + // Converts an integer value representing TimeClass to a class. This is used + // when deserializing a |TimeClass| structure, using a value known to be + // compatible. It is not provided as a constructor because the integer type + // may be unclear from the perspective of a caller. + static TimeClass FromInternalValue(int64_t us) { return TimeClass(us); } + + protected: + explicit constexpr TimeBase(int64_t us) : us_(us) {} + + // Time value in a microsecond timebase. + int64_t us_; +}; + +} // namespace time_internal + + +// ----------------------------------------------------------------------------- +// Time +// +// This class represents an absolute point in time, internally represented as +// microseconds (s/1,000,000) since 00:00:00 UTC, January 1, 1970. + +class V8_BASE_EXPORT Time final : public time_internal::TimeBase