├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── jni-test.apk
└── jni-test
├── .gitignore
├── .idea
├── caches
│ └── build_file_checksums.ser
├── compiler.xml
├── encodings.xml
├── gradle.xml
├── misc.xml
├── runConfigurations.xml
└── vcs.xml
├── app
├── .gitignore
├── CMakeLists.txt
├── build.gradle
├── libs
│ ├── armeabi-v7a
│ │ └── libv8.a
│ └── include
│ │ ├── OWNERS
│ │ ├── libplatform
│ │ ├── libplatform-export.h
│ │ ├── libplatform.h
│ │ └── v8-tracing.h
│ │ ├── mallocdebug.h
│ │ ├── node_object_wrap.h
│ │ ├── utf8.h
│ │ ├── utf8
│ │ ├── checked.h
│ │ ├── core.h
│ │ └── unchecked.h
│ │ ├── v8-debug.h
│ │ ├── v8-experimental.h
│ │ ├── v8-inspector-protocol.h
│ │ ├── v8-inspector.h
│ │ ├── v8-internal.h
│ │ ├── v8-platform.h
│ │ ├── v8-preparser.h
│ │ ├── v8-profiler.h
│ │ ├── v8-testing.h
│ │ ├── v8-util.h
│ │ ├── v8-value-serializer-version.h
│ │ ├── v8-version-string.h
│ │ ├── v8-version.h
│ │ ├── v8-wasm-trap-handler-posix.h
│ │ ├── v8-wasm-trap-handler-win.h
│ │ ├── v8.h
│ │ ├── v8config.h
│ │ └── v8stdint.h
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── org
│ │ └── cmdr2
│ │ └── jnitest
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── cpp
│ │ └── native-lib.cpp
│ ├── java
│ │ └── org
│ │ │ └── cmdr2
│ │ │ └── jnitest
│ │ │ └── MyActivity.java
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── org
│ └── cmdr2
│ └── jnitest
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitattributes:
--------------------------------------------------------------------------------
1 | jni-test/app/libs/armeabi-v7a/libv8_base.a filter=lfs diff=lfs merge=lfs -text
2 | jni-test/app/libs/armeabi-v7a/libv8_snapshot.a filter=lfs diff=lfs merge=lfs -text
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 cmdr2
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # v8-android
2 | Example Android Studio project that embeds v8 (plus some notes on compiling v8 for android)
3 |
4 | The intention is to embed v8 inside an Android app, and this project is an example of getting "Hello World" from Javascript to show up on the Android app (using v8).
5 |
6 | **Note:** If you're building a production/real-world Android app, I recommend you use [J2V8](https://github.com/eclipsesource/J2V8) instead (unless you need to make 100s of calls/sec between JS and the runtime, in which case you should use this project's approach to avoid the [JNI overhead in J2V8](https://github.com/eclipsesource/J2V8/issues/194#issuecomment-252958734)). This project is a learning exercise, or a starting point to start a v8 binding from scratch, for higher raw performance.
7 |
8 | ## Example uses for v8 in Android
9 | I needed it for building an Android game, which used Javascript as a scripting language for modding. Other engines weren't performant-enough or embeddable. Your uses may vary.
10 |
11 | I'm sure there is room to reduce the binary size and improve things. I followed [ibon's excellent guide](https://web.archive.org/web/20211205173952/http://hyperandroid.com/2020/02/12/compile-v8-arm-arm64-ia32/), but needed to change a few things to make it work with recent changes (hence this doc).
12 |
13 | ## How to use:
14 | *Install the [jni-test.apk](https://github.com/cmdr2/v8-android/blob/master/jni-test.apk) file (~7mb) incase you only want to see it running. This apk has only been compiled for armeabi-v7a, so let me know if it doesn't work on your phone*
15 |
16 | ### In Android Studio:
17 | 1. Clone this repository, and open the `jni-test` directory as a project in your Android Studio.
18 | 2. Run the project after connecting your phone via USB.
19 |
20 | Incase it has issues, try renaming the `app/libs/armeabi-v7a` directory to your phone's ABI format, like `app/libs/arm64-v8a` and update the ABI filter in [build.grade](https://github.com/cmdr2/v8-android/blob/master/jni-test/app/build.gradle#L18) with your device's ABI format. Or maybe just edit the `app/CMakeLists.txt` file and remove the `${ANDROID_ABI}` parameter. Confirm your device's ABI (via Google?).
21 |
22 | This uses a prebuilt v8 library for Android, compiled from version 7.2.502.24 of v8 (released Jan 24, 2019). You may want to create a new binary, with the latest v8 changes.
23 |
24 | ## Files of interest:
25 | 1. The compiled APK file, if you want to try: [jni-test.apk](https://github.com/cmdr2/v8-android/blob/master/jni-test.apk) (~7mb)
26 | 2. The [CMakeLists.txt](https://github.com/cmdr2/v8-android/blob/master/jni-test/app/CMakeLists.txt) for linking the v8 libraries
27 | 3. The [native-lib.cc](https://github.com/cmdr2/v8-android/blob/master/jni-test/app/src/main/cpp/native-lib.cpp) C++ file that contains a 'Hello World' v8 program, and gets called by [MyActivity.java](https://github.com/cmdr2/v8-android/blob/master/jni-test/app/src/main/java/org/cmdr2/jnitest/MyActivity.java)
28 | 4. The v8 library binary compiled for Android from version 7.2.502.24 (released Jan 24, 2019): [libv8.a](https://github.com/cmdr2/v8-android/blob/master/jni-test/app/libs/armeabi-v7a/libv8.a).
29 |
30 | ## Here's what was done broadly:
31 | 1. Compile v8 for android_arm target
32 | 2. Manually generate the ".a" static libraries from the ".o" files using the 'ar' command. The build-generated versions weren't working for some reason.
33 | 3. Create an Android NDK project from Android Studio.
34 | 4. Copy the `include` directory from v8, and the static libraries created previously and paste into an Android project's `app/libs/armeabi-v7a/` directory.
35 | 5. Specify these libraries and include directory path in the Android project's `CMakesLists.txt` file.
36 | 6. Use v8 in the native C++ file, which gets called from the Java Android Activity via JNI.
37 |
38 | ## For compiling v8:
39 | **Tip:** Before compiling your own v8, check other repositories like [ejecta-v8](https://github.com/godmodelabs/ejecta-v8) if they have already compiled a new v8 version (and remember to copy the `include` folder as well!).
40 |
41 | 0. Build on Ubuntu (or some Linux with ELF and glibc). I was on a Mac, so I created a Virtual Machine and used Ubuntu Server for a minimal distro. Give it atleast 40 GB of disk (can use dynamic resize).
42 | 1. Follow https://github.com/v8/v8/wiki/Building-from-Source
43 | 2. But before running `v8gen.py`, first run `echo "target_os = ['android']" >> /path/to/workingDir/.gclient && gclient sync`
44 | 3. Then run `tools/dev/v8gen.py gen -m client.v8.ports -b "V8 Android Arm - builder" android_arm.release`
45 | 4. Next, run `gn args out.gn/android_arm.release` and use these flags:
46 | ```
47 | is_component_build = false
48 | is_debug = false
49 | symbol_level = 1
50 | target_cpu = "arm"
51 | target_os = "android"
52 | use_goma = false
53 | v8_android_log_stdout = true
54 | v8_static_library = true
55 | use_custom_libcxx = false
56 | use_custom_libcxx_for_host = false
57 | v8_use_external_startup_data = false
58 | ```
59 | 5. Next, run `ninja -C out.gn/android_arm.release`
60 | 6. Then create the `libv8_base.a` and `libv8_snapshot.a` static libraries manually (the built ones don't seem to work for some reason):
61 | ```
62 | mkdir libs
63 | cd libs
64 | ar -rcsD libv8_base.a /path/to/v8/out.gn/android_arm.release/obj/v8_base/*.o
65 | ar -rcsD libv8_base.a /path/to/v8/out.gn/android_arm.release/obj/v8_libbase/*.o
66 | ar -rcsD libv8_base.a /path/to/v8/out.gn/android_arm.release/obj/v8_libsampler/*.o
67 | ar -rcsD libv8_base.a /path/to/v8/out.gn/android_arm.release/obj/v8_libplatform/*.o
68 | ar -rcsD libv8_base.a /path/to/v8/out.gn/android_arm.release/obj/src/inspector/inspector/*.o
69 | ar -rcsD libv8_base.a /path/to/v8/out.gn/android_arm.release/obj/third_party/icu/icuuc/*.o
70 | ar -rcsD libv8_base.a /path/to/v8/out.gn/android_arm.release/obj/third_party/icu/icui18n/*.o
71 | ar -rcsD libv8_snapshot.a /path/to/v8/out.gn/android_arm.release/obj/v8_snapshot/*.o
72 | ```
73 | 6. Then copy the includes using `cp -R /path/to/v8/include .`
74 | 7. Now you can use these in your Android NDK project
75 |
76 | ## Using the compiled v8 binaries in an Android NDK project
77 | 1. Either create a new Android NDK project in your Android Studio, or use one that's already set up with CMake
78 | 2. Copy the `include` directory from v8, and the static libraries created previously and paste into an Android project's `app/libs/armeabi-v7a/` directory.
79 | 3. Specify these libraries and include directory path in the Android project's `CMakesLists.txt` file.
80 | 4. Use v8 in the native C++ file, which gets called from the Java Android Activity via JNI.
81 |
82 | Use the example project for the example `CMakeLists.txt` and C++ file.
83 |
84 | ## Random note
85 | The key gotcha was that the `.a` files created by the build didn't seem to work for some reason, or maybe I was messing the order. So what worked was manually combining the relevant `.o` files (base, libbase, platform, sampler, inspector, icui18n, icuuc) into libv8_base.a, and the v8_snapshot `.o` files into libv8_snapshot.a.
86 |
87 | Then the order in CMakeList was important: v8_base followed by v8_snapshot.
88 |
89 | Another thing to remember: the v8 compilation process will probably take 30 GB of disk space, and download probably 15 GB of stuff. This could be because it downloaded stuff a few times, mostly because of my sheer incompetence at compiling v8. But size your VM disk, time and patience accordingly.
90 |
--------------------------------------------------------------------------------
/jni-test.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cmdr2/v8-android/45c22ef3b523a6eb019e3b4663607e45c37bcc3d/jni-test.apk
--------------------------------------------------------------------------------
/jni-test/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/libraries
5 | /.idea/modules.xml
6 | /.idea/workspace.xml
7 | .DS_Store
8 | /build
9 | /captures
10 | .externalNativeBuild
11 |
--------------------------------------------------------------------------------
/jni-test/.idea/caches/build_file_checksums.ser:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cmdr2/v8-android/45c22ef3b523a6eb019e3b4663607e45c37bcc3d/jni-test/.idea/caches/build_file_checksums.ser
--------------------------------------------------------------------------------
/jni-test/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/jni-test/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/jni-test/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/jni-test/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/jni-test/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/jni-test/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/jni-test/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/jni-test/app/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.4.1)
2 |
3 | add_library( v8_base STATIC IMPORTED )
4 | set_target_properties( v8_base PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libv8.a )
5 |
6 | add_library( native-lib SHARED src/main/cpp/native-lib.cpp )
7 | target_include_directories( native-lib PRIVATE ${CMAKE_SOURCE_DIR}/libs/include )
8 |
9 | target_link_libraries( native-lib v8_base log )
--------------------------------------------------------------------------------
/jni-test/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 26
5 | defaultConfig {
6 | applicationId "org.cmdr2.jnitest"
7 | minSdkVersion 19
8 | targetSdkVersion 26
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | externalNativeBuild {
13 | cmake {
14 | cppFlags "-std=c++0x"
15 | }
16 | }
17 | ndk {
18 | abiFilters "armeabi-v7a"
19 | }
20 | }
21 | buildTypes {
22 | release {
23 | minifyEnabled false
24 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
25 | }
26 | }
27 | externalNativeBuild {
28 | cmake {
29 | path "CMakeLists.txt"
30 | }
31 | }
32 | }
33 |
34 | dependencies {
35 | implementation fileTree(dir: 'libs', include: ['*.jar'])
36 | implementation 'com.android.support:appcompat-v7:26.1.0'
37 | implementation 'com.android.support.constraint:constraint-layout:1.1.2'
38 | testImplementation 'junit:junit:4.12'
39 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
40 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
41 | }
42 |
--------------------------------------------------------------------------------
/jni-test/app/libs/armeabi-v7a/libv8.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cmdr2/v8-android/45c22ef3b523a6eb019e3b4663607e45c37bcc3d/jni-test/app/libs/armeabi-v7a/libv8.a
--------------------------------------------------------------------------------
/jni-test/app/libs/include/OWNERS:
--------------------------------------------------------------------------------
1 | danno@chromium.org
2 | jochen@chromium.org
--------------------------------------------------------------------------------
/jni-test/app/libs/include/libplatform/libplatform-export.h:
--------------------------------------------------------------------------------
1 | // Copyright 2016 the V8 project authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | #ifndef V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_
6 | #define V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_
7 |
8 | #if defined(_WIN32)
9 |
10 | #ifdef BUILDING_V8_PLATFORM_SHARED
11 | #define V8_PLATFORM_EXPORT __declspec(dllexport)
12 | #elif USING_V8_PLATFORM_SHARED
13 | #define V8_PLATFORM_EXPORT __declspec(dllimport)
14 | #else
15 | #define V8_PLATFORM_EXPORT
16 | #endif // BUILDING_V8_PLATFORM_SHARED
17 |
18 | #else // defined(_WIN32)
19 |
20 | // Setup for Linux shared library export.
21 | #ifdef BUILDING_V8_PLATFORM_SHARED
22 | #define V8_PLATFORM_EXPORT __attribute__((visibility("default")))
23 | #else
24 | #define V8_PLATFORM_EXPORT
25 | #endif
26 |
27 | #endif // defined(_WIN32)
28 |
29 | #endif // V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_
30 |
--------------------------------------------------------------------------------
/jni-test/app/libs/include/libplatform/libplatform.h:
--------------------------------------------------------------------------------
1 | // Copyright 2014 the V8 project authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | #ifndef V8_LIBPLATFORM_LIBPLATFORM_H_
6 | #define V8_LIBPLATFORM_LIBPLATFORM_H_
7 |
8 | #include "libplatform/libplatform-export.h"
9 | #include "libplatform/v8-tracing.h"
10 | #include "v8-platform.h" // NOLINT(build/include)
11 | #include "v8config.h" // NOLINT(build/include)
12 |
13 | namespace v8 {
14 | namespace platform {
15 |
16 | enum class IdleTaskSupport { kDisabled, kEnabled };
17 | enum class InProcessStackDumping { kDisabled, kEnabled };
18 |
19 | enum class MessageLoopBehavior : bool {
20 | kDoNotWait = false,
21 | kWaitForWork = true
22 | };
23 |
24 | /**
25 | * Returns a new instance of the default v8::Platform implementation.
26 | *
27 | * The caller will take ownership of the returned pointer. |thread_pool_size|
28 | * is the number of worker threads to allocate for background jobs. If a value
29 | * of zero is passed, a suitable default based on the current number of
30 | * processors online will be chosen.
31 | * If |idle_task_support| is enabled then the platform will accept idle
32 | * tasks (IdleTasksEnabled will return true) and will rely on the embedder
33 | * calling v8::platform::RunIdleTasks to process the idle tasks.
34 | * If |tracing_controller| is nullptr, the default platform will create a
35 | * v8::platform::TracingController instance and use it.
36 | */
37 | V8_PLATFORM_EXPORT std::unique_ptr NewDefaultPlatform(
38 | int thread_pool_size = 0,
39 | IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled,
40 | InProcessStackDumping in_process_stack_dumping =
41 | InProcessStackDumping::kEnabled,
42 | std::unique_ptr tracing_controller = {});
43 |
44 | V8_PLATFORM_EXPORT V8_DEPRECATE_SOON(
45 | "Use NewDefaultPlatform instead",
46 | v8::Platform* CreateDefaultPlatform(
47 | int thread_pool_size = 0,
48 | IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled,
49 | InProcessStackDumping in_process_stack_dumping =
50 | InProcessStackDumping::kEnabled,
51 | v8::TracingController* tracing_controller = nullptr));
52 |
53 | /**
54 | * Pumps the message loop for the given isolate.
55 | *
56 | * The caller has to make sure that this is called from the right thread.
57 | * Returns true if a task was executed, and false otherwise. Unless requested
58 | * through the |behavior| parameter, this call does not block if no task is
59 | * pending. The |platform| has to be created using |NewDefaultPlatform|.
60 | */
61 | V8_PLATFORM_EXPORT bool PumpMessageLoop(
62 | v8::Platform* platform, v8::Isolate* isolate,
63 | MessageLoopBehavior behavior = MessageLoopBehavior::kDoNotWait);
64 |
65 | V8_PLATFORM_EXPORT void EnsureEventLoopInitialized(v8::Platform* platform,
66 | v8::Isolate* isolate);
67 |
68 | /**
69 | * Runs pending idle tasks for at most |idle_time_in_seconds| seconds.
70 | *
71 | * The caller has to make sure that this is called from the right thread.
72 | * This call does not block if no task is pending. The |platform| has to be
73 | * created using |NewDefaultPlatform|.
74 | */
75 | V8_PLATFORM_EXPORT void RunIdleTasks(v8::Platform* platform,
76 | v8::Isolate* isolate,
77 | double idle_time_in_seconds);
78 |
79 | /**
80 | * Attempts to set the tracing controller for the given platform.
81 | *
82 | * The |platform| has to be created using |NewDefaultPlatform|.
83 | *
84 | */
85 | V8_PLATFORM_EXPORT V8_DEPRECATE_SOON(
86 | "Access the DefaultPlatform directly",
87 | void SetTracingController(
88 | v8::Platform* platform,
89 | v8::platform::tracing::TracingController* tracing_controller));
90 |
91 | } // namespace platform
92 | } // namespace v8
93 |
94 | #endif // V8_LIBPLATFORM_LIBPLATFORM_H_
95 |
--------------------------------------------------------------------------------
/jni-test/app/libs/include/libplatform/v8-tracing.h:
--------------------------------------------------------------------------------
1 | // Copyright 2016 the V8 project authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | #ifndef V8_LIBPLATFORM_V8_TRACING_H_
6 | #define V8_LIBPLATFORM_V8_TRACING_H_
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include "libplatform/libplatform-export.h"
14 | #include "v8-platform.h" // NOLINT(build/include)
15 |
16 | namespace v8 {
17 |
18 | namespace base {
19 | class Mutex;
20 | } // namespace base
21 |
22 | namespace platform {
23 | namespace tracing {
24 |
25 | const int kTraceMaxNumArgs = 2;
26 |
27 | class V8_PLATFORM_EXPORT TraceObject {
28 | public:
29 | union ArgValue {
30 | bool as_bool;
31 | uint64_t as_uint;
32 | int64_t as_int;
33 | double as_double;
34 | const void* as_pointer;
35 | const char* as_string;
36 | };
37 |
38 | TraceObject() {}
39 | ~TraceObject();
40 | void Initialize(
41 | char phase, const uint8_t* category_enabled_flag, const char* name,
42 | const char* scope, uint64_t id, uint64_t bind_id, int num_args,
43 | const char** arg_names, const uint8_t* arg_types,
44 | const uint64_t* arg_values,
45 | std::unique_ptr* arg_convertables,
46 | unsigned int flags, int64_t timestamp, int64_t cpu_timestamp);
47 | void UpdateDuration(int64_t timestamp, int64_t cpu_timestamp);
48 | void InitializeForTesting(
49 | char phase, const uint8_t* category_enabled_flag, const char* name,
50 | const char* scope, uint64_t id, uint64_t bind_id, int num_args,
51 | const char** arg_names, const uint8_t* arg_types,
52 | const uint64_t* arg_values,
53 | std::unique_ptr* arg_convertables,
54 | unsigned int flags, int pid, int tid, int64_t ts, int64_t tts,
55 | uint64_t duration, uint64_t cpu_duration);
56 |
57 | int pid() const { return pid_; }
58 | int tid() const { return tid_; }
59 | char phase() const { return phase_; }
60 | const uint8_t* category_enabled_flag() const {
61 | return category_enabled_flag_;
62 | }
63 | const char* name() const { return name_; }
64 | const char* scope() const { return scope_; }
65 | uint64_t id() const { return id_; }
66 | uint64_t bind_id() const { return bind_id_; }
67 | int num_args() const { return num_args_; }
68 | const char** arg_names() { return arg_names_; }
69 | uint8_t* arg_types() { return arg_types_; }
70 | ArgValue* arg_values() { return arg_values_; }
71 | std::unique_ptr* arg_convertables() {
72 | return arg_convertables_;
73 | }
74 | unsigned int flags() const { return flags_; }
75 | int64_t ts() { return ts_; }
76 | int64_t tts() { return tts_; }
77 | uint64_t duration() { return duration_; }
78 | uint64_t cpu_duration() { return cpu_duration_; }
79 |
80 | private:
81 | int pid_;
82 | int tid_;
83 | char phase_;
84 | const char* name_;
85 | const char* scope_;
86 | const uint8_t* category_enabled_flag_;
87 | uint64_t id_;
88 | uint64_t bind_id_;
89 | int num_args_ = 0;
90 | const char* arg_names_[kTraceMaxNumArgs];
91 | uint8_t arg_types_[kTraceMaxNumArgs];
92 | ArgValue arg_values_[kTraceMaxNumArgs];
93 | std::unique_ptr
94 | arg_convertables_[kTraceMaxNumArgs];
95 | char* parameter_copy_storage_ = nullptr;
96 | unsigned int flags_;
97 | int64_t ts_;
98 | int64_t tts_;
99 | uint64_t duration_;
100 | uint64_t cpu_duration_;
101 |
102 | // Disallow copy and assign
103 | TraceObject(const TraceObject&) = delete;
104 | void operator=(const TraceObject&) = delete;
105 | };
106 |
107 | class V8_PLATFORM_EXPORT TraceWriter {
108 | public:
109 | TraceWriter() {}
110 | virtual ~TraceWriter() {}
111 | virtual void AppendTraceEvent(TraceObject* trace_event) = 0;
112 | virtual void Flush() = 0;
113 |
114 | static TraceWriter* CreateJSONTraceWriter(std::ostream& stream);
115 |
116 | private:
117 | // Disallow copy and assign
118 | TraceWriter(const TraceWriter&) = delete;
119 | void operator=(const TraceWriter&) = delete;
120 | };
121 |
122 | class V8_PLATFORM_EXPORT TraceBufferChunk {
123 | public:
124 | explicit TraceBufferChunk(uint32_t seq);
125 |
126 | void Reset(uint32_t new_seq);
127 | bool IsFull() const { return next_free_ == kChunkSize; }
128 | TraceObject* AddTraceEvent(size_t* event_index);
129 | TraceObject* GetEventAt(size_t index) { return &chunk_[index]; }
130 |
131 | uint32_t seq() const { return seq_; }
132 | size_t size() const { return next_free_; }
133 |
134 | static const size_t kChunkSize = 64;
135 |
136 | private:
137 | size_t next_free_ = 0;
138 | TraceObject chunk_[kChunkSize];
139 | uint32_t seq_;
140 |
141 | // Disallow copy and assign
142 | TraceBufferChunk(const TraceBufferChunk&) = delete;
143 | void operator=(const TraceBufferChunk&) = delete;
144 | };
145 |
146 | class V8_PLATFORM_EXPORT TraceBuffer {
147 | public:
148 | TraceBuffer() {}
149 | virtual ~TraceBuffer() {}
150 |
151 | virtual TraceObject* AddTraceEvent(uint64_t* handle) = 0;
152 | virtual TraceObject* GetEventByHandle(uint64_t handle) = 0;
153 | virtual bool Flush() = 0;
154 |
155 | static const size_t kRingBufferChunks = 1024;
156 |
157 | static TraceBuffer* CreateTraceBufferRingBuffer(size_t max_chunks,
158 | TraceWriter* trace_writer);
159 |
160 | private:
161 | // Disallow copy and assign
162 | TraceBuffer(const TraceBuffer&) = delete;
163 | void operator=(const TraceBuffer&) = delete;
164 | };
165 |
166 | // Options determines how the trace buffer stores data.
167 | enum TraceRecordMode {
168 | // Record until the trace buffer is full.
169 | RECORD_UNTIL_FULL,
170 |
171 | // Record until the user ends the trace. The trace buffer is a fixed size
172 | // and we use it as a ring buffer during recording.
173 | RECORD_CONTINUOUSLY,
174 |
175 | // Record until the trace buffer is full, but with a huge buffer size.
176 | RECORD_AS_MUCH_AS_POSSIBLE,
177 |
178 | // Echo to console. Events are discarded.
179 | ECHO_TO_CONSOLE,
180 | };
181 |
182 | class V8_PLATFORM_EXPORT TraceConfig {
183 | public:
184 | typedef std::vector StringList;
185 |
186 | static TraceConfig* CreateDefaultTraceConfig();
187 |
188 | TraceConfig() : enable_systrace_(false), enable_argument_filter_(false) {}
189 | TraceRecordMode GetTraceRecordMode() const { return record_mode_; }
190 | bool IsSystraceEnabled() const { return enable_systrace_; }
191 | bool IsArgumentFilterEnabled() const { return enable_argument_filter_; }
192 |
193 | void SetTraceRecordMode(TraceRecordMode mode) { record_mode_ = mode; }
194 | void EnableSystrace() { enable_systrace_ = true; }
195 | void EnableArgumentFilter() { enable_argument_filter_ = true; }
196 |
197 | void AddIncludedCategory(const char* included_category);
198 |
199 | bool IsCategoryGroupEnabled(const char* category_group) const;
200 |
201 | private:
202 | TraceRecordMode record_mode_;
203 | bool enable_systrace_ : 1;
204 | bool enable_argument_filter_ : 1;
205 | StringList included_categories_;
206 |
207 | // Disallow copy and assign
208 | TraceConfig(const TraceConfig&) = delete;
209 | void operator=(const TraceConfig&) = delete;
210 | };
211 |
212 | #if defined(_MSC_VER)
213 | #define V8_PLATFORM_NON_EXPORTED_BASE(code) \
214 | __pragma(warning(suppress : 4275)) code
215 | #else
216 | #define V8_PLATFORM_NON_EXPORTED_BASE(code) code
217 | #endif // defined(_MSC_VER)
218 |
219 | class V8_PLATFORM_EXPORT TracingController
220 | : public V8_PLATFORM_NON_EXPORTED_BASE(v8::TracingController) {
221 | public:
222 | enum Mode { DISABLED = 0, RECORDING_MODE };
223 |
224 | // The pointer returned from GetCategoryGroupEnabledInternal() points to a
225 | // value with zero or more of the following bits. Used in this class only.
226 | // The TRACE_EVENT macros should only use the value as a bool.
227 | // These values must be in sync with macro values in TraceEvent.h in Blink.
228 | enum CategoryGroupEnabledFlags {
229 | // Category group enabled for the recording mode.
230 | ENABLED_FOR_RECORDING = 1 << 0,
231 | // Category group enabled by SetEventCallbackEnabled().
232 | ENABLED_FOR_EVENT_CALLBACK = 1 << 2,
233 | // Category group enabled to export events to ETW.
234 | ENABLED_FOR_ETW_EXPORT = 1 << 3
235 | };
236 |
237 | TracingController();
238 | ~TracingController() override;
239 | void Initialize(TraceBuffer* trace_buffer);
240 |
241 | // v8::TracingController implementation.
242 | const uint8_t* GetCategoryGroupEnabled(const char* category_group) override;
243 | uint64_t AddTraceEvent(
244 | char phase, const uint8_t* category_enabled_flag, const char* name,
245 | const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
246 | const char** arg_names, const uint8_t* arg_types,
247 | const uint64_t* arg_values,
248 | std::unique_ptr* arg_convertables,
249 | unsigned int flags) override;
250 | uint64_t AddTraceEventWithTimestamp(
251 | char phase, const uint8_t* category_enabled_flag, const char* name,
252 | const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
253 | const char** arg_names, const uint8_t* arg_types,
254 | const uint64_t* arg_values,
255 | std::unique_ptr* arg_convertables,
256 | unsigned int flags, int64_t timestamp) override;
257 | void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
258 | const char* name, uint64_t handle) override;
259 | void AddTraceStateObserver(
260 | v8::TracingController::TraceStateObserver* observer) override;
261 | void RemoveTraceStateObserver(
262 | v8::TracingController::TraceStateObserver* observer) override;
263 |
264 | void StartTracing(TraceConfig* trace_config);
265 | void StopTracing();
266 |
267 | static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag);
268 |
269 | protected:
270 | virtual int64_t CurrentTimestampMicroseconds();
271 | virtual int64_t CurrentCpuTimestampMicroseconds();
272 |
273 | private:
274 | const uint8_t* GetCategoryGroupEnabledInternal(const char* category_group);
275 | void UpdateCategoryGroupEnabledFlag(size_t category_index);
276 | void UpdateCategoryGroupEnabledFlags();
277 |
278 | std::unique_ptr trace_buffer_;
279 | std::unique_ptr trace_config_;
280 | std::unique_ptr mutex_;
281 | std::unordered_set observers_;
282 | Mode mode_ = DISABLED;
283 |
284 | // Disallow copy and assign
285 | TracingController(const TracingController&) = delete;
286 | void operator=(const TracingController&) = delete;
287 | };
288 |
289 | #undef V8_PLATFORM_NON_EXPORTED_BASE
290 |
291 | } // namespace tracing
292 | } // namespace platform
293 | } // namespace v8
294 |
295 | #endif // V8_LIBPLATFORM_V8_TRACING_H_
296 |
--------------------------------------------------------------------------------
/jni-test/app/libs/include/mallocdebug.h:
--------------------------------------------------------------------------------
1 | #ifndef __MALLOCDEBUG_H
2 | #define __MALLOCDEBUG_H 1
3 |
4 | #include
5 | #include
6 |
7 | // v8::Persistent* __debugPersistentAllocObject(v8::Isolate* isolate, v8::Local *data, const char* file, int line, const char* func);
8 | // v8::Persistent* __debugPersistentAllocFunction(v8::Isolate* isolate, v8::Local *data, const char* file, int line, const char* func);
9 |
10 | /*
11 | #define malloc(x) myMalloc(x, __FILE__,__LINE__,__func__)
12 | #define free(x) myFree(x, __FILE__,__LINE__,__func__)
13 | #define memset(x, y, z) myMemset (x, y, z, __FILE__,__LINE__,__func__)
14 | #define strdup(x) myStrDup(x, __FILE__,__LINE__,__func__)
15 | #define realloc(x, y) myRealloc(x, y, __FILE__,__LINE__,__func__)
16 | #define memcpy(x, y, z) myMemcpy(x, y, z, __FILE__,__LINE__,__func__) */
17 | // #define bcopy(x, y, z) myBcopy(x, y, z, __FILE__,__LINE__,__func__)
18 | // #define strcpy
19 |
20 | #undef DEBUG_MALLOC
21 |
22 | #ifdef DEBUG_MALLOC
23 |
24 | #define BGJS_RESET_PERSISTENT(isolate, pers, data) LOGD("BGJS_PERS_RESET %p file %s line %i func %s", &pers, __FILE__, __LINE__, __func__); \
25 | pers.Reset(isolate, data); \
26 | LOGD("BGJS_PERS_NEW %p file %s line %i func %s", &pers, __FILE__, __LINE__, __func__);
27 |
28 | #define BGJS_NEW_PERSISTENT_PTR(persistent) LOGD("BGJS_PERS_NEW_PTR %p file %s line %i func %s", persistent, __FILE__, __LINE__, __func__);
29 | #define BGJS_NEW_PERSISTENT(persistent) LOGD("BGJS_PERS_NEW %p file %s line %i func %s", &persistent, __FILE__, __LINE__, __func__);
30 |
31 | #define BGJS_CLEAR_PERSISTENT(pers) if (!pers.IsEmpty()) { \
32 | LOGD("BGJS_PERS_RESET %p file %s line %i func %s", &pers, __FILE__, __LINE__, __func__); \
33 | pers.Reset(); \
34 | }
35 |
36 | #define BGJS_CLEAR_PERSISTENT_PTR(pers) if (!pers->IsEmpty()) { \
37 | LOGD("BGJS_PERS_RESET %p file %s line %i func %s", pers, __FILE__, __LINE__, __func__); \
38 | pers->Reset(); \
39 | }
40 |
41 | #else
42 | #define BGJS_RESET_PERSISTENT(isolate, pers, data) pers.Reset(isolate, data);
43 |
44 | #define BGJS_NEW_PERSISTENT_PTR(persistent)
45 | #define BGJS_NEW_PERSISTENT(persistent)
46 |
47 | #define BGJS_CLEAR_PERSISTENT(pers) pers.Reset();
48 |
49 | #define BGJS_CLEAR_PERSISTENT_PTR(pers) if (pers && !pers->IsEmpty()) { pers->Reset(); }
50 | #endif
51 |
52 |
53 | void myFree(void* ptr, const char* file, int line, const char* func);
54 | void* myMalloc (size_t size, const char* file, int line, const char* func);
55 | void* myMemset (void* ptr, int value, size_t num, const char* file, int line, const char* func);
56 | char* myStrDup (const char* str, const char* file, int line, const char* func);
57 | void* myRealloc (void* ptr, size_t size, const char* file, int line, const char* func);
58 | void* myMemcpy ( void * destination, const void * source, size_t num, const char* file, int line, const char* func);
59 | // void* myBcopy ( const void *src, const void *dest, size_t num, const char* file, int line, const char* func);
60 |
61 | #endif
62 |
--------------------------------------------------------------------------------
/jni-test/app/libs/include/node_object_wrap.h:
--------------------------------------------------------------------------------
1 | // Copyright Joyent, Inc. and other Node contributors.
2 | //
3 | // Permission is hereby granted, free of charge, to any person obtaining a
4 | // copy of this software and associated documentation files (the
5 | // "Software"), to deal in the Software without restriction, including
6 | // without limitation the rights to use, copy, modify, merge, publish,
7 | // distribute, sublicense, and/or sell copies of the Software, and to permit
8 | // persons to whom the Software is furnished to do so, subject to the
9 | // following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included
12 | // in all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 | // USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | #ifndef object_wrap_h
23 | #define object_wrap_h
24 |
25 | #include
26 | #include
27 |
28 | namespace node {
29 |
30 | class ObjectWrap {
31 | public:
32 | ObjectWrap ( ) {
33 | refs_ = 0;
34 | }
35 |
36 |
37 | virtual ~ObjectWrap ( ) {
38 | if (!handle_.IsEmpty()) {
39 | assert(handle_.IsNearDeath());
40 | handle_.ClearWeak();
41 | handle_->SetInternalField(0, v8::Undefined());
42 | handle_.Dispose();
43 | handle_.Clear();
44 | }
45 | }
46 |
47 |
48 | template
49 | static inline T* Unwrap (v8::Handle handle) {
50 | assert(!handle.IsEmpty());
51 | assert(handle->InternalFieldCount() > 0);
52 | return static_cast(handle->GetPointerFromInternalField(0));
53 | }
54 |
55 |
56 | v8::Persistent handle_; // ro
57 |
58 | protected:
59 | inline void Wrap (v8::Handle handle) {
60 | assert(handle_.IsEmpty());
61 | assert(handle->InternalFieldCount() > 0);
62 | handle_ = v8::Persistent::New(handle);
63 | handle_->SetPointerInInternalField(0, this);
64 | MakeWeak();
65 | }
66 |
67 |
68 | inline void MakeWeak (void) {
69 | handle_.MakeWeak(this, WeakCallback);
70 | handle_.MarkIndependent();
71 | }
72 |
73 | /* Ref() marks the object as being attached to an event loop.
74 | * Refed objects will not be garbage collected, even if
75 | * all references are lost.
76 | */
77 | virtual void Ref() {
78 | assert(!handle_.IsEmpty());
79 | refs_++;
80 | handle_.ClearWeak();
81 | }
82 |
83 | /* Unref() marks an object as detached from the event loop. This is its
84 | * default state. When an object with a "weak" reference changes from
85 | * attached to detached state it will be freed. Be careful not to access
86 | * the object after making this call as it might be gone!
87 | * (A "weak reference" means an object that only has a
88 | * persistant handle.)
89 | *
90 | * DO NOT CALL THIS FROM DESTRUCTOR
91 | */
92 | virtual void Unref() {
93 | assert(!handle_.IsEmpty());
94 | assert(!handle_.IsWeak());
95 | assert(refs_ > 0);
96 | if (--refs_ == 0) { MakeWeak(); }
97 | }
98 |
99 |
100 | int refs_; // ro
101 |
102 |
103 | private:
104 | static void WeakCallback (v8::Persistent value, void *data) {
105 | ObjectWrap *obj = static_cast(data);
106 | assert(value == obj->handle_);
107 | assert(!obj->refs_);
108 | assert(value.IsNearDeath());
109 | delete obj;
110 | }
111 | };
112 |
113 | } // namespace node
114 | #endif // object_wrap_h
115 |
--------------------------------------------------------------------------------
/jni-test/app/libs/include/utf8.h:
--------------------------------------------------------------------------------
1 | // Copyright 2006 Nemanja Trifunovic
2 |
3 | /*
4 | Permission is hereby granted, free of charge, to any person or organization
5 | obtaining a copy of the software and accompanying documentation covered by
6 | this license (the "Software") to use, reproduce, display, distribute,
7 | execute, and transmit the Software, and to prepare derivative works of the
8 | Software, and to permit third-parties to whom the Software is furnished to
9 | do so, all subject to the following:
10 |
11 | The copyright notices in the Software and this entire statement, including
12 | the above license grant, this restriction and the following disclaimer,
13 | must be included in all copies of the Software, in whole or in part, and
14 | all derivative works of the Software, unless such copies or derivative
15 | works are solely in the form of machine-executable object code generated by
16 | a source language processor.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 | DEALINGS IN THE SOFTWARE.
25 | */
26 |
27 |
28 | #ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
29 | #define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
30 |
31 | #include "utf8/checked.h"
32 | #include "utf8/unchecked.h"
33 |
34 | #endif // header guard
35 |
--------------------------------------------------------------------------------
/jni-test/app/libs/include/utf8/checked.h:
--------------------------------------------------------------------------------
1 | // Copyright 2006 Nemanja Trifunovic
2 |
3 | /*
4 | Permission is hereby granted, free of charge, to any person or organization
5 | obtaining a copy of the software and accompanying documentation covered by
6 | this license (the "Software") to use, reproduce, display, distribute,
7 | execute, and transmit the Software, and to prepare derivative works of the
8 | Software, and to permit third-parties to whom the Software is furnished to
9 | do so, all subject to the following:
10 |
11 | The copyright notices in the Software and this entire statement, including
12 | the above license grant, this restriction and the following disclaimer,
13 | must be included in all copies of the Software, in whole or in part, and
14 | all derivative works of the Software, unless such copies or derivative
15 | works are solely in the form of machine-executable object code generated by
16 | a source language processor.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 | DEALINGS IN THE SOFTWARE.
25 | */
26 |
27 |
28 | #ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
29 | #define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
30 |
31 | #include "core.h"
32 | #include
33 |
34 | namespace utf8
35 | {
36 | // Base for the exceptions that may be thrown from the library
37 | class exception : public ::std::exception {
38 | };
39 |
40 | // Exceptions that may be thrown from the library functions.
41 | class invalid_code_point : public exception {
42 | uint32_t cp;
43 | public:
44 | invalid_code_point(uint32_t cp) : cp(cp) {}
45 | virtual const char* what() const throw() { return "Invalid code point"; }
46 | uint32_t code_point() const {return cp;}
47 | };
48 |
49 | class invalid_utf8 : public exception {
50 | uint8_t u8;
51 | public:
52 | invalid_utf8 (uint8_t u) : u8(u) {}
53 | virtual const char* what() const throw() { return "Invalid UTF-8"; }
54 | uint8_t utf8_octet() const {return u8;}
55 | };
56 |
57 | class invalid_utf16 : public exception {
58 | uint16_t u16;
59 | public:
60 | invalid_utf16 (uint16_t u) : u16(u) {}
61 | virtual const char* what() const throw() { return "Invalid UTF-16"; }
62 | uint16_t utf16_word() const {return u16;}
63 | };
64 |
65 | class not_enough_room : public exception {
66 | public:
67 | virtual const char* what() const throw() { return "Not enough space"; }
68 | };
69 |
70 | /// The library API - functions intended to be called by the users
71 |
72 | template
73 | octet_iterator append(uint32_t cp, octet_iterator result)
74 | {
75 | if (!utf8::internal::is_code_point_valid(cp))
76 | return NULL;
77 |
78 | if (cp < 0x80) // one octet
79 | *(result++) = static_cast(cp);
80 | else if (cp < 0x800) { // two octets
81 | *(result++) = static_cast((cp >> 6) | 0xc0);
82 | *(result++) = static_cast((cp & 0x3f) | 0x80);
83 | }
84 | else if (cp < 0x10000) { // three octets
85 | *(result++) = static_cast((cp >> 12) | 0xe0);
86 | *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80);
87 | *(result++) = static_cast((cp & 0x3f) | 0x80);
88 | }
89 | else { // four octets
90 | *(result++) = static_cast((cp >> 18) | 0xf0);
91 | *(result++) = static_cast(((cp >> 12) & 0x3f) | 0x80);
92 | *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80);
93 | *(result++) = static_cast((cp & 0x3f) | 0x80);
94 | }
95 | return result;
96 | }
97 |
98 | template
99 | output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)
100 | {
101 | while (start != end) {
102 | octet_iterator sequence_start = start;
103 | internal::utf_error err_code = utf8::internal::validate_next(start, end);
104 | switch (err_code) {
105 | case internal::UTF8_OK :
106 | for (octet_iterator it = sequence_start; it != start; ++it)
107 | *out++ = *it;
108 | break;
109 | case internal::NOT_ENOUGH_ROOM:
110 | // throw not_enough_room();
111 | return NULL;
112 | case internal::INVALID_LEAD:
113 | utf8::append (replacement, out);
114 | ++start;
115 | break;
116 | case internal::INCOMPLETE_SEQUENCE:
117 | case internal::OVERLONG_SEQUENCE:
118 | case internal::INVALID_CODE_POINT:
119 | utf8::append (replacement, out);
120 | ++start;
121 | // just one replacement mark for the sequence
122 | while (start != end && utf8::internal::is_trail(*start))
123 | ++start;
124 | break;
125 | }
126 | }
127 | return out;
128 | }
129 |
130 | template
131 | inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out)
132 | {
133 | static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd);
134 | return utf8::replace_invalid(start, end, out, replacement_marker);
135 | }
136 |
137 | template
138 | uint32_t next(octet_iterator& it, octet_iterator end)
139 | {
140 | uint32_t cp = 0;
141 | internal::utf_error err_code = utf8::internal::validate_next(it, end, cp);
142 | /* switch (err_code) {
143 | case internal::UTF8_OK :
144 | break;
145 | case internal::NOT_ENOUGH_ROOM :
146 | throw not_enough_room();
147 | case internal::INVALID_LEAD :
148 | case internal::INCOMPLETE_SEQUENCE :
149 | case internal::OVERLONG_SEQUENCE :
150 | throw invalid_utf8(*it);
151 | case internal::INVALID_CODE_POINT :
152 | throw invalid_code_point(cp);
153 | } */
154 | return cp;
155 | }
156 |
157 | template
158 | uint32_t peek_next(octet_iterator it, octet_iterator end)
159 | {
160 | return utf8::next(it, end);
161 | }
162 |
163 | template
164 | uint32_t prior(octet_iterator& it, octet_iterator start)
165 | {
166 | // can't do much if it == start
167 | if (it == start)
168 | // throw not_enough_room();
169 | return NULL;
170 |
171 | octet_iterator end = it;
172 | // Go back until we hit either a lead octet or start
173 | while (utf8::internal::is_trail(*(--it)))
174 | if (it == start)
175 | return NULL;
176 | // throw invalid_utf8(*it); // error - no lead byte in the sequence
177 | return utf8::peek_next(it, end);
178 | }
179 |
180 | /// Deprecated in versions that include "prior"
181 | template
182 | uint32_t previous(octet_iterator& it, octet_iterator pass_start)
183 | {
184 | octet_iterator end = it;
185 | while (utf8::internal::is_trail(*(--it)))
186 | if (it == pass_start)
187 | // throw invalid_utf8(*it); // error - no lead byte in the sequence
188 | return 0;
189 | octet_iterator temp = it;
190 | return utf8::next(temp, end);
191 | }
192 |
193 | template
194 | void advance (octet_iterator& it, distance_type n, octet_iterator end)
195 | {
196 | for (distance_type i = 0; i < n; ++i)
197 | utf8::next(it, end);
198 | }
199 |
200 | template
201 | typename std::iterator_traits::difference_type
202 | distance (octet_iterator first, octet_iterator last)
203 | {
204 | typename std::iterator_traits::difference_type dist;
205 | for (dist = 0; first < last; ++dist)
206 | utf8::next(first, last);
207 | return dist;
208 | }
209 |
210 | template
211 | octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
212 | {
213 | while (start != end) {
214 | uint32_t cp = utf8::internal::mask16(*start++);
215 | // Take care of surrogate pairs first
216 | if (utf8::internal::is_lead_surrogate(cp)) {
217 | if (start != end) {
218 | uint32_t trail_surrogate = utf8::internal::mask16(*start++);
219 | if (utf8::internal::is_trail_surrogate(trail_surrogate))
220 | cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
221 | else
222 | // throw invalid_utf16(static_cast(trail_surrogate));
223 | return NULL;
224 | }
225 | else
226 | // throw invalid_utf16(static_cast(cp));
227 | return NULL;
228 |
229 | }
230 | // Lone trail surrogate
231 | else if (utf8::internal::is_trail_surrogate(cp))
232 | // throw invalid_utf16(static_cast(cp));
233 | return NULL;
234 |
235 | result = utf8::append(cp, result);
236 | }
237 | return result;
238 | }
239 |
240 | template
241 | u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
242 | {
243 | while (start != end) {
244 | uint32_t cp = utf8::next(start, end);
245 | if (cp > 0xffff) { //make a surrogate pair
246 | *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET);
247 | *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
248 | }
249 | else
250 | *result++ = static_cast(cp);
251 | }
252 | return result;
253 | }
254 |
255 | template
256 | octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
257 | {
258 | while (start != end)
259 | result = utf8::append(*(start++), result);
260 |
261 | return result;
262 | }
263 |
264 | template
265 | u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
266 | {
267 | while (start != end)
268 | (*result++) = utf8::next(start, end);
269 |
270 | return result;
271 | }
272 |
273 | // The iterator class
274 | template
275 | class iterator : public std::iterator {
276 | octet_iterator it;
277 | octet_iterator range_start;
278 | octet_iterator range_end;
279 | public:
280 | iterator () {};
281 | explicit iterator (const octet_iterator& octet_it,
282 | const octet_iterator& range_start,
283 | const octet_iterator& range_end) :
284 | it(octet_it), range_start(range_start), range_end(range_end)
285 | {
286 | // if (it < range_start || it > range_end)
287 | // throw std::out_of_range("Invalid utf-8 iterator position");
288 | }
289 | // the default "big three" are OK
290 | octet_iterator base () const { return it; }
291 | uint32_t operator * () const
292 | {
293 | octet_iterator temp = it;
294 | return utf8::next(temp, range_end);
295 | }
296 | bool operator == (const iterator& rhs) const
297 | {
298 | // if (range_start != rhs.range_start || range_end != rhs.range_end)
299 | // throw std::logic_error("Comparing utf-8 iterators defined with different ranges");
300 | return (it == rhs.it);
301 | }
302 | bool operator != (const iterator& rhs) const
303 | {
304 | return !(operator == (rhs));
305 | }
306 | iterator& operator ++ ()
307 | {
308 | utf8::next(it, range_end);
309 | return *this;
310 | }
311 | iterator operator ++ (int)
312 | {
313 | iterator temp = *this;
314 | utf8::next(it, range_end);
315 | return temp;
316 | }
317 | iterator& operator -- ()
318 | {
319 | utf8::prior(it, range_start);
320 | return *this;
321 | }
322 | iterator operator -- (int)
323 | {
324 | iterator temp = *this;
325 | utf8::prior(it, range_start);
326 | return temp;
327 | }
328 | }; // class iterator
329 |
330 | } // namespace utf8
331 |
332 | #endif //header guard
333 |
334 |
335 |
--------------------------------------------------------------------------------
/jni-test/app/libs/include/utf8/core.h:
--------------------------------------------------------------------------------
1 | // Copyright 2006 Nemanja Trifunovic
2 |
3 | /*
4 | Permission is hereby granted, free of charge, to any person or organization
5 | obtaining a copy of the software and accompanying documentation covered by
6 | this license (the "Software") to use, reproduce, display, distribute,
7 | execute, and transmit the Software, and to prepare derivative works of the
8 | Software, and to permit third-parties to whom the Software is furnished to
9 | do so, all subject to the following:
10 |
11 | The copyright notices in the Software and this entire statement, including
12 | the above license grant, this restriction and the following disclaimer,
13 | must be included in all copies of the Software, in whole or in part, and
14 | all derivative works of the Software, unless such copies or derivative
15 | works are solely in the form of machine-executable object code generated by
16 | a source language processor.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 | DEALINGS IN THE SOFTWARE.
25 | */
26 |
27 |
28 | #ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
29 | #define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
30 |
31 | #include
32 |
33 | namespace utf8
34 | {
35 | // The typedefs for 8-bit, 16-bit and 32-bit unsigned integers
36 | // You may need to change them to match your system.
37 | // These typedefs have the same names as ones from cstdint, or boost/cstdint
38 | typedef unsigned char uint8_t;
39 | typedef unsigned short uint16_t;
40 | typedef unsigned int uint32_t;
41 |
42 | // Helper code - not intended to be directly called by the library users. May be changed at any time
43 | namespace internal
44 | {
45 | // Unicode constants
46 | // Leading (high) surrogates: 0xd800 - 0xdbff
47 | // Trailing (low) surrogates: 0xdc00 - 0xdfff
48 | const uint16_t LEAD_SURROGATE_MIN = 0xd800u;
49 | const uint16_t LEAD_SURROGATE_MAX = 0xdbffu;
50 | const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u;
51 | const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu;
52 | const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10);
53 | const uint32_t SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN;
54 |
55 | // Maximum valid value for a Unicode code point
56 | const uint32_t CODE_POINT_MAX = 0x0010ffffu;
57 |
58 | template
59 | inline uint8_t mask8(octet_type oc)
60 | {
61 | return static_cast(0xff & oc);
62 | }
63 | template
64 | inline uint16_t mask16(u16_type oc)
65 | {
66 | return static_cast(0xffff & oc);
67 | }
68 | template
69 | inline bool is_trail(octet_type oc)
70 | {
71 | return ((utf8::internal::mask8(oc) >> 6) == 0x2);
72 | }
73 |
74 | template
75 | inline bool is_lead_surrogate(u16 cp)
76 | {
77 | return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX);
78 | }
79 |
80 | template
81 | inline bool is_trail_surrogate(u16 cp)
82 | {
83 | return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
84 | }
85 |
86 | template
87 | inline bool is_surrogate(u16 cp)
88 | {
89 | return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
90 | }
91 |
92 | template
93 | inline bool is_code_point_valid(u32 cp)
94 | {
95 | return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp));
96 | }
97 |
98 | template
99 | inline typename std::iterator_traits::difference_type
100 | sequence_length(octet_iterator lead_it)
101 | {
102 | uint8_t lead = utf8::internal::mask8(*lead_it);
103 | if (lead < 0x80)
104 | return 1;
105 | else if ((lead >> 5) == 0x6)
106 | return 2;
107 | else if ((lead >> 4) == 0xe)
108 | return 3;
109 | else if ((lead >> 3) == 0x1e)
110 | return 4;
111 | else
112 | return 0;
113 | }
114 |
115 | template
116 | inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length)
117 | {
118 | if (cp < 0x80) {
119 | if (length != 1)
120 | return true;
121 | }
122 | else if (cp < 0x800) {
123 | if (length != 2)
124 | return true;
125 | }
126 | else if (cp < 0x10000) {
127 | if (length != 3)
128 | return true;
129 | }
130 |
131 | return false;
132 | }
133 |
134 | enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT};
135 |
136 | /// Helper for get_sequence_x
137 | template
138 | utf_error increase_safely(octet_iterator& it, octet_iterator end)
139 | {
140 | if (++it == end)
141 | return NOT_ENOUGH_ROOM;
142 |
143 | if (!utf8::internal::is_trail(*it))
144 | return INCOMPLETE_SEQUENCE;
145 |
146 | return UTF8_OK;
147 | }
148 |
149 | #define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;}
150 |
151 | /// get_sequence_x functions decode utf-8 sequences of the length x
152 | template
153 | utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point)
154 | {
155 | if (it == end)
156 | return NOT_ENOUGH_ROOM;
157 |
158 | code_point = utf8::internal::mask8(*it);
159 |
160 | return UTF8_OK;
161 | }
162 |
163 | template
164 | utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point)
165 | {
166 | if (it == end)
167 | return NOT_ENOUGH_ROOM;
168 |
169 | code_point = utf8::internal::mask8(*it);
170 |
171 | UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
172 |
173 | code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f);
174 |
175 | return UTF8_OK;
176 | }
177 |
178 | template
179 | utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point)
180 | {
181 | if (it == end)
182 | return NOT_ENOUGH_ROOM;
183 |
184 | code_point = utf8::internal::mask8(*it);
185 |
186 | UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
187 |
188 | code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
189 |
190 | UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
191 |
192 | code_point += (*it) & 0x3f;
193 |
194 | return UTF8_OK;
195 | }
196 |
197 | template
198 | utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point)
199 | {
200 | if (it == end)
201 | return NOT_ENOUGH_ROOM;
202 |
203 | code_point = utf8::internal::mask8(*it);
204 |
205 | UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
206 |
207 | code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
208 |
209 | UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
210 |
211 | code_point += (utf8::internal::mask8(*it) << 6) & 0xfff;
212 |
213 | UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
214 |
215 | code_point += (*it) & 0x3f;
216 |
217 | return UTF8_OK;
218 | }
219 |
220 | #undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR
221 |
222 | template
223 | utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point)
224 | {
225 | // Save the original value of it so we can go back in case of failure
226 | // Of course, it does not make much sense with i.e. stream iterators
227 | octet_iterator original_it = it;
228 |
229 | uint32_t cp = 0;
230 | // Determine the sequence length based on the lead octet
231 | typedef typename std::iterator_traits::difference_type octet_difference_type;
232 | const octet_difference_type length = utf8::internal::sequence_length(it);
233 |
234 | // Get trail octets and calculate the code point
235 | utf_error err = UTF8_OK;
236 | switch (length) {
237 | case 0:
238 | return INVALID_LEAD;
239 | case 1:
240 | err = utf8::internal::get_sequence_1(it, end, cp);
241 | break;
242 | case 2:
243 | err = utf8::internal::get_sequence_2(it, end, cp);
244 | break;
245 | case 3:
246 | err = utf8::internal::get_sequence_3(it, end, cp);
247 | break;
248 | case 4:
249 | err = utf8::internal::get_sequence_4(it, end, cp);
250 | break;
251 | }
252 |
253 | if (err == UTF8_OK) {
254 | // Decoding succeeded. Now, security checks...
255 | if (utf8::internal::is_code_point_valid(cp)) {
256 | if (!utf8::internal::is_overlong_sequence(cp, length)){
257 | // Passed! Return here.
258 | code_point = cp;
259 | ++it;
260 | return UTF8_OK;
261 | }
262 | else
263 | err = OVERLONG_SEQUENCE;
264 | }
265 | else
266 | err = INVALID_CODE_POINT;
267 | }
268 |
269 | // Failure branch - restore the original value of the iterator
270 | it = original_it;
271 | return err;
272 | }
273 |
274 | template
275 | inline utf_error validate_next(octet_iterator& it, octet_iterator end) {
276 | uint32_t ignored;
277 | return utf8::internal::validate_next(it, end, ignored);
278 | }
279 |
280 | } // namespace internal
281 |
282 | /// The library API - functions intended to be called by the users
283 |
284 | // Byte order mark
285 | const uint8_t bom[] = {0xef, 0xbb, 0xbf};
286 |
287 | template
288 | octet_iterator find_invalid(octet_iterator start, octet_iterator end)
289 | {
290 | octet_iterator result = start;
291 | while (result != end) {
292 | utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end);
293 | if (err_code != internal::UTF8_OK)
294 | return result;
295 | }
296 | return result;
297 | }
298 |
299 | template
300 | inline bool is_valid(octet_iterator start, octet_iterator end)
301 | {
302 | return (utf8::find_invalid(start, end) == end);
303 | }
304 |
305 | template
306 | inline bool starts_with_bom (octet_iterator it, octet_iterator end)
307 | {
308 | return (
309 | ((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) &&
310 | ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) &&
311 | ((it != end) && (utf8::internal::mask8(*it)) == bom[2])
312 | );
313 | }
314 |
315 | //Deprecated in release 2.3
316 | template
317 | inline bool is_bom (octet_iterator it)
318 | {
319 | return (
320 | (utf8::internal::mask8(*it++)) == bom[0] &&
321 | (utf8::internal::mask8(*it++)) == bom[1] &&
322 | (utf8::internal::mask8(*it)) == bom[2]
323 | );
324 | }
325 | } // namespace utf8
326 |
327 | #endif // header guard
328 |
329 |
330 |
--------------------------------------------------------------------------------
/jni-test/app/libs/include/utf8/unchecked.h:
--------------------------------------------------------------------------------
1 | // Copyright 2006 Nemanja Trifunovic
2 |
3 | /*
4 | Permission is hereby granted, free of charge, to any person or organization
5 | obtaining a copy of the software and accompanying documentation covered by
6 | this license (the "Software") to use, reproduce, display, distribute,
7 | execute, and transmit the Software, and to prepare derivative works of the
8 | Software, and to permit third-parties to whom the Software is furnished to
9 | do so, all subject to the following:
10 |
11 | The copyright notices in the Software and this entire statement, including
12 | the above license grant, this restriction and the following disclaimer,
13 | must be included in all copies of the Software, in whole or in part, and
14 | all derivative works of the Software, unless such copies or derivative
15 | works are solely in the form of machine-executable object code generated by
16 | a source language processor.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 | DEALINGS IN THE SOFTWARE.
25 | */
26 |
27 |
28 | #ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
29 | #define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
30 |
31 | #include "core.h"
32 |
33 | namespace utf8
34 | {
35 | namespace unchecked
36 | {
37 | template
38 | octet_iterator append(uint32_t cp, octet_iterator result)
39 | {
40 | if (cp < 0x80) // one octet
41 | *(result++) = static_cast(cp);
42 | else if (cp < 0x800) { // two octets
43 | *(result++) = static_cast((cp >> 6) | 0xc0);
44 | *(result++) = static_cast((cp & 0x3f) | 0x80);
45 | }
46 | else if (cp < 0x10000) { // three octets
47 | *(result++) = static_cast((cp >> 12) | 0xe0);
48 | *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80);
49 | *(result++) = static_cast((cp & 0x3f) | 0x80);
50 | }
51 | else { // four octets
52 | *(result++) = static_cast((cp >> 18) | 0xf0);
53 | *(result++) = static_cast(((cp >> 12) & 0x3f)| 0x80);
54 | *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80);
55 | *(result++) = static_cast((cp & 0x3f) | 0x80);
56 | }
57 | return result;
58 | }
59 |
60 | template
61 | uint32_t next(octet_iterator& it)
62 | {
63 | uint32_t cp = utf8::internal::mask8(*it);
64 | typename std::iterator_traits::difference_type length = utf8::internal::sequence_length(it);
65 | switch (length) {
66 | case 1:
67 | break;
68 | case 2:
69 | it++;
70 | cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f);
71 | break;
72 | case 3:
73 | ++it;
74 | cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
75 | ++it;
76 | cp += (*it) & 0x3f;
77 | break;
78 | case 4:
79 | ++it;
80 | cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
81 | ++it;
82 | cp += (utf8::internal::mask8(*it) << 6) & 0xfff;
83 | ++it;
84 | cp += (*it) & 0x3f;
85 | break;
86 | }
87 | ++it;
88 | return cp;
89 | }
90 |
91 | template
92 | uint32_t peek_next(octet_iterator it)
93 | {
94 | return utf8::unchecked::next(it);
95 | }
96 |
97 | template
98 | uint32_t prior(octet_iterator& it)
99 | {
100 | while (utf8::internal::is_trail(*(--it))) ;
101 | octet_iterator temp = it;
102 | return utf8::unchecked::next(temp);
103 | }
104 |
105 | // Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous)
106 | template
107 | inline uint32_t previous(octet_iterator& it)
108 | {
109 | return utf8::unchecked::prior(it);
110 | }
111 |
112 | template
113 | void advance (octet_iterator& it, distance_type n)
114 | {
115 | for (distance_type i = 0; i < n; ++i)
116 | utf8::unchecked::next(it);
117 | }
118 |
119 | template
120 | typename std::iterator_traits::difference_type
121 | distance (octet_iterator first, octet_iterator last)
122 | {
123 | typename std::iterator_traits::difference_type dist;
124 | for (dist = 0; first < last; ++dist)
125 | utf8::unchecked::next(first);
126 | return dist;
127 | }
128 |
129 | template
130 | octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
131 | {
132 | while (start != end) {
133 | uint32_t cp = utf8::internal::mask16(*start++);
134 | // Take care of surrogate pairs first
135 | if (utf8::internal::is_lead_surrogate(cp)) {
136 | uint32_t trail_surrogate = utf8::internal::mask16(*start++);
137 | cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
138 | }
139 | result = utf8::unchecked::append(cp, result);
140 | }
141 | return result;
142 | }
143 |
144 | template
145 | u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
146 | {
147 | while (start < end) {
148 | uint32_t cp = utf8::unchecked::next(start);
149 | if (cp > 0xffff) { //make a surrogate pair
150 | *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET);
151 | *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
152 | }
153 | else
154 | *result++ = static_cast(cp);
155 | }
156 | return result;
157 | }
158 |
159 | template
160 | octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
161 | {
162 | while (start != end)
163 | result = utf8::unchecked::append(*(start++), result);
164 |
165 | return result;
166 | }
167 |
168 | template
169 | u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
170 | {
171 | while (start < end)
172 | (*result++) = utf8::unchecked::next(start);
173 |
174 | return result;
175 | }
176 |
177 | // The iterator class
178 | template
179 | class iterator : public std::iterator {
180 | octet_iterator it;
181 | public:
182 | iterator () {};
183 | explicit iterator (const octet_iterator& octet_it): it(octet_it) {}
184 | // the default "big three" are OK
185 | octet_iterator base () const { return it; }
186 | uint32_t operator * () const
187 | {
188 | octet_iterator temp = it;
189 | return utf8::unchecked::next(temp);
190 | }
191 | bool operator == (const iterator& rhs) const
192 | {
193 | return (it == rhs.it);
194 | }
195 | bool operator != (const iterator& rhs) const
196 | {
197 | return !(operator == (rhs));
198 | }
199 | iterator& operator ++ ()
200 | {
201 | ::std::advance(it, utf8::internal::sequence_length(it));
202 | return *this;
203 | }
204 | iterator operator ++ (int)
205 | {
206 | iterator temp = *this;
207 | ::std::advance(it, utf8::internal::sequence_length(it));
208 | return temp;
209 | }
210 | iterator& operator -- ()
211 | {
212 | utf8::unchecked::prior(it);
213 | return *this;
214 | }
215 | iterator operator -- (int)
216 | {
217 | iterator temp = *this;
218 | utf8::unchecked::prior(it);
219 | return temp;
220 | }
221 | }; // class iterator
222 |
223 | } // namespace utf8::unchecked
224 | } // namespace utf8
225 |
226 |
227 | #endif // header guard
228 |
229 |
--------------------------------------------------------------------------------
/jni-test/app/libs/include/v8-debug.h:
--------------------------------------------------------------------------------
1 | // Copyright 2008 the V8 project authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | #ifndef V8_V8_DEBUG_H_
6 | #define V8_V8_DEBUG_H_
7 |
8 | #include "v8.h" // NOLINT(build/include)
9 |
10 | /**
11 | * ATTENTION: The debugger API exposed by this file is deprecated and will be
12 | * removed by the end of 2017. Please use the V8 inspector declared
13 | * in include/v8-inspector.h instead.
14 | */
15 | namespace v8 {
16 |
17 | // Debug events which can occur in the V8 JavaScript engine.
18 | enum DebugEvent {
19 | Break = 1,
20 | Exception = 2,
21 | AfterCompile = 3,
22 | CompileError = 4,
23 | AsyncTaskEvent = 5,
24 | };
25 |
26 | class V8_EXPORT Debug {
27 | public:
28 | /**
29 | * A client object passed to the v8 debugger whose ownership will be taken by
30 | * it. v8 is always responsible for deleting the object.
31 | */
32 | class ClientData {
33 | public:
34 | virtual ~ClientData() {}
35 | };
36 |
37 |
38 | /**
39 | * A message object passed to the debug message handler.
40 | */
41 | class Message {
42 | public:
43 | /**
44 | * Check type of message.
45 | */
46 | virtual bool IsEvent() const = 0;
47 | virtual bool IsResponse() const = 0;
48 | virtual DebugEvent GetEvent() const = 0;
49 |
50 | /**
51 | * Indicate whether this is a response to a continue command which will
52 | * start the VM running after this is processed.
53 | */
54 | virtual bool WillStartRunning() const = 0;
55 |
56 | /**
57 | * Access to execution state and event data. Don't store these cross
58 | * callbacks as their content becomes invalid. These objects are from the
59 | * debugger event that started the debug message loop.
60 | */
61 | virtual Local GetExecutionState() const = 0;
62 | virtual Local GetEventData() const = 0;
63 |
64 | /**
65 | * Get the debugger protocol JSON.
66 | */
67 | virtual Local GetJSON() const = 0;
68 |
69 | /**
70 | * Get the context active when the debug event happened. Note this is not
71 | * the current active context as the JavaScript part of the debugger is
72 | * running in its own context which is entered at this point.
73 | */
74 | virtual Local GetEventContext() const = 0;
75 |
76 | /**
77 | * Client data passed with the corresponding request if any. This is the
78 | * client_data data value passed into Debug::SendCommand along with the
79 | * request that led to the message or NULL if the message is an event. The
80 | * debugger takes ownership of the data and will delete it even if there is
81 | * no message handler.
82 | */
83 | virtual ClientData* GetClientData() const = 0;
84 |
85 | virtual Isolate* GetIsolate() const = 0;
86 |
87 | virtual ~Message() {}
88 | };
89 |
90 | /**
91 | * An event details object passed to the debug event listener.
92 | */
93 | class EventDetails {
94 | public:
95 | /**
96 | * Event type.
97 | */
98 | virtual DebugEvent GetEvent() const = 0;
99 |
100 | /**
101 | * Access to execution state and event data of the debug event. Don't store
102 | * these cross callbacks as their content becomes invalid.
103 | */
104 | virtual Local GetExecutionState() const = 0;
105 | virtual Local GetEventData() const = 0;
106 |
107 | /**
108 | * Get the context active when the debug event happened. Note this is not
109 | * the current active context as the JavaScript part of the debugger is
110 | * running in its own context which is entered at this point.
111 | */
112 | virtual Local GetEventContext() const = 0;
113 |
114 | /**
115 | * Client data passed with the corresponding callback when it was
116 | * registered.
117 | */
118 | virtual Local GetCallbackData() const = 0;
119 |
120 | /**
121 | * This is now a dummy that returns nullptr.
122 | */
123 | virtual ClientData* GetClientData() const = 0;
124 |
125 | virtual Isolate* GetIsolate() const = 0;
126 |
127 | virtual ~EventDetails() {}
128 | };
129 |
130 | /**
131 | * Debug event callback function.
132 | *
133 | * \param event_details object providing information about the debug event
134 | *
135 | * A EventCallback does not take possession of the event data,
136 | * and must not rely on the data persisting after the handler returns.
137 | */
138 | typedef void (*EventCallback)(const EventDetails& event_details);
139 |
140 | /**
141 | * This is now a no-op.
142 | */
143 | typedef void (*MessageHandler)(const Message& message);
144 |
145 | V8_DEPRECATED("No longer supported", static bool SetDebugEventListener(
146 | Isolate* isolate, EventCallback that,
147 | Local data = Local()));
148 |
149 | // Schedule a debugger break to happen when JavaScript code is run
150 | // in the given isolate.
151 | V8_DEPRECATED("No longer supported",
152 | static void DebugBreak(Isolate* isolate));
153 |
154 | // Remove scheduled debugger break in given isolate if it has not
155 | // happened yet.
156 | V8_DEPRECATED("No longer supported",
157 | static void CancelDebugBreak(Isolate* isolate));
158 |
159 | // Check if a debugger break is scheduled in the given isolate.
160 | V8_DEPRECATED("No longer supported",
161 | static bool CheckDebugBreak(Isolate* isolate));
162 |
163 | // This is now a no-op.
164 | V8_DEPRECATED("No longer supported",
165 | static void SetMessageHandler(Isolate* isolate,
166 | MessageHandler handler));
167 |
168 | // This is now a no-op.
169 | V8_DEPRECATED("No longer supported",
170 | static void SendCommand(Isolate* isolate,
171 | const uint16_t* command, int length,
172 | ClientData* client_data = NULL));
173 |
174 | /**
175 | * Run a JavaScript function in the debugger.
176 | * \param fun the function to call
177 | * \param data passed as second argument to the function
178 | * With this call the debugger is entered and the function specified is called
179 | * with the execution state as the first argument. This makes it possible to
180 | * get access to information otherwise not available during normal JavaScript
181 | * execution e.g. details on stack frames. Receiver of the function call will
182 | * be the debugger context global object, however this is a subject to change.
183 | * The following example shows a JavaScript function which when passed to
184 | * v8::Debug::Call will return the current line of JavaScript execution.
185 | *
186 | * \code
187 | * function frame_source_line(exec_state) {
188 | * return exec_state.frame(0).sourceLine();
189 | * }
190 | * \endcode
191 | */
192 | V8_DEPRECATED("No longer supported",
193 | static MaybeLocal Call(
194 | Local context, v8::Local fun,
195 | Local data = Local()));
196 |
197 | // This is now a no-op.
198 | V8_DEPRECATED("No longer supported",
199 | static void ProcessDebugMessages(Isolate* isolate));
200 |
201 | /**
202 | * Debugger is running in its own context which is entered while debugger
203 | * messages are being dispatched. This is an explicit getter for this
204 | * debugger context. Note that the content of the debugger context is subject
205 | * to change. The Context exists only when the debugger is active, i.e. at
206 | * least one DebugEventListener or MessageHandler is set.
207 | */
208 | V8_DEPRECATED("Use v8-inspector",
209 | static Local GetDebugContext(Isolate* isolate));
210 |
211 | /**
212 | * While in the debug context, this method returns the top-most non-debug
213 | * context, if it exists.
214 | */
215 | V8_DEPRECATED(
216 | "No longer supported",
217 | static MaybeLocal GetDebuggedContext(Isolate* isolate));
218 |
219 | /**
220 | * Enable/disable LiveEdit functionality for the given Isolate
221 | * (default Isolate if not provided). V8 will abort if LiveEdit is
222 | * unexpectedly used. LiveEdit is enabled by default.
223 | */
224 | V8_DEPRECATED("No longer supported",
225 | static void SetLiveEditEnabled(Isolate* isolate, bool enable));
226 |
227 | /**
228 | * Returns array of internal properties specific to the value type. Result has
229 | * the following format: [, ,...,, ]. Result array
230 | * will be allocated in the current context.
231 | */
232 | V8_DEPRECATED("No longer supported",
233 | static MaybeLocal GetInternalProperties(
234 | Isolate* isolate, Local value));
235 |
236 | /**
237 | * Defines if the ES2015 tail call elimination feature is enabled or not.
238 | * The change of this flag triggers deoptimization of all functions that
239 | * contain calls at tail position.
240 | */
241 | V8_DEPRECATED("No longer supported",
242 | static bool IsTailCallEliminationEnabled(Isolate* isolate));
243 | V8_DEPRECATED("No longer supported",
244 | static void SetTailCallEliminationEnabled(Isolate* isolate,
245 | bool enabled));
246 | };
247 |
248 |
249 | } // namespace v8
250 |
251 |
252 | #undef EXPORT
253 |
254 |
255 | #endif // V8_V8_DEBUG_H_
256 |
--------------------------------------------------------------------------------
/jni-test/app/libs/include/v8-experimental.h:
--------------------------------------------------------------------------------
1 | // Copyright 2015 the V8 project authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | /**
6 | * This header contains a set of experimental V8 APIs. We hope these will
7 | * become a part of standard V8, but they may also be removed if we deem the
8 | * experiment to not be successul.
9 | */
10 | #ifndef V8_INCLUDE_V8_EXPERIMENTAL_H_
11 | #define V8_INCLUDE_V8_EXPERIMENTAL_H_
12 |
13 | #include "v8.h" // NOLINT(build/include)
14 |
15 | namespace v8 {
16 | namespace experimental {
17 |
18 | // Allow the embedder to construct accessors that V8 can compile and use
19 | // directly, without jumping into the runtime.
20 | class V8_EXPORT FastAccessorBuilder {
21 | public:
22 | struct ValueId {
23 | size_t value_id;
24 | };
25 | struct LabelId {
26 | size_t label_id;
27 | };
28 |
29 | static FastAccessorBuilder* New(Isolate* isolate);
30 |
31 | ValueId IntegerConstant(int int_constant);
32 | ValueId GetReceiver();
33 | ValueId LoadInternalField(ValueId value_id, int field_no);
34 | ValueId LoadInternalFieldUnchecked(ValueId value_id, int field_no);
35 | ValueId LoadValue(ValueId value_id, int offset);
36 | ValueId LoadObject(ValueId value_id, int offset);
37 | ValueId ToSmi(ValueId value_id);
38 |
39 | void ReturnValue(ValueId value_id);
40 | void CheckFlagSetOrReturnNull(ValueId value_id, int mask);
41 | void CheckNotZeroOrReturnNull(ValueId value_id);
42 | LabelId MakeLabel();
43 | void SetLabel(LabelId label_id);
44 | void Goto(LabelId label_id);
45 | void CheckNotZeroOrJump(ValueId value_id, LabelId label_id);
46 | ValueId Call(v8::FunctionCallback callback, ValueId value_id);
47 |
48 | private:
49 | FastAccessorBuilder() = delete;
50 | FastAccessorBuilder(const FastAccessorBuilder&) = delete;
51 | ~FastAccessorBuilder() = delete;
52 | void operator=(const FastAccessorBuilder&) = delete;
53 | };
54 |
55 | } // namespace experimental
56 | } // namespace v8
57 |
58 | #endif // V8_INCLUDE_V8_EXPERIMENTAL_H_
59 |
--------------------------------------------------------------------------------
/jni-test/app/libs/include/v8-inspector-protocol.h:
--------------------------------------------------------------------------------
1 | // Copyright 2016 the V8 project authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | #ifndef V8_V8_INSPECTOR_PROTOCOL_H_
6 | #define V8_V8_INSPECTOR_PROTOCOL_H_
7 |
8 | #include "inspector/Debugger.h" // NOLINT(build/include)
9 | #include "inspector/Runtime.h" // NOLINT(build/include)
10 | #include "inspector/Schema.h" // NOLINT(build/include)
11 | #include "v8-inspector.h" // NOLINT(build/include)
12 |
13 | #endif // V8_V8_INSPECTOR_PROTOCOL_H_
14 |
--------------------------------------------------------------------------------
/jni-test/app/libs/include/v8-inspector.h:
--------------------------------------------------------------------------------
1 | // Copyright 2016 the V8 project authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | #ifndef V8_V8_INSPECTOR_H_
6 | #define V8_V8_INSPECTOR_H_
7 |
8 | #include
9 | #include
10 |
11 | #include
12 |
13 | #include "v8.h" // NOLINT(build/include)
14 |
15 | namespace v8_inspector {
16 |
17 | namespace protocol {
18 | namespace Debugger {
19 | namespace API {
20 | class SearchMatch;
21 | }
22 | }
23 | namespace Runtime {
24 | namespace API {
25 | class RemoteObject;
26 | class StackTrace;
27 | }
28 | }
29 | namespace Schema {
30 | namespace API {
31 | class Domain;
32 | }
33 | }
34 | } // namespace protocol
35 |
36 | class V8_EXPORT StringView {
37 | public:
38 | StringView() : m_is8Bit(true), m_length(0), m_characters8(nullptr) {}
39 |
40 | StringView(const uint8_t* characters, size_t length)
41 | : m_is8Bit(true), m_length(length), m_characters8(characters) {}
42 |
43 | StringView(const uint16_t* characters, size_t length)
44 | : m_is8Bit(false), m_length(length), m_characters16(characters) {}
45 |
46 | bool is8Bit() const { return m_is8Bit; }
47 | size_t length() const { return m_length; }
48 |
49 | // TODO(dgozman): add DCHECK(m_is8Bit) to accessors once platform can be used
50 | // here.
51 | const uint8_t* characters8() const { return m_characters8; }
52 | const uint16_t* characters16() const { return m_characters16; }
53 |
54 | private:
55 | bool m_is8Bit;
56 | size_t m_length;
57 | union {
58 | const uint8_t* m_characters8;
59 | const uint16_t* m_characters16;
60 | };
61 | };
62 |
63 | class V8_EXPORT StringBuffer {
64 | public:
65 | virtual ~StringBuffer() = default;
66 | virtual const StringView& string() = 0;
67 | // This method copies contents.
68 | static std::unique_ptr create(const StringView&);
69 | };
70 |
71 | class V8_EXPORT V8ContextInfo {
72 | public:
73 | V8ContextInfo(v8::Local context, int contextGroupId,
74 | const StringView& humanReadableName)
75 | : context(context),
76 | contextGroupId(contextGroupId),
77 | humanReadableName(humanReadableName),
78 | hasMemoryOnConsole(false) {}
79 |
80 | v8::Local context;
81 | // Each v8::Context is a part of a group. The group id must be non-zero.
82 | int contextGroupId;
83 | StringView humanReadableName;
84 | StringView origin;
85 | StringView auxData;
86 | bool hasMemoryOnConsole;
87 |
88 | static int executionContextId(v8::Local context);
89 |
90 | private:
91 | // Disallow copying and allocating this one.
92 | enum NotNullTagEnum { NotNullLiteral };
93 | void* operator new(size_t) = delete;
94 | void* operator new(size_t, NotNullTagEnum, void*) = delete;
95 | void* operator new(size_t, void*) = delete;
96 | V8ContextInfo(const V8ContextInfo&) = delete;
97 | V8ContextInfo& operator=(const V8ContextInfo&) = delete;
98 | };
99 |
100 | class V8_EXPORT V8StackTrace {
101 | public:
102 | virtual StringView firstNonEmptySourceURL() const = 0;
103 | virtual bool isEmpty() const = 0;
104 | virtual StringView topSourceURL() const = 0;
105 | virtual int topLineNumber() const = 0;
106 | virtual int topColumnNumber() const = 0;
107 | virtual StringView topScriptId() const = 0;
108 | virtual StringView topFunctionName() const = 0;
109 |
110 | virtual ~V8StackTrace() = default;
111 | virtual std::unique_ptr
112 | buildInspectorObject() const = 0;
113 | virtual std::unique_ptr toString() const = 0;
114 |
115 | // Safe to pass between threads, drops async chain.
116 | virtual std::unique_ptr clone() = 0;
117 | };
118 |
119 | class V8_EXPORT V8InspectorSession {
120 | public:
121 | virtual ~V8InspectorSession() = default;
122 |
123 | // Cross-context inspectable values (DOM nodes in different worlds, etc.).
124 | class V8_EXPORT Inspectable {
125 | public:
126 | virtual v8::Local get(v8::Local) = 0;
127 | virtual ~Inspectable() = default;
128 | };
129 | virtual void addInspectedObject(std::unique_ptr) = 0;
130 |
131 | // Dispatching protocol messages.
132 | static bool canDispatchMethod(const StringView& method);
133 | virtual void dispatchProtocolMessage(const StringView& message) = 0;
134 | virtual std::unique_ptr stateJSON() = 0;
135 | virtual std::vector>
136 | supportedDomains() = 0;
137 |
138 | // Debugger actions.
139 | virtual void schedulePauseOnNextStatement(const StringView& breakReason,
140 | const StringView& breakDetails) = 0;
141 | virtual void cancelPauseOnNextStatement() = 0;
142 | virtual void breakProgram(const StringView& breakReason,
143 | const StringView& breakDetails) = 0;
144 | virtual void setSkipAllPauses(bool) = 0;
145 | virtual void resume() = 0;
146 | virtual void stepOver() = 0;
147 | virtual std::vector>
148 | searchInTextByLines(const StringView& text, const StringView& query,
149 | bool caseSensitive, bool isRegex) = 0;
150 |
151 | // Remote objects.
152 | virtual std::unique_ptr wrapObject(
153 | v8::Local, v8::Local, const StringView& groupName,
154 | bool generatePreview) = 0;
155 |
156 | virtual bool unwrapObject(std::unique_ptr* error,
157 | const StringView& objectId, v8::Local*,
158 | v8::Local*,
159 | std::unique_ptr* objectGroup) = 0;
160 | virtual void releaseObjectGroup(const StringView&) = 0;
161 | };
162 |
163 | class V8_EXPORT V8InspectorClient {
164 | public:
165 | virtual ~V8InspectorClient() = default;
166 |
167 | virtual void runMessageLoopOnPause(int contextGroupId) {}
168 | virtual void quitMessageLoopOnPause() {}
169 | virtual void runIfWaitingForDebugger(int contextGroupId) {}
170 |
171 | virtual void muteMetrics(int contextGroupId) {}
172 | virtual void unmuteMetrics(int contextGroupId) {}
173 |
174 | virtual void beginUserGesture() {}
175 | virtual void endUserGesture() {}
176 |
177 | virtual std::unique_ptr valueSubtype(v8::Local) {
178 | return nullptr;
179 | }
180 | virtual bool formatAccessorsAsProperties(v8::Local) {
181 | return false;
182 | }
183 | virtual bool isInspectableHeapObject(v8::Local) { return true; }
184 |
185 | virtual v8::Local ensureDefaultContextInGroup(
186 | int contextGroupId) {
187 | return v8::Local();
188 | }
189 | virtual void beginEnsureAllContextsInGroup(int contextGroupId) {}
190 | virtual void endEnsureAllContextsInGroup(int contextGroupId) {}
191 |
192 | virtual void installAdditionalCommandLineAPI(v8::Local,
193 | v8::Local) {}
194 | virtual void consoleAPIMessage(int contextGroupId,
195 | v8::Isolate::MessageErrorLevel level,
196 | const StringView& message,
197 | const StringView& url, unsigned lineNumber,
198 | unsigned columnNumber, V8StackTrace*) {}
199 | virtual v8::MaybeLocal memoryInfo(v8::Isolate*,
200 | v8::Local) {
201 | return v8::MaybeLocal();
202 | }
203 |
204 | virtual void consoleTime(const StringView& title) {}
205 | virtual void consoleTimeEnd(const StringView& title) {}
206 | virtual void consoleTimeStamp(const StringView& title) {}
207 | virtual void consoleClear(int contextGroupId) {}
208 | virtual double currentTimeMS() { return 0; }
209 | typedef void (*TimerCallback)(void*);
210 | virtual void startRepeatingTimer(double, TimerCallback, void* data) {}
211 | virtual void cancelTimer(void* data) {}
212 |
213 | // TODO(dgozman): this was added to support service worker shadow page. We
214 | // should not connect at all.
215 | virtual bool canExecuteScripts(int contextGroupId) { return true; }
216 |
217 | virtual void maxAsyncCallStackDepthChanged(int depth) {}
218 |
219 | virtual std::unique_ptr resourceNameToUrl(
220 | const StringView& resourceName) {
221 | return nullptr;
222 | }
223 | };
224 |
225 | // These stack trace ids are intended to be passed between debuggers and be
226 | // resolved later. This allows to track cross-debugger calls and step between
227 | // them if a single client connects to multiple debuggers.
228 | struct V8_EXPORT V8StackTraceId {
229 | uintptr_t id;
230 | std::pair debugger_id;
231 |
232 | V8StackTraceId();
233 | V8StackTraceId(uintptr_t id, const std::pair debugger_id);
234 | ~V8StackTraceId() = default;
235 |
236 | bool IsInvalid() const;
237 | };
238 |
239 | class V8_EXPORT V8Inspector {
240 | public:
241 | static std::unique_ptr create(v8::Isolate*, V8InspectorClient*);
242 | virtual ~V8Inspector() = default;
243 |
244 | // Contexts instrumentation.
245 | virtual void contextCreated(const V8ContextInfo&) = 0;
246 | virtual void contextDestroyed(v8::Local) = 0;
247 | virtual void resetContextGroup(int contextGroupId) = 0;
248 | virtual v8::MaybeLocal contextById(int groupId,
249 | v8::Maybe contextId) = 0;
250 |
251 | // Various instrumentation.
252 | virtual void idleStarted() = 0;
253 | virtual void idleFinished() = 0;
254 |
255 | // Async stack traces instrumentation.
256 | virtual void asyncTaskScheduled(const StringView& taskName, void* task,
257 | bool recurring) = 0;
258 | virtual void asyncTaskCanceled(void* task) = 0;
259 | virtual void asyncTaskStarted(void* task) = 0;
260 | virtual void asyncTaskFinished(void* task) = 0;
261 | virtual void allAsyncTasksCanceled() = 0;
262 |
263 | virtual V8StackTraceId storeCurrentStackTrace(
264 | const StringView& description) = 0;
265 | virtual void externalAsyncTaskStarted(const V8StackTraceId& parent) = 0;
266 | virtual void externalAsyncTaskFinished(const V8StackTraceId& parent) = 0;
267 |
268 | // Exceptions instrumentation.
269 | virtual unsigned exceptionThrown(
270 | v8::Local, const StringView& message,
271 | v8::Local exception, const StringView& detailedMessage,
272 | const StringView& url, unsigned lineNumber, unsigned columnNumber,
273 | std::unique_ptr, int scriptId) = 0;
274 | virtual void exceptionRevoked(v8::Local, unsigned exceptionId,
275 | const StringView& message) = 0;
276 |
277 | // Connection.
278 | class V8_EXPORT Channel {
279 | public:
280 | virtual ~Channel() = default;
281 | virtual void sendResponse(int callId,
282 | std::unique_ptr message) = 0;
283 | virtual void sendNotification(std::unique_ptr message) = 0;
284 | virtual void flushProtocolNotifications() = 0;
285 | };
286 | virtual std::unique_ptr connect(
287 | int contextGroupId, Channel*, const StringView& state) = 0;
288 |
289 | // API methods.
290 | virtual std::unique_ptr createStackTrace(
291 | v8::Local) = 0;
292 | virtual std::unique_ptr captureStackTrace(bool fullStack) = 0;
293 | };
294 |
295 | } // namespace v8_inspector
296 |
297 | #endif // V8_V8_INSPECTOR_H_
298 |
--------------------------------------------------------------------------------
/jni-test/app/libs/include/v8-internal.h:
--------------------------------------------------------------------------------
1 | // Copyright 2018 the V8 project authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | #ifndef INCLUDE_V8_INTERNAL_H_
6 | #define INCLUDE_V8_INTERNAL_H_
7 |
8 | #include
9 | #include
10 | #include
11 |
12 | #include "v8-version.h" // NOLINT(build/include)
13 | #include "v8config.h" // NOLINT(build/include)
14 |
15 | namespace v8 {
16 |
17 | class Context;
18 | class Data;
19 | class Isolate;
20 |
21 | namespace internal {
22 |
23 | typedef uintptr_t Address;
24 | static const Address kNullAddress = 0;
25 |
26 | /**
27 | * Configuration of tagging scheme.
28 | */
29 | const int kApiSystemPointerSize = sizeof(void*);
30 | const int kApiTaggedSize = kApiSystemPointerSize;
31 | const int kApiDoubleSize = sizeof(double);
32 | const int kApiIntSize = sizeof(int);
33 | const int kApiInt64Size = sizeof(int64_t);
34 |
35 | // Tag information for HeapObject.
36 | const int kHeapObjectTag = 1;
37 | const int kWeakHeapObjectTag = 3;
38 | const int kHeapObjectTagSize = 2;
39 | const intptr_t kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1;
40 |
41 | // Tag information for Smi.
42 | const int kSmiTag = 0;
43 | const int kSmiTagSize = 1;
44 | const intptr_t kSmiTagMask = (1 << kSmiTagSize) - 1;
45 |
46 | template
47 | struct SmiTagging;
48 |
49 | // Smi constants for systems where tagged pointer is a 32-bit value.
50 | template <>
51 | struct SmiTagging<4> {
52 | enum { kSmiShiftSize = 0, kSmiValueSize = 31 };
53 | V8_INLINE static int SmiToInt(const internal::Address value) {
54 | int shift_bits = kSmiTagSize + kSmiShiftSize;
55 | // Shift down (requires >> to be sign extending).
56 | return static_cast(static_cast(value)) >> shift_bits;
57 | }
58 | V8_INLINE static constexpr bool IsValidSmi(intptr_t value) {
59 | // To be representable as an tagged small integer, the two
60 | // most-significant bits of 'value' must be either 00 or 11 due to
61 | // sign-extension. To check this we add 01 to the two
62 | // most-significant bits, and check if the most-significant bit is 0.
63 | //
64 | // CAUTION: The original code below:
65 | // bool result = ((value + 0x40000000) & 0x80000000) == 0;
66 | // may lead to incorrect results according to the C language spec, and
67 | // in fact doesn't work correctly with gcc4.1.1 in some cases: The
68 | // compiler may produce undefined results in case of signed integer
69 | // overflow. The computation must be done w/ unsigned ints.
70 | return static_cast(value) + 0x40000000U < 0x80000000U;
71 | }
72 | };
73 |
74 | // Smi constants for systems where tagged pointer is a 64-bit value.
75 | template <>
76 | struct SmiTagging<8> {
77 | enum { kSmiShiftSize = 31, kSmiValueSize = 32 };
78 | V8_INLINE static int SmiToInt(const internal::Address value) {
79 | int shift_bits = kSmiTagSize + kSmiShiftSize;
80 | // Shift down and throw away top 32 bits.
81 | return static_cast(static_cast(value) >> shift_bits);
82 | }
83 | V8_INLINE static constexpr bool IsValidSmi(intptr_t value) {
84 | // To be representable as a long smi, the value must be a 32-bit integer.
85 | return (value == static_cast(value));
86 | }
87 | };
88 |
89 | #if defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH)
90 | static_assert(
91 | kApiSystemPointerSize == kApiInt64Size,
92 | "Pointer compression can be enabled only for 64-bit architectures");
93 | typedef SmiTagging<4> PlatformSmiTagging;
94 | #else
95 | typedef SmiTagging PlatformSmiTagging;
96 | #endif
97 |
98 | const int kSmiShiftSize = PlatformSmiTagging::kSmiShiftSize;
99 | const int kSmiValueSize = PlatformSmiTagging::kSmiValueSize;
100 | const int kSmiMinValue = (static_cast(-1)) << (kSmiValueSize - 1);
101 | const int kSmiMaxValue = -(kSmiMinValue + 1);
102 | constexpr bool SmiValuesAre31Bits() { return kSmiValueSize == 31; }
103 | constexpr bool SmiValuesAre32Bits() { return kSmiValueSize == 32; }
104 |
105 | V8_INLINE static constexpr internal::Address IntToSmi(int value) {
106 | return (static_cast(value) << (kSmiTagSize + kSmiShiftSize)) |
107 | kSmiTag;
108 | }
109 |
110 | /**
111 | * This class exports constants and functionality from within v8 that
112 | * is necessary to implement inline functions in the v8 api. Don't
113 | * depend on functions and constants defined here.
114 | */
115 | class Internals {
116 | public:
117 | // These values match non-compiler-dependent values defined within
118 | // the implementation of v8.
119 | static const int kHeapObjectMapOffset = 0;
120 | static const int kMapInstanceTypeOffset = 1 * kApiTaggedSize + kApiIntSize;
121 | static const int kStringResourceOffset = 1 * kApiTaggedSize + 2 * kApiIntSize;
122 |
123 | static const int kOddballKindOffset = 4 * kApiTaggedSize + kApiDoubleSize;
124 | static const int kForeignAddressOffset = kApiTaggedSize;
125 | static const int kJSObjectHeaderSize = 3 * kApiTaggedSize;
126 | static const int kFixedArrayHeaderSize = 2 * kApiTaggedSize;
127 | static const int kEmbedderDataArrayHeaderSize = 2 * kApiTaggedSize;
128 | static const int kEmbedderDataSlotSize =
129 | #ifdef V8_COMPRESS_POINTERS
130 | 2 *
131 | #endif
132 | kApiSystemPointerSize;
133 | static const int kNativeContextEmbedderDataOffset = 7 * kApiTaggedSize;
134 | static const int kFullStringRepresentationMask = 0x0f;
135 | static const int kStringEncodingMask = 0x8;
136 | static const int kExternalTwoByteRepresentationTag = 0x02;
137 | static const int kExternalOneByteRepresentationTag = 0x0a;
138 |
139 | static const uint32_t kNumIsolateDataSlots = 4;
140 |
141 | static const int kIsolateEmbedderDataOffset = 0;
142 | static const int kExternalMemoryOffset =
143 | kNumIsolateDataSlots * kApiTaggedSize;
144 | static const int kExternalMemoryLimitOffset =
145 | kExternalMemoryOffset + kApiInt64Size;
146 | static const int kExternalMemoryAtLastMarkCompactOffset =
147 | kExternalMemoryLimitOffset + kApiInt64Size;
148 | static const int kIsolateRootsOffset =
149 | kExternalMemoryAtLastMarkCompactOffset + kApiInt64Size;
150 |
151 | static const int kUndefinedValueRootIndex = 4;
152 | static const int kTheHoleValueRootIndex = 5;
153 | static const int kNullValueRootIndex = 6;
154 | static const int kTrueValueRootIndex = 7;
155 | static const int kFalseValueRootIndex = 8;
156 | static const int kEmptyStringRootIndex = 9;
157 |
158 | static const int kNodeClassIdOffset = 1 * kApiTaggedSize;
159 | static const int kNodeFlagsOffset = 1 * kApiTaggedSize + 3;
160 | static const int kNodeStateMask = 0x7;
161 | static const int kNodeStateIsWeakValue = 2;
162 | static const int kNodeStateIsPendingValue = 3;
163 | static const int kNodeStateIsNearDeathValue = 4;
164 | static const int kNodeIsIndependentShift = 3;
165 | static const int kNodeIsActiveShift = 4;
166 |
167 | static const int kFirstNonstringType = 0x80;
168 | static const int kOddballType = 0x83;
169 | static const int kForeignType = 0x87;
170 | static const int kJSSpecialApiObjectType = 0x410;
171 | static const int kJSApiObjectType = 0x420;
172 | static const int kJSObjectType = 0x421;
173 |
174 | static const int kUndefinedOddballKind = 5;
175 | static const int kNullOddballKind = 3;
176 |
177 | // Soft limit for AdjustAmountofExternalAllocatedMemory. Trigger an
178 | // incremental GC once the external memory reaches this limit.
179 | static constexpr int kExternalAllocationSoftLimit = 64 * 1024 * 1024;
180 |
181 | V8_EXPORT static void CheckInitializedImpl(v8::Isolate* isolate);
182 | V8_INLINE static void CheckInitialized(v8::Isolate* isolate) {
183 | #ifdef V8_ENABLE_CHECKS
184 | CheckInitializedImpl(isolate);
185 | #endif
186 | }
187 |
188 | V8_INLINE static bool HasHeapObjectTag(const internal::Address value) {
189 | return (value & kHeapObjectTagMask) == static_cast(kHeapObjectTag);
190 | }
191 |
192 | V8_INLINE static int SmiValue(const internal::Address value) {
193 | return PlatformSmiTagging::SmiToInt(value);
194 | }
195 |
196 | V8_INLINE static constexpr internal::Address IntToSmi(int value) {
197 | return internal::IntToSmi(value);
198 | }
199 |
200 | V8_INLINE static constexpr bool IsValidSmi(intptr_t value) {
201 | return PlatformSmiTagging::IsValidSmi(value);
202 | }
203 |
204 | V8_INLINE static int GetInstanceType(const internal::Address obj) {
205 | typedef internal::Address A;
206 | A map = ReadField(obj, kHeapObjectMapOffset);
207 | return ReadField(map, kMapInstanceTypeOffset);
208 | }
209 |
210 | V8_INLINE static int GetOddballKind(const internal::Address obj) {
211 | return SmiValue(ReadField(obj, kOddballKindOffset));
212 | }
213 |
214 | V8_INLINE static bool IsExternalTwoByteString(int instance_type) {
215 | int representation = (instance_type & kFullStringRepresentationMask);
216 | return representation == kExternalTwoByteRepresentationTag;
217 | }
218 |
219 | V8_INLINE static uint8_t GetNodeFlag(internal::Address* obj, int shift) {
220 | uint8_t* addr = reinterpret_cast(obj) + kNodeFlagsOffset;
221 | return *addr & static_cast(1U << shift);
222 | }
223 |
224 | V8_INLINE static void UpdateNodeFlag(internal::Address* obj, bool value,
225 | int shift) {
226 | uint8_t* addr = reinterpret_cast(obj) + kNodeFlagsOffset;
227 | uint8_t mask = static_cast(1U << shift);
228 | *addr = static_cast((*addr & ~mask) | (value << shift));
229 | }
230 |
231 | V8_INLINE static uint8_t GetNodeState(internal::Address* obj) {
232 | uint8_t* addr = reinterpret_cast(obj) + kNodeFlagsOffset;
233 | return *addr & kNodeStateMask;
234 | }
235 |
236 | V8_INLINE static void UpdateNodeState(internal::Address* obj, uint8_t value) {
237 | uint8_t* addr = reinterpret_cast(obj) + kNodeFlagsOffset;
238 | *addr = static_cast((*addr & ~kNodeStateMask) | value);
239 | }
240 |
241 | V8_INLINE static void SetEmbedderData(v8::Isolate* isolate, uint32_t slot,
242 | void* data) {
243 | internal::Address addr = reinterpret_cast(isolate) +
244 | kIsolateEmbedderDataOffset +
245 | slot * kApiSystemPointerSize;
246 | *reinterpret_cast(addr) = data;
247 | }
248 |
249 | V8_INLINE static void* GetEmbedderData(const v8::Isolate* isolate,
250 | uint32_t slot) {
251 | internal::Address addr = reinterpret_cast(isolate) +
252 | kIsolateEmbedderDataOffset +
253 | slot * kApiSystemPointerSize;
254 | return *reinterpret_cast(addr);
255 | }
256 |
257 | V8_INLINE static internal::Address* GetRoot(v8::Isolate* isolate, int index) {
258 | internal::Address addr = reinterpret_cast(isolate) +
259 | kIsolateRootsOffset +
260 | index * kApiSystemPointerSize;
261 | return reinterpret_cast(addr);
262 | }
263 |
264 | template
265 | V8_INLINE static T ReadField(const internal::Address heap_object_ptr,
266 | int offset) {
267 | internal::Address addr = heap_object_ptr + offset - kHeapObjectTag;
268 | return *reinterpret_cast(addr);
269 | }
270 |
271 | #ifndef V8_COMPRESS_POINTERS
272 | template
273 | V8_INLINE static T ReadEmbedderData(const v8::Context* context, int index) {
274 | typedef internal::Address A;
275 | typedef internal::Internals I;
276 | A ctx = *reinterpret_cast(context);
277 | A embedder_data = I::ReadField(ctx, I::kNativeContextEmbedderDataOffset);
278 | int value_offset =
279 | I::kEmbedderDataArrayHeaderSize + (I::kEmbedderDataSlotSize * index);
280 | return I::ReadField(embedder_data, value_offset);
281 | }
282 | #endif
283 | };
284 |
285 | // Only perform cast check for types derived from v8::Data since
286 | // other types do not implement the Cast method.
287 | template
288 | struct CastCheck {
289 | template
290 | static void Perform(T* data);
291 | };
292 |
293 | template <>
294 | template
295 | void CastCheck::Perform(T* data) {
296 | T::Cast(data);
297 | }
298 |
299 | template <>
300 | template
301 | void CastCheck::Perform(T* data) {}
302 |
303 | template
304 | V8_INLINE void PerformCastCheck(T* data) {
305 | CastCheck::value>::Perform(data);
306 | }
307 |
308 | } // namespace internal
309 | } // namespace v8
310 |
311 | #endif // INCLUDE_V8_INTERNAL_H_
312 |
--------------------------------------------------------------------------------
/jni-test/app/libs/include/v8-platform.h:
--------------------------------------------------------------------------------
1 | // Copyright 2013 the V8 project authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | #ifndef V8_V8_PLATFORM_H_
6 | #define V8_V8_PLATFORM_H_
7 |
8 | #include
9 | #include
10 | #include // For abort.
11 | #include
12 | #include
13 |
14 | #include "v8config.h" // NOLINT(build/include)
15 |
16 | namespace v8 {
17 |
18 | class Isolate;
19 |
20 | /**
21 | * A Task represents a unit of work.
22 | */
23 | class Task {
24 | public:
25 | virtual ~Task() = default;
26 |
27 | virtual void Run() = 0;
28 | };
29 |
30 | /**
31 | * An IdleTask represents a unit of work to be performed in idle time.
32 | * The Run method is invoked with an argument that specifies the deadline in
33 | * seconds returned by MonotonicallyIncreasingTime().
34 | * The idle task is expected to complete by this deadline.
35 | */
36 | class IdleTask {
37 | public:
38 | virtual ~IdleTask() = default;
39 | virtual void Run(double deadline_in_seconds) = 0;
40 | };
41 |
42 | /**
43 | * A TaskRunner allows scheduling of tasks. The TaskRunner may still be used to
44 | * post tasks after the isolate gets destructed, but these tasks may not get
45 | * executed anymore. All tasks posted to a given TaskRunner will be invoked in
46 | * sequence. Tasks can be posted from any thread.
47 | */
48 | class TaskRunner {
49 | public:
50 | /**
51 | * Schedules a task to be invoked by this TaskRunner. The TaskRunner
52 | * implementation takes ownership of |task|.
53 | */
54 | virtual void PostTask(std::unique_ptr task) = 0;
55 |
56 | /**
57 | * Schedules a task to be invoked by this TaskRunner. The TaskRunner
58 | * implementation takes ownership of |task|. The |task| cannot be nested
59 | * within other task executions.
60 | *
61 | * Requires that |TaskRunner::NonNestableTasksEnabled()| is true.
62 | */
63 | virtual void PostNonNestableTask(std::unique_ptr task) {}
64 |
65 | /**
66 | * Schedules a task to be invoked by this TaskRunner. The task is scheduled
67 | * after the given number of seconds |delay_in_seconds|. The TaskRunner
68 | * implementation takes ownership of |task|.
69 | */
70 | virtual void PostDelayedTask(std::unique_ptr task,
71 | double delay_in_seconds) = 0;
72 |
73 | /**
74 | * Schedules an idle task to be invoked by this TaskRunner. The task is
75 | * scheduled when the embedder is idle. Requires that
76 | * |TaskRunner::IdleTasksEnabled()| is true. Idle tasks may be reordered
77 | * relative to other task types and may be starved for an arbitrarily long
78 | * time if no idle time is available. The TaskRunner implementation takes
79 | * ownership of |task|.
80 | */
81 | virtual void PostIdleTask(std::unique_ptr task) = 0;
82 |
83 | /**
84 | * Returns true if idle tasks are enabled for this TaskRunner.
85 | */
86 | virtual bool IdleTasksEnabled() = 0;
87 |
88 | /**
89 | * Returns true if non-nestable tasks are enabled for this TaskRunner.
90 | */
91 | virtual bool NonNestableTasksEnabled() const { return false; }
92 |
93 | TaskRunner() = default;
94 | virtual ~TaskRunner() = default;
95 |
96 | private:
97 | TaskRunner(const TaskRunner&) = delete;
98 | TaskRunner& operator=(const TaskRunner&) = delete;
99 | };
100 |
101 | /**
102 | * The interface represents complex arguments to trace events.
103 | */
104 | class ConvertableToTraceFormat {
105 | public:
106 | virtual ~ConvertableToTraceFormat() = default;
107 |
108 | /**
109 | * Append the class info to the provided |out| string. The appended
110 | * data must be a valid JSON object. Strings must be properly quoted, and
111 | * escaped. There is no processing applied to the content after it is
112 | * appended.
113 | */
114 | virtual void AppendAsTraceFormat(std::string* out) const = 0;
115 | };
116 |
117 | /**
118 | * V8 Tracing controller.
119 | *
120 | * Can be implemented by an embedder to record trace events from V8.
121 | */
122 | class TracingController {
123 | public:
124 | virtual ~TracingController() = default;
125 |
126 | /**
127 | * Called by TRACE_EVENT* macros, don't call this directly.
128 | * The name parameter is a category group for example:
129 | * TRACE_EVENT0("v8,parse", "V8.Parse")
130 | * The pointer returned points to a value with zero or more of the bits
131 | * defined in CategoryGroupEnabledFlags.
132 | **/
133 | virtual const uint8_t* GetCategoryGroupEnabled(const char* name) {
134 | static uint8_t no = 0;
135 | return &no;
136 | }
137 |
138 | /**
139 | * Adds a trace event to the platform tracing system. These function calls are
140 | * usually the result of a TRACE_* macro from trace_event_common.h when
141 | * tracing and the category of the particular trace are enabled. It is not
142 | * advisable to call these functions on their own; they are really only meant
143 | * to be used by the trace macros. The returned handle can be used by
144 | * UpdateTraceEventDuration to update the duration of COMPLETE events.
145 | */
146 | virtual uint64_t AddTraceEvent(
147 | char phase, const uint8_t* category_enabled_flag, const char* name,
148 | const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
149 | const char** arg_names, const uint8_t* arg_types,
150 | const uint64_t* arg_values,
151 | std::unique_ptr* arg_convertables,
152 | unsigned int flags) {
153 | return 0;
154 | }
155 | virtual uint64_t AddTraceEventWithTimestamp(
156 | char phase, const uint8_t* category_enabled_flag, const char* name,
157 | const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
158 | const char** arg_names, const uint8_t* arg_types,
159 | const uint64_t* arg_values,
160 | std::unique_ptr* arg_convertables,
161 | unsigned int flags, int64_t timestamp) {
162 | return 0;
163 | }
164 |
165 | /**
166 | * Sets the duration field of a COMPLETE trace event. It must be called with
167 | * the handle returned from AddTraceEvent().
168 | **/
169 | virtual void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
170 | const char* name, uint64_t handle) {}
171 |
172 | class TraceStateObserver {
173 | public:
174 | virtual ~TraceStateObserver() = default;
175 | virtual void OnTraceEnabled() = 0;
176 | virtual void OnTraceDisabled() = 0;
177 | };
178 |
179 | /** Adds tracing state change observer. */
180 | virtual void AddTraceStateObserver(TraceStateObserver*) {}
181 |
182 | /** Removes tracing state change observer. */
183 | virtual void RemoveTraceStateObserver(TraceStateObserver*) {}
184 | };
185 |
186 | /**
187 | * A V8 memory page allocator.
188 | *
189 | * Can be implemented by an embedder to manage large host OS allocations.
190 | */
191 | class PageAllocator {
192 | public:
193 | virtual ~PageAllocator() = default;
194 |
195 | /**
196 | * Gets the page granularity for AllocatePages and FreePages. Addresses and
197 | * lengths for those calls should be multiples of AllocatePageSize().
198 | */
199 | virtual size_t AllocatePageSize() = 0;
200 |
201 | /**
202 | * Gets the page granularity for SetPermissions and ReleasePages. Addresses
203 | * and lengths for those calls should be multiples of CommitPageSize().
204 | */
205 | virtual size_t CommitPageSize() = 0;
206 |
207 | /**
208 | * Sets the random seed so that GetRandomMmapAddr() will generate repeatable
209 | * sequences of random mmap addresses.
210 | */
211 | virtual void SetRandomMmapSeed(int64_t seed) = 0;
212 |
213 | /**
214 | * Returns a randomized address, suitable for memory allocation under ASLR.
215 | * The address will be aligned to AllocatePageSize.
216 | */
217 | virtual void* GetRandomMmapAddr() = 0;
218 |
219 | /**
220 | * Memory permissions.
221 | */
222 | enum Permission {
223 | kNoAccess,
224 | kRead,
225 | kReadWrite,
226 | // TODO(hpayer): Remove this flag. Memory should never be rwx.
227 | kReadWriteExecute,
228 | kReadExecute
229 | };
230 |
231 | /**
232 | * Allocates memory in range with the given alignment and permission.
233 | */
234 | virtual void* AllocatePages(void* address, size_t length, size_t alignment,
235 | Permission permissions) = 0;
236 |
237 | /**
238 | * Frees memory in a range that was allocated by a call to AllocatePages.
239 | */
240 | virtual bool FreePages(void* address, size_t length) = 0;
241 |
242 | /**
243 | * Releases memory in a range that was allocated by a call to AllocatePages.
244 | */
245 | virtual bool ReleasePages(void* address, size_t length,
246 | size_t new_length) = 0;
247 |
248 | /**
249 | * Sets permissions on pages in an allocated range.
250 | */
251 | virtual bool SetPermissions(void* address, size_t length,
252 | Permission permissions) = 0;
253 |
254 | /**
255 | * Frees memory in the given [address, address + size) range. address and size
256 | * should be operating system page-aligned. The next write to this
257 | * memory area brings the memory transparently back.
258 | */
259 | virtual bool DiscardSystemPages(void* address, size_t size) { return true; }
260 | };
261 |
262 | /**
263 | * V8 Platform abstraction layer.
264 | *
265 | * The embedder has to provide an implementation of this interface before
266 | * initializing the rest of V8.
267 | */
268 | class Platform {
269 | public:
270 | virtual ~Platform() = default;
271 |
272 | /**
273 | * Allows the embedder to manage memory page allocations.
274 | */
275 | virtual PageAllocator* GetPageAllocator() {
276 | // TODO(bbudge) Make this abstract after all embedders implement this.
277 | return nullptr;
278 | }
279 |
280 | /**
281 | * Enables the embedder to respond in cases where V8 can't allocate large
282 | * blocks of memory. V8 retries the failed allocation once after calling this
283 | * method. On success, execution continues; otherwise V8 exits with a fatal
284 | * error.
285 | * Embedder overrides of this function must NOT call back into V8.
286 | */
287 | virtual void OnCriticalMemoryPressure() {
288 | // TODO(bbudge) Remove this when embedders override the following method.
289 | // See crbug.com/634547.
290 | }
291 |
292 | /**
293 | * Enables the embedder to respond in cases where V8 can't allocate large
294 | * memory regions. The |length| parameter is the amount of memory needed.
295 | * Returns true if memory is now available. Returns false if no memory could
296 | * be made available. V8 will retry allocations until this method returns
297 | * false.
298 | *
299 | * Embedder overrides of this function must NOT call back into V8.
300 | */
301 | virtual bool OnCriticalMemoryPressure(size_t length) { return false; }
302 |
303 | /**
304 | * Gets the number of worker threads used by
305 | * Call(BlockingTask)OnWorkerThread(). This can be used to estimate the number
306 | * of tasks a work package should be split into. A return value of 0 means
307 | * that there are no worker threads available. Note that a value of 0 won't
308 | * prohibit V8 from posting tasks using |CallOnWorkerThread|.
309 | */
310 | virtual int NumberOfWorkerThreads() = 0;
311 |
312 | /**
313 | * Returns a TaskRunner which can be used to post a task on the foreground.
314 | * This function should only be called from a foreground thread.
315 | */
316 | virtual std::shared_ptr GetForegroundTaskRunner(
317 | Isolate* isolate) = 0;
318 |
319 | /**
320 | * Schedules a task to be invoked on a worker thread.
321 | */
322 | virtual void CallOnWorkerThread(std::unique_ptr task) = 0;
323 |
324 | /**
325 | * Schedules a task that blocks the main thread to be invoked with
326 | * high-priority on a worker thread.
327 | */
328 | virtual void CallBlockingTaskOnWorkerThread(std::unique_ptr task) {
329 | // Embedders may optionally override this to process these tasks in a high
330 | // priority pool.
331 | CallOnWorkerThread(std::move(task));
332 | }
333 |
334 | /**
335 | * Schedules a task to be invoked on a worker thread after |delay_in_seconds|
336 | * expires.
337 | */
338 | virtual void CallDelayedOnWorkerThread(std::unique_ptr