diff --git a/calclib/.gitignore b/calclib/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/calclib/.gitignore @@ -0,0 +1 @@ +/build diff --git a/calclib/.gradle/2.14.1/taskArtifacts/cache.properties b/calclib/.gradle/2.14.1/taskArtifacts/cache.properties new file mode 100644 index 0000000..786abcc --- /dev/null +++ b/calclib/.gradle/2.14.1/taskArtifacts/cache.properties @@ -0,0 +1 @@ +#Tue Aug 08 14:58:38 EEST 2017 diff --git a/calclib/.gradle/2.14.1/taskArtifacts/cache.properties.lock b/calclib/.gradle/2.14.1/taskArtifacts/cache.properties.lock new file mode 100644 index 0000000..874e3d7 Binary files /dev/null and b/calclib/.gradle/2.14.1/taskArtifacts/cache.properties.lock differ diff --git a/calclib/.gradle/2.14.1/taskArtifacts/compilationState.bin b/calclib/.gradle/2.14.1/taskArtifacts/compilationState.bin new file mode 100644 index 0000000..33d1060 Binary files /dev/null and b/calclib/.gradle/2.14.1/taskArtifacts/compilationState.bin differ diff --git a/calclib/.gradle/2.14.1/taskArtifacts/fileHashes.bin b/calclib/.gradle/2.14.1/taskArtifacts/fileHashes.bin new file mode 100644 index 0000000..869a172 Binary files /dev/null and b/calclib/.gradle/2.14.1/taskArtifacts/fileHashes.bin differ diff --git a/calclib/.gradle/2.14.1/taskArtifacts/fileSnapshots.bin b/calclib/.gradle/2.14.1/taskArtifacts/fileSnapshots.bin new file mode 100644 index 0000000..15ae02d Binary files /dev/null and b/calclib/.gradle/2.14.1/taskArtifacts/fileSnapshots.bin differ diff --git a/calclib/.gradle/2.14.1/taskArtifacts/fileSnapshotsToTreeSnapshotsIndex.bin b/calclib/.gradle/2.14.1/taskArtifacts/fileSnapshotsToTreeSnapshotsIndex.bin new file mode 100644 index 0000000..93f384a Binary files /dev/null and b/calclib/.gradle/2.14.1/taskArtifacts/fileSnapshotsToTreeSnapshotsIndex.bin differ diff --git a/calclib/.gradle/2.14.1/taskArtifacts/taskArtifacts.bin b/calclib/.gradle/2.14.1/taskArtifacts/taskArtifacts.bin new file mode 100644 index 0000000..c0d6115 Binary files /dev/null and b/calclib/.gradle/2.14.1/taskArtifacts/taskArtifacts.bin differ diff --git a/calclib/.gradle/2.14.1/tasks/_compileDebugJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.bin b/calclib/.gradle/2.14.1/tasks/_compileDebugJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.bin new file mode 100644 index 0000000..52d643f Binary files /dev/null and b/calclib/.gradle/2.14.1/tasks/_compileDebugJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.bin differ diff --git a/calclib/.gradle/2.14.1/tasks/_compileDebugJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.lock b/calclib/.gradle/2.14.1/tasks/_compileDebugJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.lock new file mode 100644 index 0000000..6142967 Binary files /dev/null and b/calclib/.gradle/2.14.1/tasks/_compileDebugJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.lock differ diff --git a/calclib/.gradle/2.14.1/tasks/_compileDebugJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.bin b/calclib/.gradle/2.14.1/tasks/_compileDebugJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.bin new file mode 100644 index 0000000..eb29afb Binary files /dev/null and b/calclib/.gradle/2.14.1/tasks/_compileDebugJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.bin differ diff --git a/calclib/.gradle/2.14.1/tasks/_compileDebugJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.lock b/calclib/.gradle/2.14.1/tasks/_compileDebugJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.lock new file mode 100644 index 0000000..b9d17be Binary files /dev/null and b/calclib/.gradle/2.14.1/tasks/_compileDebugJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.lock differ diff --git a/calclib/.gradle/2.14.1/tasks/_compileReleaseJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.bin b/calclib/.gradle/2.14.1/tasks/_compileReleaseJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.bin new file mode 100644 index 0000000..48ff32b Binary files /dev/null and b/calclib/.gradle/2.14.1/tasks/_compileReleaseJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.bin differ diff --git a/calclib/.gradle/2.14.1/tasks/_compileReleaseJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.lock b/calclib/.gradle/2.14.1/tasks/_compileReleaseJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.lock new file mode 100644 index 0000000..6bf676a Binary files /dev/null and b/calclib/.gradle/2.14.1/tasks/_compileReleaseJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.lock differ diff --git a/calclib/.gradle/2.14.1/tasks/_compileReleaseJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.bin b/calclib/.gradle/2.14.1/tasks/_compileReleaseJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.bin new file mode 100644 index 0000000..eb29afb Binary files /dev/null and b/calclib/.gradle/2.14.1/tasks/_compileReleaseJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.bin differ diff --git a/calclib/.gradle/2.14.1/tasks/_compileReleaseJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.lock b/calclib/.gradle/2.14.1/tasks/_compileReleaseJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.lock new file mode 100644 index 0000000..e9ad769 Binary files /dev/null and b/calclib/.gradle/2.14.1/tasks/_compileReleaseJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.lock differ diff --git a/calclib/.idea/compiler.xml b/calclib/.idea/compiler.xml new file mode 100644 index 0000000..96cc43e --- /dev/null +++ b/calclib/.idea/compiler.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/calclib/.idea/copyright/profiles_settings.xml b/calclib/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/calclib/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/calclib/.idea/gradle.xml b/calclib/.idea/gradle.xml new file mode 100644 index 0000000..47bd81f --- /dev/null +++ b/calclib/.idea/gradle.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/calclib/.idea/misc.xml b/calclib/.idea/misc.xml new file mode 100644 index 0000000..7e15d9d --- /dev/null +++ b/calclib/.idea/misc.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/calclib/.idea/modules.xml b/calclib/.idea/modules.xml new file mode 100644 index 0000000..edd743e --- /dev/null +++ b/calclib/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/calclib/.idea/runConfigurations.xml b/calclib/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/calclib/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/calclib/.idea/workspace.xml b/calclib/.idea/workspace.xml new file mode 100644 index 0000000..bf22917 --- /dev/null +++ b/calclib/.idea/workspace.xml @@ -0,0 +1,2025 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1502194549378 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/calclib/build.gradle b/calclib/build.gradle new file mode 100644 index 0000000..b505838 --- /dev/null +++ b/calclib/build.gradle @@ -0,0 +1,104 @@ +apply plugin: 'com.android.model.library' + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle-experimental:0.8.1' + } +} + +allprojects { + repositories { + jcenter() + } +} + +model { + android { + compileSdkVersion = 23 + buildToolsVersion = "25.0.2" + + defaultConfig.with { + minSdkVersion.apiLevel = 17 + targetSdkVersion.apiLevel = 25 + } + + lintOptions.with { + abortOnError = false + } + } + + android.buildTypes { + release { + minifyEnabled = false + } + } + + android.ndk { + cppFlags.addAll(["-I${file("src/main/")}".toString(), + "-I${file("src/main/cpp/include")}".toString() + ]) + + CFlags.addAll(["-I${file("src/main/cpp")}".toString(), + "-I${file("src/main/cpp/include")}".toString() + ]) + + cppFlags.addAll(["-std=c++11", ])//"-fexceptions", "-fno-builtin-stpcpy",]) + + CFlags.addAll(["-Wno-error=format-security", "-g", "-fno-builtin-stpcpy"]) + +// ldLibs.addAll(["android", "dl", "log", "atomic", "z"]) + + ldFlags.addAll(["-Wl,--allow-multiple-definition"]) + + toolchain = "clang" + stl = "c++_static" + +// abiFilters.addAll(["armeabi-v7a", "x86", "arm64-v8a"]) + abiFilters.addAll(["x86"]) +// abiFilters.addAll(["arm64-v8a", "x86", "armeabi-v7a"]) + moduleName = "calcLib" + } + + android.sources { + main { + java { + source { + srcDirs 'src/main/java' + } + } + + jni { + source { + srcDirs 'src/main/cpp' + } + + exportedHeaders { + srcDir "src/main/cpp/include" + } + + dependencies { + library "NativeScript" linkage "shared" + } + } + } + } + + repositories { + prebuilt(PrebuiltLibraries) { + NativeScript { + headers.srcDir "src/main/cpp/include" + binaries.withType(SharedLibraryBinary) { + def filep = file("src/main/libs/${targetPlatform.getName()}/libNativeScript.so") + def exists = filep.exists() + if (exists) { + sharedLibraryFile = filep + } + println "~~~~~ FILE PATH: src/main/libs/${targetPlatform.getName()}/libNativeScript.so exists: ${exists}" + } + } + } + } +} diff --git a/calclib/build.properties b/calclib/build.properties new file mode 100644 index 0000000..715fd3b --- /dev/null +++ b/calclib/build.properties @@ -0,0 +1 @@ +android.useDeprecatedNdk = true \ No newline at end of file diff --git a/calclib/calclib.iml b/calclib/calclib.iml new file mode 100644 index 0000000..fab99ca --- /dev/null +++ b/calclib/calclib.iml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/calclib/gradle/wrapper/gradle-wrapper.jar b/calclib/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..8c0fb64 Binary files /dev/null and b/calclib/gradle/wrapper/gradle-wrapper.jar differ diff --git a/calclib/gradle/wrapper/gradle-wrapper.properties b/calclib/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..f336f77 --- /dev/null +++ b/calclib/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Apr 12 10:33:26 EEST 2016 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip diff --git a/calclib/gradlew b/calclib/gradlew new file mode 100644 index 0000000..91a7e26 --- /dev/null +++ b/calclib/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/calclib/gradlew.bat b/calclib/gradlew.bat new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ b/calclib/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/calclib/local.properties b/calclib/local.properties new file mode 100644 index 0000000..2f47f64 --- /dev/null +++ b/calclib/local.properties @@ -0,0 +1,12 @@ +## This file is automatically generated by Android Studio. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. +# +# Location of the SDK. This is only used by Gradle. +# For customization when using a Version Control System, please read the +# header note. +#Tue Aug 08 15:19:46 EEST 2017 +ndk.dir=C\:\\NDK\\ndk12b +sdk.dir=C\:\\Android\\sdk_2.0 diff --git a/calclib/proguard-rules.pro b/calclib/proguard-rules.pro new file mode 100644 index 0000000..28b3f2a --- /dev/null +++ b/calclib/proguard-rules.pro @@ -0,0 +1,25 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in C:\Android\sdk_2.0/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/calclib/src/main/AndroidManifest.xml b/calclib/src/main/AndroidManifest.xml new file mode 100644 index 0000000..41b0ef3 --- /dev/null +++ b/calclib/src/main/AndroidManifest.xml @@ -0,0 +1,13 @@ + + + + + + + diff --git a/calclib/src/main/cpp/Calc.cpp b/calclib/src/main/cpp/Calc.cpp new file mode 100644 index 0000000..3c90a0c --- /dev/null +++ b/calclib/src/main/cpp/Calc.cpp @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include "include/v8.h" + +void AddFuncCallback(const v8::FunctionCallbackInfo& args); + +extern "C" void NSMain(const v8::FunctionCallbackInfo& args) +{ + auto isolate = args.GetIsolate(); + + auto len = args.Length(); + + if (len != 5) + { + auto errMsg = v8::String::NewFromUtf8(isolate, "Wrong number of arguments (expected 5)"); + auto err = v8::Exception::Error(errMsg); + isolate->ThrowException(err); + return; + } + + auto exports = args[1].As(); + + auto ft = v8::FunctionTemplate::New(isolate, AddFuncCallback); + auto ctx = isolate->GetCurrentContext(); + auto maybeFunc = ft->GetFunction(ctx); + if (maybeFunc.IsEmpty()) + { + auto errMsg = v8::String::NewFromUtf8(isolate, "Cannot create 'add' function"); + auto err = v8::Exception::Error(errMsg); + isolate->ThrowException(err); + return; + } + + auto func = maybeFunc.ToLocalChecked(); + + auto propName = v8::String::NewFromUtf8(isolate, "add"); + auto result = exports->Set(ctx, propName, func); +} + +void AddFuncCallback(const v8::FunctionCallbackInfo& args) +{ + int result = 0; + + auto len = args.Length(); + + if ((len == 2) && args[0]->IsInt32() && args[1]->IsInt32()) + { + result = args[0]->Int32Value() + args[1]->Int32Value(); + } + + args.GetReturnValue().Set(v8::Int32::New(args.GetIsolate(), result)); +} \ No newline at end of file diff --git a/calclib/src/main/cpp/include/V8NativeScriptExtension.h b/calclib/src/main/cpp/include/V8NativeScriptExtension.h new file mode 100644 index 0000000..53b721d --- /dev/null +++ b/calclib/src/main/cpp/include/V8NativeScriptExtension.h @@ -0,0 +1,25 @@ +#include "v8.h" + +namespace v8 { + + class NativeScriptExtension { + public: + static uint8_t* GetAddress(const v8::Local& obj); + + static v8::Local* GetClosureObjects(v8::Isolate *isolate, const v8::Local& func, int *length); + + static void ReleaseClosureObjects(v8::Local* closureObjects); + + static void GetAssessorPair(v8::Isolate *isolate, const v8::Local& obj, const v8::Local& propName, v8::Local& getter, v8::Local& setter); + + static v8::Local GetPropertyKeys(v8::Isolate *isolate, const v8::Local& context, const v8::Local& object, bool& success); + + static int GetInternalFieldCount(const v8::Local& object); + + static void CpuFeaturesProbe(bool cross_compile); + private: + NativeScriptExtension(); + + // static v8::internal::Handle GetEnumPropertyKeys(const v8::internal::Handle& object, bool cache_result); + }; +} diff --git a/calclib/src/main/cpp/include/libplatform/libplatform-export.h b/calclib/src/main/cpp/include/libplatform/libplatform-export.h new file mode 100644 index 0000000..1561843 --- /dev/null +++ b/calclib/src/main/cpp/include/libplatform/libplatform-export.h @@ -0,0 +1,29 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_ +#define V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_ + +#if defined(_WIN32) + +#ifdef BUILDING_V8_PLATFORM_SHARED +#define V8_PLATFORM_EXPORT __declspec(dllexport) +#elif USING_V8_PLATFORM_SHARED +#define V8_PLATFORM_EXPORT __declspec(dllimport) +#else +#define V8_PLATFORM_EXPORT +#endif // BUILDING_V8_PLATFORM_SHARED + +#else // defined(_WIN32) + +// Setup for Linux shared library export. +#ifdef BUILDING_V8_PLATFORM_SHARED +#define V8_PLATFORM_EXPORT __attribute__((visibility("default"))) +#else +#define V8_PLATFORM_EXPORT +#endif + +#endif // defined(_WIN32) + +#endif // V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_ diff --git a/calclib/src/main/cpp/include/libplatform/libplatform.h b/calclib/src/main/cpp/include/libplatform/libplatform.h new file mode 100644 index 0000000..55a1020 --- /dev/null +++ b/calclib/src/main/cpp/include/libplatform/libplatform.h @@ -0,0 +1,66 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_LIBPLATFORM_LIBPLATFORM_H_ +#define V8_LIBPLATFORM_LIBPLATFORM_H_ + +#include "libplatform/libplatform-export.h" +#include "libplatform/v8-tracing.h" +#include "v8-platform.h" // NOLINT(build/include) + +namespace v8 { +namespace platform { + +enum class IdleTaskSupport { kDisabled, kEnabled }; + +/** + * Returns a new instance of the default v8::Platform implementation. + * + * The caller will take ownership of the returned pointer. |thread_pool_size| + * is the number of worker threads to allocate for background jobs. If a value + * of zero is passed, a suitable default based on the current number of + * processors online will be chosen. + * If |idle_task_support| is enabled then the platform will accept idle + * tasks (IdleTasksEnabled will return true) and will rely on the embedder + * calling v8::platform::RunIdleTasks to process the idle tasks. + */ +V8_PLATFORM_EXPORT v8::Platform* CreateDefaultPlatform( + int thread_pool_size = 0, + IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled); + +/** + * Pumps the message loop for the given isolate. + * + * The caller has to make sure that this is called from the right thread. + * Returns true if a task was executed, and false otherwise. This call does + * not block if no task is pending. The |platform| has to be created using + * |CreateDefaultPlatform|. + */ +V8_PLATFORM_EXPORT bool PumpMessageLoop(v8::Platform* platform, + v8::Isolate* isolate); + +/** + * Runs pending idle tasks for at most |idle_time_in_seconds| seconds. + * + * The caller has to make sure that this is called from the right thread. + * This call does not block if no task is pending. The |platform| has to be + * created using |CreateDefaultPlatform|. + */ +V8_PLATFORM_EXPORT void RunIdleTasks(v8::Platform* platform, + v8::Isolate* isolate, + double idle_time_in_seconds); + +/** + * Attempts to set the tracing controller for the given platform. + * + * The |platform| has to be created using |CreateDefaultPlatform|. + */ +V8_PLATFORM_EXPORT void SetTracingController( + v8::Platform* platform, + v8::platform::tracing::TracingController* tracing_controller); + +} // namespace platform +} // namespace v8 + +#endif // V8_LIBPLATFORM_LIBPLATFORM_H_ diff --git a/calclib/src/main/cpp/include/libplatform/v8-tracing.h b/calclib/src/main/cpp/include/libplatform/v8-tracing.h new file mode 100644 index 0000000..902f8ea --- /dev/null +++ b/calclib/src/main/cpp/include/libplatform/v8-tracing.h @@ -0,0 +1,270 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_LIBPLATFORM_V8_TRACING_H_ +#define V8_LIBPLATFORM_V8_TRACING_H_ + +#include +#include +#include +#include + +#include "libplatform/libplatform-export.h" +#include "v8-platform.h" // NOLINT(build/include) + +namespace v8 { + +namespace base { +class Mutex; +} // namespace base + +namespace platform { +namespace tracing { + +const int kTraceMaxNumArgs = 2; + +class V8_PLATFORM_EXPORT TraceObject { + public: + union ArgValue { + bool as_bool; + uint64_t as_uint; + int64_t as_int; + double as_double; + const void* as_pointer; + const char* as_string; + }; + + TraceObject() {} + ~TraceObject(); + void Initialize( + char phase, const uint8_t* category_enabled_flag, const char* name, + const char* scope, uint64_t id, uint64_t bind_id, int num_args, + const char** arg_names, const uint8_t* arg_types, + const uint64_t* arg_values, + std::unique_ptr* arg_convertables, + unsigned int flags); + void UpdateDuration(); + void InitializeForTesting( + char phase, const uint8_t* category_enabled_flag, const char* name, + const char* scope, uint64_t id, uint64_t bind_id, int num_args, + const char** arg_names, const uint8_t* arg_types, + const uint64_t* arg_values, + std::unique_ptr* arg_convertables, + unsigned int flags, int pid, int tid, int64_t ts, int64_t tts, + uint64_t duration, uint64_t cpu_duration); + + int pid() const { return pid_; } + int tid() const { return tid_; } + char phase() const { return phase_; } + const uint8_t* category_enabled_flag() const { + return category_enabled_flag_; + } + const char* name() const { return name_; } + const char* scope() const { return scope_; } + uint64_t id() const { return id_; } + uint64_t bind_id() const { return bind_id_; } + int num_args() const { return num_args_; } + const char** arg_names() { return arg_names_; } + uint8_t* arg_types() { return arg_types_; } + ArgValue* arg_values() { return arg_values_; } + std::unique_ptr* arg_convertables() { + return arg_convertables_; + } + unsigned int flags() const { return flags_; } + int64_t ts() { return ts_; } + int64_t tts() { return tts_; } + uint64_t duration() { return duration_; } + uint64_t cpu_duration() { return cpu_duration_; } + + private: + int pid_; + int tid_; + char phase_; + const char* name_; + const char* scope_; + const uint8_t* category_enabled_flag_; + uint64_t id_; + uint64_t bind_id_; + int num_args_ = 0; + const char* arg_names_[kTraceMaxNumArgs]; + uint8_t arg_types_[kTraceMaxNumArgs]; + ArgValue arg_values_[kTraceMaxNumArgs]; + std::unique_ptr + arg_convertables_[kTraceMaxNumArgs]; + char* parameter_copy_storage_ = nullptr; + unsigned int flags_; + int64_t ts_; + int64_t tts_; + uint64_t duration_; + uint64_t cpu_duration_; + + // Disallow copy and assign + TraceObject(const TraceObject&) = delete; + void operator=(const TraceObject&) = delete; +}; + +class V8_PLATFORM_EXPORT TraceWriter { + public: + TraceWriter() {} + virtual ~TraceWriter() {} + virtual void AppendTraceEvent(TraceObject* trace_event) = 0; + virtual void Flush() = 0; + + static TraceWriter* CreateJSONTraceWriter(std::ostream& stream); + + private: + // Disallow copy and assign + TraceWriter(const TraceWriter&) = delete; + void operator=(const TraceWriter&) = delete; +}; + +class V8_PLATFORM_EXPORT TraceBufferChunk { + public: + explicit TraceBufferChunk(uint32_t seq); + + void Reset(uint32_t new_seq); + bool IsFull() const { return next_free_ == kChunkSize; } + TraceObject* AddTraceEvent(size_t* event_index); + TraceObject* GetEventAt(size_t index) { return &chunk_[index]; } + + uint32_t seq() const { return seq_; } + size_t size() const { return next_free_; } + + static const size_t kChunkSize = 64; + + private: + size_t next_free_ = 0; + TraceObject chunk_[kChunkSize]; + uint32_t seq_; + + // Disallow copy and assign + TraceBufferChunk(const TraceBufferChunk&) = delete; + void operator=(const TraceBufferChunk&) = delete; +}; + +class V8_PLATFORM_EXPORT TraceBuffer { + public: + TraceBuffer() {} + virtual ~TraceBuffer() {} + + virtual TraceObject* AddTraceEvent(uint64_t* handle) = 0; + virtual TraceObject* GetEventByHandle(uint64_t handle) = 0; + virtual bool Flush() = 0; + + static const size_t kRingBufferChunks = 1024; + + static TraceBuffer* CreateTraceBufferRingBuffer(size_t max_chunks, + TraceWriter* trace_writer); + + private: + // Disallow copy and assign + TraceBuffer(const TraceBuffer&) = delete; + void operator=(const TraceBuffer&) = delete; +}; + +// Options determines how the trace buffer stores data. +enum TraceRecordMode { + // Record until the trace buffer is full. + RECORD_UNTIL_FULL, + + // Record until the user ends the trace. The trace buffer is a fixed size + // and we use it as a ring buffer during recording. + RECORD_CONTINUOUSLY, + + // Record until the trace buffer is full, but with a huge buffer size. + RECORD_AS_MUCH_AS_POSSIBLE, + + // Echo to console. Events are discarded. + ECHO_TO_CONSOLE, +}; + +class V8_PLATFORM_EXPORT TraceConfig { + public: + typedef std::vector StringList; + + static TraceConfig* CreateDefaultTraceConfig(); + + TraceConfig() : enable_systrace_(false), enable_argument_filter_(false) {} + TraceRecordMode GetTraceRecordMode() const { return record_mode_; } + bool IsSystraceEnabled() const { return enable_systrace_; } + bool IsArgumentFilterEnabled() const { return enable_argument_filter_; } + + void SetTraceRecordMode(TraceRecordMode mode) { record_mode_ = mode; } + void EnableSystrace() { enable_systrace_ = true; } + void EnableArgumentFilter() { enable_argument_filter_ = true; } + + void AddIncludedCategory(const char* included_category); + + bool IsCategoryGroupEnabled(const char* category_group) const; + + private: + TraceRecordMode record_mode_; + bool enable_systrace_ : 1; + bool enable_argument_filter_ : 1; + StringList included_categories_; + + // Disallow copy and assign + TraceConfig(const TraceConfig&) = delete; + void operator=(const TraceConfig&) = delete; +}; + +class V8_PLATFORM_EXPORT TracingController { + public: + enum Mode { DISABLED = 0, RECORDING_MODE }; + + // The pointer returned from GetCategoryGroupEnabledInternal() points to a + // value with zero or more of the following bits. Used in this class only. + // The TRACE_EVENT macros should only use the value as a bool. + // These values must be in sync with macro values in TraceEvent.h in Blink. + enum CategoryGroupEnabledFlags { + // Category group enabled for the recording mode. + ENABLED_FOR_RECORDING = 1 << 0, + // Category group enabled by SetEventCallbackEnabled(). + ENABLED_FOR_EVENT_CALLBACK = 1 << 2, + // Category group enabled to export events to ETW. + ENABLED_FOR_ETW_EXPORT = 1 << 3 + }; + + TracingController(); + ~TracingController(); + void Initialize(TraceBuffer* trace_buffer); + const uint8_t* GetCategoryGroupEnabled(const char* category_group); + static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag); + uint64_t AddTraceEvent( + char phase, const uint8_t* category_enabled_flag, const char* name, + const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args, + const char** arg_names, const uint8_t* arg_types, + const uint64_t* arg_values, + std::unique_ptr* arg_convertables, + unsigned int flags); + void UpdateTraceEventDuration(const uint8_t* category_enabled_flag, + const char* name, uint64_t handle); + + void StartTracing(TraceConfig* trace_config); + void StopTracing(); + + void AddTraceStateObserver(Platform::TraceStateObserver* observer); + void RemoveTraceStateObserver(Platform::TraceStateObserver* observer); + + private: + const uint8_t* GetCategoryGroupEnabledInternal(const char* category_group); + void UpdateCategoryGroupEnabledFlag(size_t category_index); + void UpdateCategoryGroupEnabledFlags(); + + std::unique_ptr trace_buffer_; + std::unique_ptr trace_config_; + std::unique_ptr mutex_; + std::unordered_set observers_; + Mode mode_ = DISABLED; + + // Disallow copy and assign + TracingController(const TracingController&) = delete; + void operator=(const TracingController&) = delete; +}; + +} // namespace tracing +} // namespace platform +} // namespace v8 + +#endif // V8_LIBPLATFORM_V8_TRACING_H_ diff --git a/calclib/src/main/cpp/include/v8-debug.h b/calclib/src/main/cpp/include/v8-debug.h new file mode 100644 index 0000000..6385a31 --- /dev/null +++ b/calclib/src/main/cpp/include/v8-debug.h @@ -0,0 +1,287 @@ +// Copyright 2008 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_V8_DEBUG_H_ +#define V8_V8_DEBUG_H_ + +#include "v8.h" // NOLINT(build/include) + +/** + * Debugger support for the V8 JavaScript engine. + */ +namespace v8 { + +// Debug events which can occur in the V8 JavaScript engine. +enum DebugEvent { + Break = 1, + Exception = 2, + NewFunction = 3, + BeforeCompile = 4, + AfterCompile = 5, + CompileError = 6, + AsyncTaskEvent = 7, +}; + +class V8_EXPORT Debug { + public: + /** + * A client object passed to the v8 debugger whose ownership will be taken by + * it. v8 is always responsible for deleting the object. + */ + class ClientData { + public: + virtual ~ClientData() {} + }; + + + /** + * A message object passed to the debug message handler. + */ + class Message { + public: + /** + * Check type of message. + */ + virtual bool IsEvent() const = 0; + virtual bool IsResponse() const = 0; + virtual DebugEvent GetEvent() const = 0; + + /** + * Indicate whether this is a response to a continue command which will + * start the VM running after this is processed. + */ + virtual bool WillStartRunning() const = 0; + + /** + * Access to execution state and event data. Don't store these cross + * callbacks as their content becomes invalid. These objects are from the + * debugger event that started the debug message loop. + */ + virtual Local GetExecutionState() const = 0; + virtual Local GetEventData() const = 0; + + /** + * Get the debugger protocol JSON. + */ + virtual Local GetJSON() const = 0; + + /** + * Get the context active when the debug event happened. Note this is not + * the current active context as the JavaScript part of the debugger is + * running in its own context which is entered at this point. + */ + virtual Local GetEventContext() const = 0; + + /** + * Client data passed with the corresponding request if any. This is the + * client_data data value passed into Debug::SendCommand along with the + * request that led to the message or NULL if the message is an event. The + * debugger takes ownership of the data and will delete it even if there is + * no message handler. + */ + virtual ClientData* GetClientData() const = 0; + + virtual Isolate* GetIsolate() const = 0; + + virtual ~Message() {} + }; + + + /** + * An event details object passed to the debug event listener. + */ + class EventDetails { + public: + /** + * Event type. + */ + virtual DebugEvent GetEvent() const = 0; + + /** + * Access to execution state and event data of the debug event. Don't store + * these cross callbacks as their content becomes invalid. + */ + virtual Local GetExecutionState() const = 0; + virtual Local GetEventData() const = 0; + + /** + * Get the context active when the debug event happened. Note this is not + * the current active context as the JavaScript part of the debugger is + * running in its own context which is entered at this point. + */ + virtual Local GetEventContext() const = 0; + + /** + * Client data passed with the corresponding callback when it was + * registered. + */ + virtual Local GetCallbackData() const = 0; + + /** + * Client data passed to DebugBreakForCommand function. The + * debugger takes ownership of the data and will delete it even if + * there is no message handler. + */ + virtual ClientData* GetClientData() const = 0; + + virtual Isolate* GetIsolate() const = 0; + + virtual ~EventDetails() {} + }; + + /** + * Debug event callback function. + * + * \param event_details object providing information about the debug event + * + * A EventCallback2 does not take possession of the event data, + * and must not rely on the data persisting after the handler returns. + */ + typedef void (*EventCallback)(const EventDetails& event_details); + + /** + * Debug message callback function. + * + * \param message the debug message handler message object + * + * A MessageHandler2 does not take possession of the message data, + * and must not rely on the data persisting after the handler returns. + */ + typedef void (*MessageHandler)(const Message& message); + + /** + * Callback function for the host to ensure debug messages are processed. + */ + typedef void (*DebugMessageDispatchHandler)(); + + static bool SetDebugEventListener(Isolate* isolate, EventCallback that, + Local data = Local()); + + // Schedule a debugger break to happen when JavaScript code is run + // in the given isolate. + static void DebugBreak(Isolate* isolate); + + // Remove scheduled debugger break in given isolate if it has not + // happened yet. + static void CancelDebugBreak(Isolate* isolate); + + // Check if a debugger break is scheduled in the given isolate. + static bool CheckDebugBreak(Isolate* isolate); + + // Message based interface. The message protocol is JSON. + static void SetMessageHandler(Isolate* isolate, MessageHandler handler); + + static void SendCommand(Isolate* isolate, + const uint16_t* command, int length, + ClientData* client_data = NULL); + + /** + * Run a JavaScript function in the debugger. + * \param fun the function to call + * \param data passed as second argument to the function + * With this call the debugger is entered and the function specified is called + * with the execution state as the first argument. This makes it possible to + * get access to information otherwise not available during normal JavaScript + * execution e.g. details on stack frames. Receiver of the function call will + * be the debugger context global object, however this is a subject to change. + * The following example shows a JavaScript function which when passed to + * v8::Debug::Call will return the current line of JavaScript execution. + * + * \code + * function frame_source_line(exec_state) { + * return exec_state.frame(0).sourceLine(); + * } + * \endcode + */ + // TODO(dcarney): data arg should be a MaybeLocal + static MaybeLocal Call(Local context, + v8::Local fun, + Local data = Local()); + + /** + * Returns a mirror object for the given object. + */ + static MaybeLocal GetMirror(Local context, + v8::Local obj); + + /** + * Makes V8 process all pending debug messages. + * + * From V8 point of view all debug messages come asynchronously (e.g. from + * remote debugger) but they all must be handled synchronously: V8 cannot + * do 2 things at one time so normal script execution must be interrupted + * for a while. + * + * Generally when message arrives V8 may be in one of 3 states: + * 1. V8 is running script; V8 will automatically interrupt and process all + * pending messages; + * 2. V8 is suspended on debug breakpoint; in this state V8 is dedicated + * to reading and processing debug messages; + * 3. V8 is not running at all or has called some long-working C++ function; + * by default it means that processing of all debug messages will be deferred + * until V8 gets control again; however, embedding application may improve + * this by manually calling this method. + * + * Technically this method in many senses is equivalent to executing empty + * script: + * 1. It does nothing except for processing all pending debug messages. + * 2. It should be invoked with the same precautions and from the same context + * as V8 script would be invoked from, because: + * a. with "evaluate" command it can do whatever normal script can do, + * including all native calls; + * b. no other thread should call V8 while this method is running + * (v8::Locker may be used here). + * + * "Evaluate" debug command behavior currently is not specified in scope + * of this method. + */ + static void ProcessDebugMessages(Isolate* isolate); + + /** + * Debugger is running in its own context which is entered while debugger + * messages are being dispatched. This is an explicit getter for this + * debugger context. Note that the content of the debugger context is subject + * to change. The Context exists only when the debugger is active, i.e. at + * least one DebugEventListener or MessageHandler is set. + */ + static Local GetDebugContext(Isolate* isolate); + + /** + * While in the debug context, this method returns the top-most non-debug + * context, if it exists. + */ + static MaybeLocal GetDebuggedContext(Isolate* isolate); + + /** + * Enable/disable LiveEdit functionality for the given Isolate + * (default Isolate if not provided). V8 will abort if LiveEdit is + * unexpectedly used. LiveEdit is enabled by default. + */ + static void SetLiveEditEnabled(Isolate* isolate, bool enable); + + /** + * Returns array of internal properties specific to the value type. Result has + * the following format: [, ,...,, ]. Result array + * will be allocated in the current context. + */ + static MaybeLocal GetInternalProperties(Isolate* isolate, + Local value); + + /** + * Defines if the ES2015 tail call elimination feature is enabled or not. + * The change of this flag triggers deoptimization of all functions that + * contain calls at tail position. + */ + static bool IsTailCallEliminationEnabled(Isolate* isolate); + static void SetTailCallEliminationEnabled(Isolate* isolate, bool enabled); +}; + + +} // namespace v8 + + +#undef EXPORT + + +#endif // V8_V8_DEBUG_H_ diff --git a/calclib/src/main/cpp/include/v8-experimental.h b/calclib/src/main/cpp/include/v8-experimental.h new file mode 100644 index 0000000..1773345 --- /dev/null +++ b/calclib/src/main/cpp/include/v8-experimental.h @@ -0,0 +1,58 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * This header contains a set of experimental V8 APIs. We hope these will + * become a part of standard V8, but they may also be removed if we deem the + * experiment to not be successul. + */ +#ifndef V8_INCLUDE_V8_EXPERIMENTAL_H_ +#define V8_INCLUDE_V8_EXPERIMENTAL_H_ + +#include "v8.h" // NOLINT(build/include) + +namespace v8 { +namespace experimental { + +// Allow the embedder to construct accessors that V8 can compile and use +// directly, without jumping into the runtime. +class V8_EXPORT FastAccessorBuilder { + public: + struct ValueId { + size_t value_id; + }; + struct LabelId { + size_t label_id; + }; + + static FastAccessorBuilder* New(Isolate* isolate); + + ValueId IntegerConstant(int int_constant); + ValueId GetReceiver(); + ValueId LoadInternalField(ValueId value_id, int field_no); + ValueId LoadInternalFieldUnchecked(ValueId value_id, int field_no); + ValueId LoadValue(ValueId value_id, int offset); + ValueId LoadObject(ValueId value_id, int offset); + ValueId ToSmi(ValueId value_id); + + void ReturnValue(ValueId value_id); + void CheckFlagSetOrReturnNull(ValueId value_id, int mask); + void CheckNotZeroOrReturnNull(ValueId value_id); + LabelId MakeLabel(); + void SetLabel(LabelId label_id); + void Goto(LabelId label_id); + void CheckNotZeroOrJump(ValueId value_id, LabelId label_id); + ValueId Call(v8::FunctionCallback callback, ValueId value_id); + + private: + FastAccessorBuilder() = delete; + FastAccessorBuilder(const FastAccessorBuilder&) = delete; + ~FastAccessorBuilder() = delete; + void operator=(const FastAccessorBuilder&) = delete; +}; + +} // namespace experimental +} // namespace v8 + +#endif // V8_INCLUDE_V8_EXPERIMENTAL_H_ diff --git a/calclib/src/main/cpp/include/v8-platform.h b/calclib/src/main/cpp/include/v8-platform.h new file mode 100644 index 0000000..e115674 --- /dev/null +++ b/calclib/src/main/cpp/include/v8-platform.h @@ -0,0 +1,219 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_V8_PLATFORM_H_ +#define V8_V8_PLATFORM_H_ + +#include +#include +#include +#include + +namespace v8 { + +class Isolate; + +/** + * A Task represents a unit of work. + */ +class Task { + public: + virtual ~Task() = default; + + virtual void Run() = 0; +}; + +/** + * An IdleTask represents a unit of work to be performed in idle time. + * The Run method is invoked with an argument that specifies the deadline in + * seconds returned by MonotonicallyIncreasingTime(). + * The idle task is expected to complete by this deadline. + */ +class IdleTask { + public: + virtual ~IdleTask() = default; + virtual void Run(double deadline_in_seconds) = 0; +}; + +/** + * The interface represents complex arguments to trace events. + */ +class ConvertableToTraceFormat { + public: + virtual ~ConvertableToTraceFormat() = default; + + /** + * Append the class info to the provided |out| string. The appended + * data must be a valid JSON object. Strings must be properly quoted, and + * escaped. There is no processing applied to the content after it is + * appended. + */ + virtual void AppendAsTraceFormat(std::string* out) const = 0; +}; + +/** + * V8 Platform abstraction layer. + * + * The embedder has to provide an implementation of this interface before + * initializing the rest of V8. + */ +class Platform { + public: + /** + * This enum is used to indicate whether a task is potentially long running, + * or causes a long wait. The embedder might want to use this hint to decide + * whether to execute the task on a dedicated thread. + */ + enum ExpectedRuntime { + kShortRunningTask, + kLongRunningTask + }; + + virtual ~Platform() = default; + + /** + * Gets the number of threads that are used to execute background tasks. Is + * used to estimate the number of tasks a work package should be split into. + * A return value of 0 means that there are no background threads available. + * Note that a value of 0 won't prohibit V8 from posting tasks using + * |CallOnBackgroundThread|. + */ + virtual size_t NumberOfAvailableBackgroundThreads() { return 0; } + + /** + * Schedules a task to be invoked on a background thread. |expected_runtime| + * indicates that the task will run a long time. The Platform implementation + * takes ownership of |task|. There is no guarantee about order of execution + * of tasks wrt order of scheduling, nor is there a guarantee about the + * thread the task will be run on. + */ + virtual void CallOnBackgroundThread(Task* task, + ExpectedRuntime expected_runtime) = 0; + + /** + * Schedules a task to be invoked on a foreground thread wrt a specific + * |isolate|. Tasks posted for the same isolate should be execute in order of + * scheduling. The definition of "foreground" is opaque to V8. + */ + virtual void CallOnForegroundThread(Isolate* isolate, Task* task) = 0; + + /** + * Schedules a task to be invoked on a foreground thread wrt a specific + * |isolate| after the given number of seconds |delay_in_seconds|. + * Tasks posted for the same isolate should be execute in order of + * scheduling. The definition of "foreground" is opaque to V8. + */ + virtual void CallDelayedOnForegroundThread(Isolate* isolate, Task* task, + double delay_in_seconds) = 0; + + /** + * Schedules a task to be invoked on a foreground thread wrt a specific + * |isolate| when the embedder is idle. + * Requires that SupportsIdleTasks(isolate) is true. + * Idle tasks may be reordered relative to other task types and may be + * starved for an arbitrarily long time if no idle time is available. + * The definition of "foreground" is opaque to V8. + */ + virtual void CallIdleOnForegroundThread(Isolate* isolate, IdleTask* task) { + // TODO(ulan): Make this function abstract after V8 roll in Chromium. + } + + /** + * Returns true if idle tasks are enabled for the given |isolate|. + */ + virtual bool IdleTasksEnabled(Isolate* isolate) { + // TODO(ulan): Make this function abstract after V8 roll in Chromium. + return false; + } + + /** + * Monotonically increasing time in seconds from an arbitrary fixed point in + * the past. This function is expected to return at least + * millisecond-precision values. For this reason, + * it is recommended that the fixed point be no further in the past than + * the epoch. + **/ + virtual double MonotonicallyIncreasingTime() = 0; + + /** + * Called by TRACE_EVENT* macros, don't call this directly. + * The name parameter is a category group for example: + * TRACE_EVENT0("v8,parse", "V8.Parse") + * The pointer returned points to a value with zero or more of the bits + * defined in CategoryGroupEnabledFlags. + **/ + virtual const uint8_t* GetCategoryGroupEnabled(const char* name) { + static uint8_t no = 0; + return &no; + } + + /** + * Gets the category group name of the given category_enabled_flag pointer. + * Usually used while serliazing TRACE_EVENTs. + **/ + virtual const char* GetCategoryGroupName( + const uint8_t* category_enabled_flag) { + static const char dummy[] = "dummy"; + return dummy; + } + + /** + * Adds a trace event to the platform tracing system. This function call is + * usually the result of a TRACE_* macro from trace_event_common.h when + * tracing and the category of the particular trace are enabled. It is not + * advisable to call this function on its own; it is really only meant to be + * used by the trace macros. The returned handle can be used by + * UpdateTraceEventDuration to update the duration of COMPLETE events. + */ + virtual uint64_t AddTraceEvent( + char phase, const uint8_t* category_enabled_flag, const char* name, + const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args, + const char** arg_names, const uint8_t* arg_types, + const uint64_t* arg_values, unsigned int flags) { + return 0; + } + + /** + * Adds a trace event to the platform tracing system. This function call is + * usually the result of a TRACE_* macro from trace_event_common.h when + * tracing and the category of the particular trace are enabled. It is not + * advisable to call this function on its own; it is really only meant to be + * used by the trace macros. The returned handle can be used by + * UpdateTraceEventDuration to update the duration of COMPLETE events. + */ + virtual uint64_t AddTraceEvent( + char phase, const uint8_t* category_enabled_flag, const char* name, + const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args, + const char** arg_names, const uint8_t* arg_types, + const uint64_t* arg_values, + std::unique_ptr* arg_convertables, + unsigned int flags) { + return AddTraceEvent(phase, category_enabled_flag, name, scope, id, bind_id, + num_args, arg_names, arg_types, arg_values, flags); + } + + /** + * Sets the duration field of a COMPLETE trace event. It must be called with + * the handle returned from AddTraceEvent(). + **/ + virtual void UpdateTraceEventDuration(const uint8_t* category_enabled_flag, + const char* name, uint64_t handle) {} + + class TraceStateObserver { + public: + virtual ~TraceStateObserver() = default; + virtual void OnTraceEnabled() = 0; + virtual void OnTraceDisabled() = 0; + }; + + /** Adds tracing state change observer. */ + virtual void AddTraceStateObserver(TraceStateObserver*) {} + + /** Removes tracing state change observer. */ + virtual void RemoveTraceStateObserver(TraceStateObserver*) {} +}; + +} // namespace v8 + +#endif // V8_V8_PLATFORM_H_ diff --git a/calclib/src/main/cpp/include/v8-profiler.h b/calclib/src/main/cpp/include/v8-profiler.h new file mode 100644 index 0000000..6ee0340 --- /dev/null +++ b/calclib/src/main/cpp/include/v8-profiler.h @@ -0,0 +1,897 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_V8_PROFILER_H_ +#define V8_V8_PROFILER_H_ + +#include +#include "v8.h" // NOLINT(build/include) + +/** + * Profiler support for the V8 JavaScript engine. + */ +namespace v8 { + +class HeapGraphNode; +struct HeapStatsUpdate; + +typedef uint32_t SnapshotObjectId; + + +struct CpuProfileDeoptFrame { + int script_id; + size_t position; +}; + +} // namespace v8 + +#ifdef V8_OS_WIN +template class V8_EXPORT std::vector; +#endif + +namespace v8 { + +struct V8_EXPORT CpuProfileDeoptInfo { + /** A pointer to a static string owned by v8. */ + const char* deopt_reason; + std::vector stack; +}; + +} // namespace v8 + +#ifdef V8_OS_WIN +template class V8_EXPORT std::vector; +#endif + +namespace v8 { + +/** + * TracingCpuProfiler monitors tracing being enabled/disabled + * and emits CpuProfile trace events once v8.cpu_profile2 tracing category + * is enabled. It has no overhead unless the category is enabled. + */ +class V8_EXPORT TracingCpuProfiler { + public: + static std::unique_ptr Create(Isolate*); + virtual ~TracingCpuProfiler() = default; + + protected: + TracingCpuProfiler() = default; +}; + +// TickSample captures the information collected for each sample. +struct TickSample { + // Internal profiling (with --prof + tools/$OS-tick-processor) wants to + // include the runtime function we're calling. Externally exposed tick + // samples don't care. + enum RecordCEntryFrame { kIncludeCEntryFrame, kSkipCEntryFrame }; + + TickSample() + : state(OTHER), + pc(nullptr), + external_callback_entry(nullptr), + frames_count(0), + has_external_callback(false), + update_stats(true) {} + + /** + * Initialize a tick sample from the isolate. + * \param isolate The isolate. + * \param state Execution state. + * \param record_c_entry_frame Include or skip the runtime function. + * \param update_stats Whether update the sample to the aggregated stats. + * \param use_simulator_reg_state When set to true and V8 is running under a + * simulator, the method will use the simulator + * register state rather than the one provided + * with |state| argument. Otherwise the method + * will use provided register |state| as is. + */ + void Init(Isolate* isolate, const v8::RegisterState& state, + RecordCEntryFrame record_c_entry_frame, bool update_stats, + bool use_simulator_reg_state = true); + /** + * Get a call stack sample from the isolate. + * \param isolate The isolate. + * \param state Register state. + * \param record_c_entry_frame Include or skip the runtime function. + * \param frames Caller allocated buffer to store stack frames. + * \param frames_limit Maximum number of frames to capture. The buffer must + * be large enough to hold the number of frames. + * \param sample_info The sample info is filled up by the function + * provides number of actual captured stack frames and + * the current VM state. + * \param use_simulator_reg_state When set to true and V8 is running under a + * simulator, the method will use the simulator + * register state rather than the one provided + * with |state| argument. Otherwise the method + * will use provided register |state| as is. + * \note GetStackSample is thread and signal safe and should only be called + * when the JS thread is paused or interrupted. + * Otherwise the behavior is undefined. + */ + static bool GetStackSample(Isolate* isolate, v8::RegisterState* state, + RecordCEntryFrame record_c_entry_frame, + void** frames, size_t frames_limit, + v8::SampleInfo* sample_info, + bool use_simulator_reg_state = true); + StateTag state; // The state of the VM. + void* pc; // Instruction pointer. + union { + void* tos; // Top stack value (*sp). + void* external_callback_entry; + }; + static const unsigned kMaxFramesCountLog2 = 8; + static const unsigned kMaxFramesCount = (1 << kMaxFramesCountLog2) - 1; + void* stack[kMaxFramesCount]; // Call stack. + unsigned frames_count : kMaxFramesCountLog2; // Number of captured frames. + bool has_external_callback : 1; + bool update_stats : 1; // Whether the sample should update aggregated stats. +}; + +/** + * CpuProfileNode represents a node in a call graph. + */ +class V8_EXPORT CpuProfileNode { + public: + struct LineTick { + /** The 1-based number of the source line where the function originates. */ + int line; + + /** The count of samples associated with the source line. */ + unsigned int hit_count; + }; + + /** Returns function name (empty string for anonymous functions.) */ + Local GetFunctionName() const; + + /** + * Returns function name (empty string for anonymous functions.) + * The string ownership is *not* passed to the caller. It stays valid until + * profile is deleted. The function is thread safe. + */ + const char* GetFunctionNameStr() const; + + /** Returns id of the script where function is located. */ + int GetScriptId() const; + + /** Returns resource name for script from where the function originates. */ + Local GetScriptResourceName() const; + + /** + * Returns resource name for script from where the function originates. + * The string ownership is *not* passed to the caller. It stays valid until + * profile is deleted. The function is thread safe. + */ + const char* GetScriptResourceNameStr() const; + + /** + * Returns the number, 1-based, of the line where the function originates. + * kNoLineNumberInfo if no line number information is available. + */ + int GetLineNumber() const; + + /** + * Returns 1-based number of the column where the function originates. + * kNoColumnNumberInfo if no column number information is available. + */ + int GetColumnNumber() const; + + /** + * Returns the number of the function's source lines that collect the samples. + */ + unsigned int GetHitLineCount() const; + + /** Returns the set of source lines that collect the samples. + * The caller allocates buffer and responsible for releasing it. + * True if all available entries are copied, otherwise false. + * The function copies nothing if buffer is not large enough. + */ + bool GetLineTicks(LineTick* entries, unsigned int length) const; + + /** Returns bailout reason for the function + * if the optimization was disabled for it. + */ + const char* GetBailoutReason() const; + + /** + * Returns the count of samples where the function was currently executing. + */ + unsigned GetHitCount() const; + + /** Returns function entry UID. */ + V8_DEPRECATE_SOON( + "Use GetScriptId, GetLineNumber, and GetColumnNumber instead.", + unsigned GetCallUid() const); + + /** Returns id of the node. The id is unique within the tree */ + unsigned GetNodeId() const; + + /** Returns child nodes count of the node. */ + int GetChildrenCount() const; + + /** Retrieves a child node by index. */ + const CpuProfileNode* GetChild(int index) const; + + /** Retrieves deopt infos for the node. */ + const std::vector& GetDeoptInfos() const; + + static const int kNoLineNumberInfo = Message::kNoLineNumberInfo; + static const int kNoColumnNumberInfo = Message::kNoColumnInfo; +}; + + +/** + * CpuProfile contains a CPU profile in a form of top-down call tree + * (from main() down to functions that do all the work). + */ +class V8_EXPORT CpuProfile { + public: + /** Returns CPU profile title. */ + Local GetTitle() const; + + /** Returns the root node of the top down call tree. */ + const CpuProfileNode* GetTopDownRoot() const; + + /** + * Returns number of samples recorded. The samples are not recorded unless + * |record_samples| parameter of CpuProfiler::StartCpuProfiling is true. + */ + int GetSamplesCount() const; + + /** + * Returns profile node corresponding to the top frame the sample at + * the given index. + */ + const CpuProfileNode* GetSample(int index) const; + + /** + * Returns the timestamp of the sample. The timestamp is the number of + * microseconds since some unspecified starting point. + * The point is equal to the starting point used by GetStartTime. + */ + int64_t GetSampleTimestamp(int index) const; + + /** + * Returns time when the profile recording was started (in microseconds) + * since some unspecified starting point. + */ + int64_t GetStartTime() const; + + /** + * Returns time when the profile recording was stopped (in microseconds) + * since some unspecified starting point. + * The point is equal to the starting point used by GetStartTime. + */ + int64_t GetEndTime() const; + + /** + * Deletes the profile and removes it from CpuProfiler's list. + * All pointers to nodes previously returned become invalid. + */ + void Delete(); +}; + +/** + * Interface for controlling CPU profiling. Instance of the + * profiler can be created using v8::CpuProfiler::New method. + */ +class V8_EXPORT CpuProfiler { + public: + /** + * Creates a new CPU profiler for the |isolate|. The isolate must be + * initialized. The profiler object must be disposed after use by calling + * |Dispose| method. + */ + static CpuProfiler* New(Isolate* isolate); + + /** + * Disposes the CPU profiler object. + */ + void Dispose(); + + /** + * Changes default CPU profiler sampling interval to the specified number + * of microseconds. Default interval is 1000us. This method must be called + * when there are no profiles being recorded. + */ + void SetSamplingInterval(int us); + + /** + * Starts collecting CPU profile. Title may be an empty string. It + * is allowed to have several profiles being collected at + * once. Attempts to start collecting several profiles with the same + * title are silently ignored. While collecting a profile, functions + * from all security contexts are included in it. The token-based + * filtering is only performed when querying for a profile. + * + * |record_samples| parameter controls whether individual samples should + * be recorded in addition to the aggregated tree. + */ + void StartProfiling(Local title, bool record_samples = false); + + /** + * Stops collecting CPU profile with a given title and returns it. + * If the title given is empty, finishes the last profile started. + */ + CpuProfile* StopProfiling(Local title); + + /** + * Force collection of a sample. Must be called on the VM thread. + * Recording the forced sample does not contribute to the aggregated + * profile statistics. + */ + void CollectSample(); + + /** + * Tells the profiler whether the embedder is idle. + */ + void SetIdle(bool is_idle); + + private: + CpuProfiler(); + ~CpuProfiler(); + CpuProfiler(const CpuProfiler&); + CpuProfiler& operator=(const CpuProfiler&); +}; + + +/** + * HeapSnapshotEdge represents a directed connection between heap + * graph nodes: from retainers to retained nodes. + */ +class V8_EXPORT HeapGraphEdge { + public: + enum Type { + kContextVariable = 0, // A variable from a function context. + kElement = 1, // An element of an array. + kProperty = 2, // A named object property. + kInternal = 3, // A link that can't be accessed from JS, + // thus, its name isn't a real property name + // (e.g. parts of a ConsString). + kHidden = 4, // A link that is needed for proper sizes + // calculation, but may be hidden from user. + kShortcut = 5, // A link that must not be followed during + // sizes calculation. + kWeak = 6 // A weak reference (ignored by the GC). + }; + + /** Returns edge type (see HeapGraphEdge::Type). */ + Type GetType() const; + + /** + * Returns edge name. This can be a variable name, an element index, or + * a property name. + */ + Local GetName() const; + + /** Returns origin node. */ + const HeapGraphNode* GetFromNode() const; + + /** Returns destination node. */ + const HeapGraphNode* GetToNode() const; +}; + + +/** + * HeapGraphNode represents a node in a heap graph. + */ +class V8_EXPORT HeapGraphNode { + public: + enum Type { + kHidden = 0, // Hidden node, may be filtered when shown to user. + kArray = 1, // An array of elements. + kString = 2, // A string. + kObject = 3, // A JS object (except for arrays and strings). + kCode = 4, // Compiled code. + kClosure = 5, // Function closure. + kRegExp = 6, // RegExp. + kHeapNumber = 7, // Number stored in the heap. + kNative = 8, // Native object (not from V8 heap). + kSynthetic = 9, // Synthetic object, usualy used for grouping + // snapshot items together. + kConsString = 10, // Concatenated string. A pair of pointers to strings. + kSlicedString = 11, // Sliced string. A fragment of another string. + kSymbol = 12, // A Symbol (ES6). + kSimdValue = 13 // A SIMD value stored in the heap (Proposed ES7). + }; + + /** Returns node type (see HeapGraphNode::Type). */ + Type GetType() const; + + /** + * Returns node name. Depending on node's type this can be the name + * of the constructor (for objects), the name of the function (for + * closures), string value, or an empty string (for compiled code). + */ + Local GetName() const; + + /** + * Returns node id. For the same heap object, the id remains the same + * across all snapshots. + */ + SnapshotObjectId GetId() const; + + /** Returns node's own size, in bytes. */ + size_t GetShallowSize() const; + + /** Returns child nodes count of the node. */ + int GetChildrenCount() const; + + /** Retrieves a child by index. */ + const HeapGraphEdge* GetChild(int index) const; +}; + + +/** + * An interface for exporting data from V8, using "push" model. + */ +class V8_EXPORT OutputStream { // NOLINT + public: + enum WriteResult { + kContinue = 0, + kAbort = 1 + }; + virtual ~OutputStream() {} + /** Notify about the end of stream. */ + virtual void EndOfStream() = 0; + /** Get preferred output chunk size. Called only once. */ + virtual int GetChunkSize() { return 1024; } + /** + * Writes the next chunk of snapshot data into the stream. Writing + * can be stopped by returning kAbort as function result. EndOfStream + * will not be called in case writing was aborted. + */ + virtual WriteResult WriteAsciiChunk(char* data, int size) = 0; + /** + * Writes the next chunk of heap stats data into the stream. Writing + * can be stopped by returning kAbort as function result. EndOfStream + * will not be called in case writing was aborted. + */ + virtual WriteResult WriteHeapStatsChunk(HeapStatsUpdate* data, int count) { + return kAbort; + } +}; + + +/** + * HeapSnapshots record the state of the JS heap at some moment. + */ +class V8_EXPORT HeapSnapshot { + public: + enum SerializationFormat { + kJSON = 0 // See format description near 'Serialize' method. + }; + + /** Returns the root node of the heap graph. */ + const HeapGraphNode* GetRoot() const; + + /** Returns a node by its id. */ + const HeapGraphNode* GetNodeById(SnapshotObjectId id) const; + + /** Returns total nodes count in the snapshot. */ + int GetNodesCount() const; + + /** Returns a node by index. */ + const HeapGraphNode* GetNode(int index) const; + + /** Returns a max seen JS object Id. */ + SnapshotObjectId GetMaxSnapshotJSObjectId() const; + + /** + * Deletes the snapshot and removes it from HeapProfiler's list. + * All pointers to nodes, edges and paths previously returned become + * invalid. + */ + void Delete(); + + /** + * Prepare a serialized representation of the snapshot. The result + * is written into the stream provided in chunks of specified size. + * The total length of the serialized snapshot is unknown in + * advance, it can be roughly equal to JS heap size (that means, + * it can be really big - tens of megabytes). + * + * For the JSON format, heap contents are represented as an object + * with the following structure: + * + * { + * snapshot: { + * title: "...", + * uid: nnn, + * meta: { meta-info }, + * node_count: nnn, + * edge_count: nnn + * }, + * nodes: [nodes array], + * edges: [edges array], + * strings: [strings array] + * } + * + * Nodes reference strings, other nodes, and edges by their indexes + * in corresponding arrays. + */ + void Serialize(OutputStream* stream, + SerializationFormat format = kJSON) const; +}; + + +/** + * An interface for reporting progress and controlling long-running + * activities. + */ +class V8_EXPORT ActivityControl { // NOLINT + public: + enum ControlOption { + kContinue = 0, + kAbort = 1 + }; + virtual ~ActivityControl() {} + /** + * Notify about current progress. The activity can be stopped by + * returning kAbort as the callback result. + */ + virtual ControlOption ReportProgressValue(int done, int total) = 0; +}; + + +/** + * AllocationProfile is a sampled profile of allocations done by the program. + * This is structured as a call-graph. + */ +class V8_EXPORT AllocationProfile { + public: + struct Allocation { + /** + * Size of the sampled allocation object. + */ + size_t size; + + /** + * The number of objects of such size that were sampled. + */ + unsigned int count; + }; + + /** + * Represents a node in the call-graph. + */ + struct Node { + /** + * Name of the function. May be empty for anonymous functions or if the + * script corresponding to this function has been unloaded. + */ + Local name; + + /** + * Name of the script containing the function. May be empty if the script + * name is not available, or if the script has been unloaded. + */ + Local script_name; + + /** + * id of the script where the function is located. May be equal to + * v8::UnboundScript::kNoScriptId in cases where the script doesn't exist. + */ + int script_id; + + /** + * Start position of the function in the script. + */ + int start_position; + + /** + * 1-indexed line number where the function starts. May be + * kNoLineNumberInfo if no line number information is available. + */ + int line_number; + + /** + * 1-indexed column number where the function starts. May be + * kNoColumnNumberInfo if no line number information is available. + */ + int column_number; + + /** + * List of callees called from this node for which we have sampled + * allocations. The lifetime of the children is scoped to the containing + * AllocationProfile. + */ + std::vector children; + + /** + * List of self allocations done by this node in the call-graph. + */ + std::vector allocations; + }; + + /** + * Returns the root node of the call-graph. The root node corresponds to an + * empty JS call-stack. The lifetime of the returned Node* is scoped to the + * containing AllocationProfile. + */ + virtual Node* GetRootNode() = 0; + + virtual ~AllocationProfile() {} + + static const int kNoLineNumberInfo = Message::kNoLineNumberInfo; + static const int kNoColumnNumberInfo = Message::kNoColumnInfo; +}; + + +/** + * Interface for controlling heap profiling. Instance of the + * profiler can be retrieved using v8::Isolate::GetHeapProfiler. + */ +class V8_EXPORT HeapProfiler { + public: + enum SamplingFlags { + kSamplingNoFlags = 0, + kSamplingForceGC = 1 << 0, + }; + + /** + * Callback function invoked for obtaining RetainedObjectInfo for + * the given JavaScript wrapper object. It is prohibited to enter V8 + * while the callback is running: only getters on the handle and + * GetPointerFromInternalField on the objects are allowed. + */ + typedef RetainedObjectInfo* (*WrapperInfoCallback)(uint16_t class_id, + Local wrapper); + + /** Returns the number of snapshots taken. */ + int GetSnapshotCount(); + + /** Returns a snapshot by index. */ + const HeapSnapshot* GetHeapSnapshot(int index); + + /** + * Returns SnapshotObjectId for a heap object referenced by |value| if + * it has been seen by the heap profiler, kUnknownObjectId otherwise. + */ + SnapshotObjectId GetObjectId(Local value); + + /** + * Returns heap object with given SnapshotObjectId if the object is alive, + * otherwise empty handle is returned. + */ + Local FindObjectById(SnapshotObjectId id); + + /** + * Clears internal map from SnapshotObjectId to heap object. The new objects + * will not be added into it unless a heap snapshot is taken or heap object + * tracking is kicked off. + */ + void ClearObjectIds(); + + /** + * A constant for invalid SnapshotObjectId. GetSnapshotObjectId will return + * it in case heap profiler cannot find id for the object passed as + * parameter. HeapSnapshot::GetNodeById will always return NULL for such id. + */ + static const SnapshotObjectId kUnknownObjectId = 0; + + /** + * Callback interface for retrieving user friendly names of global objects. + */ + class ObjectNameResolver { + public: + /** + * Returns name to be used in the heap snapshot for given node. Returned + * string must stay alive until snapshot collection is completed. + */ + virtual const char* GetName(Local object) = 0; + + protected: + virtual ~ObjectNameResolver() {} + }; + + /** + * Takes a heap snapshot and returns it. + */ + const HeapSnapshot* TakeHeapSnapshot( + ActivityControl* control = NULL, + ObjectNameResolver* global_object_name_resolver = NULL); + + /** + * Starts tracking of heap objects population statistics. After calling + * this method, all heap objects relocations done by the garbage collector + * are being registered. + * + * |track_allocations| parameter controls whether stack trace of each + * allocation in the heap will be recorded and reported as part of + * HeapSnapshot. + */ + void StartTrackingHeapObjects(bool track_allocations = false); + + /** + * Adds a new time interval entry to the aggregated statistics array. The + * time interval entry contains information on the current heap objects + * population size. The method also updates aggregated statistics and + * reports updates for all previous time intervals via the OutputStream + * object. Updates on each time interval are provided as a stream of the + * HeapStatsUpdate structure instances. + * If |timestamp_us| is supplied, timestamp of the new entry will be written + * into it. The return value of the function is the last seen heap object Id. + * + * StartTrackingHeapObjects must be called before the first call to this + * method. + */ + SnapshotObjectId GetHeapStats(OutputStream* stream, + int64_t* timestamp_us = NULL); + + /** + * Stops tracking of heap objects population statistics, cleans up all + * collected data. StartHeapObjectsTracking must be called again prior to + * calling GetHeapStats next time. + */ + void StopTrackingHeapObjects(); + + /** + * Starts gathering a sampling heap profile. A sampling heap profile is + * similar to tcmalloc's heap profiler and Go's mprof. It samples object + * allocations and builds an online 'sampling' heap profile. At any point in + * time, this profile is expected to be a representative sample of objects + * currently live in the system. Each sampled allocation includes the stack + * trace at the time of allocation, which makes this really useful for memory + * leak detection. + * + * This mechanism is intended to be cheap enough that it can be used in + * production with minimal performance overhead. + * + * Allocations are sampled using a randomized Poisson process. On average, one + * allocation will be sampled every |sample_interval| bytes allocated. The + * |stack_depth| parameter controls the maximum number of stack frames to be + * captured on each allocation. + * + * NOTE: This is a proof-of-concept at this point. Right now we only sample + * newspace allocations. Support for paged space allocation (e.g. pre-tenured + * objects, large objects, code objects, etc.) and native allocations + * doesn't exist yet, but is anticipated in the future. + * + * Objects allocated before the sampling is started will not be included in + * the profile. + * + * Returns false if a sampling heap profiler is already running. + */ + bool StartSamplingHeapProfiler(uint64_t sample_interval = 512 * 1024, + int stack_depth = 16, + SamplingFlags flags = kSamplingNoFlags); + + /** + * Stops the sampling heap profile and discards the current profile. + */ + void StopSamplingHeapProfiler(); + + /** + * Returns the sampled profile of allocations allocated (and still live) since + * StartSamplingHeapProfiler was called. The ownership of the pointer is + * transfered to the caller. Returns nullptr if sampling heap profiler is not + * active. + */ + AllocationProfile* GetAllocationProfile(); + + /** + * Deletes all snapshots taken. All previously returned pointers to + * snapshots and their contents become invalid after this call. + */ + void DeleteAllHeapSnapshots(); + + /** Binds a callback to embedder's class ID. */ + void SetWrapperClassInfoProvider( + uint16_t class_id, + WrapperInfoCallback callback); + + /** + * Default value of persistent handle class ID. Must not be used to + * define a class. Can be used to reset a class of a persistent + * handle. + */ + static const uint16_t kPersistentHandleNoClassId = 0; + + /** Returns memory used for profiler internal data and snapshots. */ + size_t GetProfilerMemorySize(); + + /** + * Sets a RetainedObjectInfo for an object group (see V8::SetObjectGroupId). + */ + void SetRetainedObjectInfo(UniqueId id, RetainedObjectInfo* info); + + private: + HeapProfiler(); + ~HeapProfiler(); + HeapProfiler(const HeapProfiler&); + HeapProfiler& operator=(const HeapProfiler&); +}; + +/** + * Interface for providing information about embedder's objects + * held by global handles. This information is reported in two ways: + * + * 1. When calling AddObjectGroup, an embedder may pass + * RetainedObjectInfo instance describing the group. To collect + * this information while taking a heap snapshot, V8 calls GC + * prologue and epilogue callbacks. + * + * 2. When a heap snapshot is collected, V8 additionally + * requests RetainedObjectInfos for persistent handles that + * were not previously reported via AddObjectGroup. + * + * Thus, if an embedder wants to provide information about native + * objects for heap snapshots, it can do it in a GC prologue + * handler, and / or by assigning wrapper class ids in the following way: + * + * 1. Bind a callback to class id by calling SetWrapperClassInfoProvider. + * 2. Call SetWrapperClassId on certain persistent handles. + * + * V8 takes ownership of RetainedObjectInfo instances passed to it and + * keeps them alive only during snapshot collection. Afterwards, they + * are freed by calling the Dispose class function. + */ +class V8_EXPORT RetainedObjectInfo { // NOLINT + public: + /** Called by V8 when it no longer needs an instance. */ + virtual void Dispose() = 0; + + /** Returns whether two instances are equivalent. */ + virtual bool IsEquivalent(RetainedObjectInfo* other) = 0; + + /** + * Returns hash value for the instance. Equivalent instances + * must have the same hash value. + */ + virtual intptr_t GetHash() = 0; + + /** + * Returns human-readable label. It must be a null-terminated UTF-8 + * encoded string. V8 copies its contents during a call to GetLabel. + */ + virtual const char* GetLabel() = 0; + + /** + * Returns human-readable group label. It must be a null-terminated UTF-8 + * encoded string. V8 copies its contents during a call to GetGroupLabel. + * Heap snapshot generator will collect all the group names, create + * top level entries with these names and attach the objects to the + * corresponding top level group objects. There is a default + * implementation which is required because embedders don't have their + * own implementation yet. + */ + virtual const char* GetGroupLabel() { return GetLabel(); } + + /** + * Returns element count in case if a global handle retains + * a subgraph by holding one of its nodes. + */ + virtual intptr_t GetElementCount() { return -1; } + + /** Returns embedder's object size in bytes. */ + virtual intptr_t GetSizeInBytes() { return -1; } + + protected: + RetainedObjectInfo() {} + virtual ~RetainedObjectInfo() {} + + private: + RetainedObjectInfo(const RetainedObjectInfo&); + RetainedObjectInfo& operator=(const RetainedObjectInfo&); +}; + + +/** + * A struct for exporting HeapStats data from V8, using "push" model. + * See HeapProfiler::GetHeapStats. + */ +struct HeapStatsUpdate { + HeapStatsUpdate(uint32_t index, uint32_t count, uint32_t size) + : index(index), count(count), size(size) { } + uint32_t index; // Index of the time interval that was changed. + uint32_t count; // New value of count field for the interval with this index. + uint32_t size; // New value of size field for the interval with this index. +}; + + +} // namespace v8 + + +#endif // V8_V8_PROFILER_H_ diff --git a/calclib/src/main/cpp/include/v8-testing.h b/calclib/src/main/cpp/include/v8-testing.h new file mode 100644 index 0000000..f67bf25 --- /dev/null +++ b/calclib/src/main/cpp/include/v8-testing.h @@ -0,0 +1,48 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_V8_TEST_H_ +#define V8_V8_TEST_H_ + +#include "v8.h" // NOLINT(build/include) + +/** + * Testing support for the V8 JavaScript engine. + */ +namespace v8 { + +class V8_EXPORT Testing { + public: + enum StressType { + kStressTypeOpt, + kStressTypeDeopt + }; + + /** + * Set the type of stressing to do. The default if not set is kStressTypeOpt. + */ + static void SetStressRunType(StressType type); + + /** + * Get the number of runs of a given test that is required to get the full + * stress coverage. + */ + static int GetStressRuns(); + + /** + * Indicate the number of the run which is about to start. The value of run + * should be between 0 and one less than the result from GetStressRuns() + */ + static void PrepareStressRun(int run); + + /** + * Force deoptimization of all functions. + */ + static void DeoptimizeAll(Isolate* isolate); +}; + + +} // namespace v8 + +#endif // V8_V8_TEST_H_ diff --git a/calclib/src/main/cpp/include/v8-util.h b/calclib/src/main/cpp/include/v8-util.h new file mode 100644 index 0000000..99c59fe --- /dev/null +++ b/calclib/src/main/cpp/include/v8-util.h @@ -0,0 +1,659 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_UTIL_H_ +#define V8_UTIL_H_ + +#include "v8.h" // NOLINT(build/include) +#include +#include + +/** + * Support for Persistent containers. + * + * C++11 embedders can use STL containers with Global values, + * but pre-C++11 does not support the required move semantic and hence + * may want these container classes. + */ +namespace v8 { + +typedef uintptr_t PersistentContainerValue; +static const uintptr_t kPersistentContainerNotFound = 0; +enum PersistentContainerCallbackType { + kNotWeak, + // These correspond to v8::WeakCallbackType + kWeakWithParameter, + kWeakWithInternalFields, + kWeak = kWeakWithParameter // For backwards compatibility. Deprecate. +}; + + +/** + * A default trait implemenation for PersistentValueMap which uses std::map + * as a backing map. + * + * Users will have to implement their own weak callbacks & dispose traits. + */ +template +class StdMapTraits { + public: + // STL map & related: + typedef std::map Impl; + typedef typename Impl::iterator Iterator; + + static bool Empty(Impl* impl) { return impl->empty(); } + static size_t Size(Impl* impl) { return impl->size(); } + static void Swap(Impl& a, Impl& b) { std::swap(a, b); } // NOLINT + static Iterator Begin(Impl* impl) { return impl->begin(); } + static Iterator End(Impl* impl) { return impl->end(); } + static K Key(Iterator it) { return it->first; } + static PersistentContainerValue Value(Iterator it) { return it->second; } + static PersistentContainerValue Set(Impl* impl, K key, + PersistentContainerValue value) { + std::pair res = impl->insert(std::make_pair(key, value)); + PersistentContainerValue old_value = kPersistentContainerNotFound; + if (!res.second) { + old_value = res.first->second; + res.first->second = value; + } + return old_value; + } + static PersistentContainerValue Get(Impl* impl, K key) { + Iterator it = impl->find(key); + if (it == impl->end()) return kPersistentContainerNotFound; + return it->second; + } + static PersistentContainerValue Remove(Impl* impl, K key) { + Iterator it = impl->find(key); + if (it == impl->end()) return kPersistentContainerNotFound; + PersistentContainerValue value = it->second; + impl->erase(it); + return value; + } +}; + + +/** + * A default trait implementation for PersistentValueMap, which inherits + * a std:map backing map from StdMapTraits and holds non-weak persistent + * objects and has no special Dispose handling. + * + * You should not derive from this class, since MapType depends on the + * surrounding class, and hence a subclass cannot simply inherit the methods. + */ +template +class DefaultPersistentValueMapTraits : public StdMapTraits { + public: + // Weak callback & friends: + static const PersistentContainerCallbackType kCallbackType = kNotWeak; + typedef PersistentValueMap > + MapType; + typedef void WeakCallbackDataType; + + static WeakCallbackDataType* WeakCallbackParameter( + MapType* map, const K& key, Local value) { + return NULL; + } + static MapType* MapFromWeakCallbackInfo( + const WeakCallbackInfo& data) { + return NULL; + } + static K KeyFromWeakCallbackInfo( + const WeakCallbackInfo& data) { + return K(); + } + static void DisposeCallbackData(WeakCallbackDataType* data) { } + static void Dispose(Isolate* isolate, Global value, K key) {} +}; + + +template +class DefaultGlobalMapTraits : public StdMapTraits { + private: + template + struct RemovePointer; + + public: + // Weak callback & friends: + static const PersistentContainerCallbackType kCallbackType = kNotWeak; + typedef GlobalValueMap > MapType; + typedef void WeakCallbackDataType; + + static WeakCallbackDataType* WeakCallbackParameter(MapType* map, const K& key, + Local value) { + return nullptr; + } + static MapType* MapFromWeakCallbackInfo( + const WeakCallbackInfo& data) { + return nullptr; + } + static K KeyFromWeakCallbackInfo( + const WeakCallbackInfo& data) { + return K(); + } + static void DisposeCallbackData(WeakCallbackDataType* data) {} + static void OnWeakCallback( + const WeakCallbackInfo& data) {} + static void Dispose(Isolate* isolate, Global value, K key) {} + // This is a second pass callback, so SetSecondPassCallback cannot be called. + static void DisposeWeak(const WeakCallbackInfo& data) {} + + private: + template + struct RemovePointer { + typedef T Type; + }; +}; + + +/** + * A map wrapper that allows using Global as a mapped value. + * C++11 embedders don't need this class, as they can use Global + * directly in std containers. + * + * The map relies on a backing map, whose type and accessors are described + * by the Traits class. The backing map will handle values of type + * PersistentContainerValue, with all conversion into and out of V8 + * handles being transparently handled by this class. + */ +template +class PersistentValueMapBase { + public: + Isolate* GetIsolate() { return isolate_; } + + /** + * Return size of the map. + */ + size_t Size() { return Traits::Size(&impl_); } + + /** + * Return whether the map holds weak persistents. + */ + bool IsWeak() { return Traits::kCallbackType != kNotWeak; } + + /** + * Get value stored in map. + */ + Local Get(const K& key) { + return Local::New(isolate_, FromVal(Traits::Get(&impl_, key))); + } + + /** + * Check whether a value is contained in the map. + */ + bool Contains(const K& key) { + return Traits::Get(&impl_, key) != kPersistentContainerNotFound; + } + + /** + * Get value stored in map and set it in returnValue. + * Return true if a value was found. + */ + bool SetReturnValue(const K& key, + ReturnValue returnValue) { + return SetReturnValueFromVal(&returnValue, Traits::Get(&impl_, key)); + } + + /** + * Call Isolate::SetReference with the given parent and the map value. + */ + void SetReference(const K& key, + const Persistent& parent) { + GetIsolate()->SetReference( + reinterpret_cast(parent.val_), + reinterpret_cast(FromVal(Traits::Get(&impl_, key)))); + } + + /** + * Deprecated. Call V8::RegisterExternallyReferencedObject with the map value + * for given key. + * TODO(hlopko) Remove once migration to reporter is finished. + */ + void RegisterExternallyReferencedObject(K& key) {} + + /** + * Use EmbedderReachableReferenceReporter with the map value for given key. + */ + void RegisterExternallyReferencedObject( + EmbedderReachableReferenceReporter* reporter, K& key) { + DCHECK(Contains(key)); + reporter->ReportExternalReference(FromVal(Traits::Get(&impl_, key))); + } + + /** + * Return value for key and remove it from the map. + */ + Global Remove(const K& key) { + return Release(Traits::Remove(&impl_, key)).Pass(); + } + + /** + * Traverses the map repeatedly, + * in case side effects of disposal cause insertions. + **/ + void Clear() { + typedef typename Traits::Iterator It; + HandleScope handle_scope(isolate_); + // TODO(dcarney): figure out if this swap and loop is necessary. + while (!Traits::Empty(&impl_)) { + typename Traits::Impl impl; + Traits::Swap(impl_, impl); + for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) { + Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(), + Traits::Key(i)); + } + } + } + + /** + * Helper class for GetReference/SetWithReference. Do not use outside + * that context. + */ + class PersistentValueReference { + public: + PersistentValueReference() : value_(kPersistentContainerNotFound) { } + PersistentValueReference(const PersistentValueReference& other) + : value_(other.value_) { } + + Local NewLocal(Isolate* isolate) const { + return Local::New(isolate, FromVal(value_)); + } + bool IsEmpty() const { + return value_ == kPersistentContainerNotFound; + } + template + bool SetReturnValue(ReturnValue returnValue) { + return SetReturnValueFromVal(&returnValue, value_); + } + void Reset() { + value_ = kPersistentContainerNotFound; + } + void operator=(const PersistentValueReference& other) { + value_ = other.value_; + } + + private: + friend class PersistentValueMapBase; + friend class PersistentValueMap; + friend class GlobalValueMap; + + explicit PersistentValueReference(PersistentContainerValue value) + : value_(value) { } + + void operator=(PersistentContainerValue value) { + value_ = value; + } + + PersistentContainerValue value_; + }; + + /** + * Get a reference to a map value. This enables fast, repeated access + * to a value stored in the map while the map remains unchanged. + * + * Careful: This is potentially unsafe, so please use with care. + * The value will become invalid if the value for this key changes + * in the underlying map, as a result of Set or Remove for the same + * key; as a result of the weak callback for the same key; or as a + * result of calling Clear() or destruction of the map. + */ + PersistentValueReference GetReference(const K& key) { + return PersistentValueReference(Traits::Get(&impl_, key)); + } + + protected: + explicit PersistentValueMapBase(Isolate* isolate) : isolate_(isolate) {} + + ~PersistentValueMapBase() { Clear(); } + + Isolate* isolate() { return isolate_; } + typename Traits::Impl* impl() { return &impl_; } + + static V* FromVal(PersistentContainerValue v) { + return reinterpret_cast(v); + } + + static PersistentContainerValue ClearAndLeak(Global* persistent) { + V* v = persistent->val_; + persistent->val_ = 0; + return reinterpret_cast(v); + } + + static PersistentContainerValue Leak(Global* persistent) { + return reinterpret_cast(persistent->val_); + } + + /** + * Return a container value as Global and make sure the weak + * callback is properly disposed of. All remove functionality should go + * through this. + */ + static Global Release(PersistentContainerValue v) { + Global p; + p.val_ = FromVal(v); + if (Traits::kCallbackType != kNotWeak && p.IsWeak()) { + Traits::DisposeCallbackData( + p.template ClearWeak()); + } + return p.Pass(); + } + + void RemoveWeak(const K& key) { + Global p; + p.val_ = FromVal(Traits::Remove(&impl_, key)); + p.Reset(); + } + + private: + PersistentValueMapBase(PersistentValueMapBase&); + void operator=(PersistentValueMapBase&); + + static bool SetReturnValueFromVal(ReturnValue* returnValue, + PersistentContainerValue value) { + bool hasValue = value != kPersistentContainerNotFound; + if (hasValue) { + returnValue->SetInternal( + *reinterpret_cast(FromVal(value))); + } + return hasValue; + } + + Isolate* isolate_; + typename Traits::Impl impl_; +}; + + +template +class PersistentValueMap : public PersistentValueMapBase { + public: + explicit PersistentValueMap(Isolate* isolate) + : PersistentValueMapBase(isolate) {} + + typedef + typename PersistentValueMapBase::PersistentValueReference + PersistentValueReference; + + /** + * Put value into map. Depending on Traits::kIsWeak, the value will be held + * by the map strongly or weakly. + * Returns old value as Global. + */ + Global Set(const K& key, Local value) { + Global persistent(this->isolate(), value); + return SetUnique(key, &persistent); + } + + /** + * Put value into map, like Set(const K&, Local). + */ + Global Set(const K& key, Global value) { + return SetUnique(key, &value); + } + + /** + * Put the value into the map, and set the 'weak' callback when demanded + * by the Traits class. + */ + Global SetUnique(const K& key, Global* persistent) { + if (Traits::kCallbackType != kNotWeak) { + Local value(Local::New(this->isolate(), *persistent)); + persistent->template SetWeak( + Traits::WeakCallbackParameter(this, key, value), WeakCallback); + } + PersistentContainerValue old_value = + Traits::Set(this->impl(), key, this->ClearAndLeak(persistent)); + return this->Release(old_value).Pass(); + } + + /** + * Put a value into the map and update the reference. + * Restrictions of GetReference apply here as well. + */ + Global Set(const K& key, Global value, + PersistentValueReference* reference) { + *reference = this->Leak(&value); + return SetUnique(key, &value); + } + + private: + static void WeakCallback( + const WeakCallbackInfo& data) { + if (Traits::kCallbackType != kNotWeak) { + PersistentValueMap* persistentValueMap = + Traits::MapFromWeakCallbackInfo(data); + K key = Traits::KeyFromWeakCallbackInfo(data); + Traits::Dispose(data.GetIsolate(), + persistentValueMap->Remove(key).Pass(), key); + Traits::DisposeCallbackData(data.GetParameter()); + } + } +}; + + +template +class GlobalValueMap : public PersistentValueMapBase { + public: + explicit GlobalValueMap(Isolate* isolate) + : PersistentValueMapBase(isolate) {} + + typedef + typename PersistentValueMapBase::PersistentValueReference + PersistentValueReference; + + /** + * Put value into map. Depending on Traits::kIsWeak, the value will be held + * by the map strongly or weakly. + * Returns old value as Global. + */ + Global Set(const K& key, Local value) { + Global persistent(this->isolate(), value); + return SetUnique(key, &persistent); + } + + /** + * Put value into map, like Set(const K&, Local). + */ + Global Set(const K& key, Global value) { + return SetUnique(key, &value); + } + + /** + * Put the value into the map, and set the 'weak' callback when demanded + * by the Traits class. + */ + Global SetUnique(const K& key, Global* persistent) { + if (Traits::kCallbackType != kNotWeak) { + WeakCallbackType callback_type = + Traits::kCallbackType == kWeakWithInternalFields + ? WeakCallbackType::kInternalFields + : WeakCallbackType::kParameter; + Local value(Local::New(this->isolate(), *persistent)); + persistent->template SetWeak( + Traits::WeakCallbackParameter(this, key, value), OnWeakCallback, + callback_type); + } + PersistentContainerValue old_value = + Traits::Set(this->impl(), key, this->ClearAndLeak(persistent)); + return this->Release(old_value).Pass(); + } + + /** + * Put a value into the map and update the reference. + * Restrictions of GetReference apply here as well. + */ + Global Set(const K& key, Global value, + PersistentValueReference* reference) { + *reference = this->Leak(&value); + return SetUnique(key, &value); + } + + private: + static void OnWeakCallback( + const WeakCallbackInfo& data) { + if (Traits::kCallbackType != kNotWeak) { + auto map = Traits::MapFromWeakCallbackInfo(data); + K key = Traits::KeyFromWeakCallbackInfo(data); + map->RemoveWeak(key); + Traits::OnWeakCallback(data); + data.SetSecondPassCallback(SecondWeakCallback); + } + } + + static void SecondWeakCallback( + const WeakCallbackInfo& data) { + Traits::DisposeWeak(data); + } +}; + + +/** + * A map that uses Global as value and std::map as the backing + * implementation. Persistents are held non-weak. + * + * C++11 embedders don't need this class, as they can use + * Global directly in std containers. + */ +template > +class StdPersistentValueMap : public PersistentValueMap { + public: + explicit StdPersistentValueMap(Isolate* isolate) + : PersistentValueMap(isolate) {} +}; + + +/** + * A map that uses Global as value and std::map as the backing + * implementation. Globals are held non-weak. + * + * C++11 embedders don't need this class, as they can use + * Global directly in std containers. + */ +template > +class StdGlobalValueMap : public GlobalValueMap { + public: + explicit StdGlobalValueMap(Isolate* isolate) + : GlobalValueMap(isolate) {} +}; + + +class DefaultPersistentValueVectorTraits { + public: + typedef std::vector Impl; + + static void Append(Impl* impl, PersistentContainerValue value) { + impl->push_back(value); + } + static bool IsEmpty(const Impl* impl) { + return impl->empty(); + } + static size_t Size(const Impl* impl) { + return impl->size(); + } + static PersistentContainerValue Get(const Impl* impl, size_t i) { + return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound; + } + static void ReserveCapacity(Impl* impl, size_t capacity) { + impl->reserve(capacity); + } + static void Clear(Impl* impl) { + impl->clear(); + } +}; + + +/** + * A vector wrapper that safely stores Global values. + * C++11 embedders don't need this class, as they can use Global + * directly in std containers. + * + * This class relies on a backing vector implementation, whose type and methods + * are described by the Traits class. The backing map will handle values of type + * PersistentContainerValue, with all conversion into and out of V8 + * handles being transparently handled by this class. + */ +template +class PersistentValueVector { + public: + explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { } + + ~PersistentValueVector() { + Clear(); + } + + /** + * Append a value to the vector. + */ + void Append(Local value) { + Global persistent(isolate_, value); + Traits::Append(&impl_, ClearAndLeak(&persistent)); + } + + /** + * Append a persistent's value to the vector. + */ + void Append(Global persistent) { + Traits::Append(&impl_, ClearAndLeak(&persistent)); + } + + /** + * Are there any values in the vector? + */ + bool IsEmpty() const { + return Traits::IsEmpty(&impl_); + } + + /** + * How many elements are in the vector? + */ + size_t Size() const { + return Traits::Size(&impl_); + } + + /** + * Retrieve the i-th value in the vector. + */ + Local Get(size_t index) const { + return Local::New(isolate_, FromVal(Traits::Get(&impl_, index))); + } + + /** + * Remove all elements from the vector. + */ + void Clear() { + size_t length = Traits::Size(&impl_); + for (size_t i = 0; i < length; i++) { + Global p; + p.val_ = FromVal(Traits::Get(&impl_, i)); + } + Traits::Clear(&impl_); + } + + /** + * Reserve capacity in the vector. + * (Efficiency gains depend on the backing implementation.) + */ + void ReserveCapacity(size_t capacity) { + Traits::ReserveCapacity(&impl_, capacity); + } + + private: + static PersistentContainerValue ClearAndLeak(Global* persistent) { + V* v = persistent->val_; + persistent->val_ = 0; + return reinterpret_cast(v); + } + + static V* FromVal(PersistentContainerValue v) { + return reinterpret_cast(v); + } + + Isolate* isolate_; + typename Traits::Impl impl_; +}; + +} // namespace v8 + +#endif // V8_UTIL_H diff --git a/calclib/src/main/cpp/include/v8-version-string.h b/calclib/src/main/cpp/include/v8-version-string.h new file mode 100644 index 0000000..075282d --- /dev/null +++ b/calclib/src/main/cpp/include/v8-version-string.h @@ -0,0 +1,33 @@ +// Copyright 2017 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_VERSION_STRING_H_ +#define V8_VERSION_STRING_H_ + +#include "v8-version.h" // NOLINT(build/include) + +// This is here rather than v8-version.h to keep that file simple and +// machine-processable. + +#if V8_IS_CANDIDATE_VERSION +#define V8_CANDIDATE_STRING " (candidate)" +#else +#define V8_CANDIDATE_STRING "" +#endif + +#define V8_SX(x) #x +#define V8_S(x) V8_SX(x) + +#if V8_PATCH_LEVEL > 0 +#define V8_VERSION_STRING \ + V8_S(V8_MAJOR_VERSION) \ + "." V8_S(V8_MINOR_VERSION) "." V8_S(V8_BUILD_NUMBER) "." V8_S( \ + V8_PATCH_LEVEL) V8_CANDIDATE_STRING +#else +#define V8_VERSION_STRING \ + V8_S(V8_MAJOR_VERSION) \ + "." V8_S(V8_MINOR_VERSION) "." V8_S(V8_BUILD_NUMBER) V8_CANDIDATE_STRING +#endif + +#endif // V8_VERSION_STRING_H_ diff --git a/calclib/src/main/cpp/include/v8-version.h b/calclib/src/main/cpp/include/v8-version.h new file mode 100644 index 0000000..16133c3 --- /dev/null +++ b/calclib/src/main/cpp/include/v8-version.h @@ -0,0 +1,20 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_INCLUDE_VERSION_H_ // V8_VERSION_H_ conflicts with src/version.h +#define V8_INCLUDE_VERSION_H_ + +// These macros define the version number for the current version. +// NOTE these macros are used by some of the tool scripts and the build +// system so their names cannot be changed without changing the scripts. +#define V8_MAJOR_VERSION 5 +#define V8_MINOR_VERSION 5 +#define V8_BUILD_NUMBER 372 +#define V8_PATCH_LEVEL 32 + +// Use 1 for candidates and 0 otherwise. +// (Boolean macro values are not supported by all preprocessors.) +#define V8_IS_CANDIDATE_VERSION 0 + +#endif // V8_INCLUDE_VERSION_H_ diff --git a/calclib/src/main/cpp/include/v8.h b/calclib/src/main/cpp/include/v8.h new file mode 100644 index 0000000..36edf53 --- /dev/null +++ b/calclib/src/main/cpp/include/v8.h @@ -0,0 +1,9660 @@ +// Copyright 2012 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** \mainpage V8 API Reference Guide + * + * V8 is Google's open source JavaScript engine. + * + * This set of documents provides reference material generated from the + * V8 header file, include/v8.h. + * + * For other documentation see http://code.google.com/apis/v8/ + */ + +#ifndef INCLUDE_V8_H_ +#define INCLUDE_V8_H_ + +#include +#include +#include +#include +#include +#include + +#include "v8-version.h" // NOLINT(build/include) +#include "v8config.h" // NOLINT(build/include) + +// We reserve the V8_* prefix for macros defined in V8 public API and +// assume there are no name conflicts with the embedder's code. + +#ifdef V8_OS_WIN + +// Setup for Windows DLL export/import. When building the V8 DLL the +// BUILDING_V8_SHARED needs to be defined. When building a program which uses +// the V8 DLL USING_V8_SHARED needs to be defined. When either building the V8 +// static library or building a program which uses the V8 static library neither +// BUILDING_V8_SHARED nor USING_V8_SHARED should be defined. +#if defined(BUILDING_V8_SHARED) && defined(USING_V8_SHARED) +#error both BUILDING_V8_SHARED and USING_V8_SHARED are set - please check the\ + build configuration to ensure that at most one of these is set +#endif + +#ifdef BUILDING_V8_SHARED +# define V8_EXPORT __declspec(dllexport) +#elif USING_V8_SHARED +# define V8_EXPORT __declspec(dllimport) +#else +# define V8_EXPORT +#endif // BUILDING_V8_SHARED + +#else // V8_OS_WIN + +// Setup for Linux shared library export. +#if V8_HAS_ATTRIBUTE_VISIBILITY +# ifdef BUILDING_V8_SHARED +# define V8_EXPORT __attribute__ ((visibility("default"))) +# else +# define V8_EXPORT +# endif +#else +# define V8_EXPORT +#endif + +#endif // V8_OS_WIN + +/** + * The v8 JavaScript engine. + */ +namespace v8 { + +class AccessorSignature; +class Array; +class ArrayBuffer; +class Boolean; +class BooleanObject; +class Context; +class CpuProfiler; +class Data; +class Date; +class External; +class Function; +class FunctionTemplate; +class HeapProfiler; +class ImplementationUtilities; +class Int32; +class Integer; +class Isolate; +template +class Maybe; +class Name; +class Number; +class NumberObject; +class Object; +class ObjectOperationDescriptor; +class ObjectTemplate; +class Platform; +class Primitive; +class Promise; +class PropertyDescriptor; +class Proxy; +class RawOperationDescriptor; +class Script; +class SharedArrayBuffer; +class Signature; +class StartupData; +class StackFrame; +class StackTrace; +class String; +class StringObject; +class Symbol; +class SymbolObject; +class Private; +class Uint32; +class Utils; +class Value; +template class Local; +template +class MaybeLocal; +template class Eternal; +template class NonCopyablePersistentTraits; +template class PersistentBase; +template > +class Persistent; +template +class Global; +template class PersistentValueMap; +template +class PersistentValueMapBase; +template +class GlobalValueMap; +template class PersistentValueVector; +template class WeakCallbackObject; +class FunctionTemplate; +class ObjectTemplate; +class Data; +template class FunctionCallbackInfo; +template class PropertyCallbackInfo; +class StackTrace; +class StackFrame; +class Isolate; +class CallHandlerHelper; +class EscapableHandleScope; +template class ReturnValue; + +namespace experimental { +class FastAccessorBuilder; +} // namespace experimental + +namespace internal { +class Arguments; +class Heap; +class HeapObject; +class Isolate; +class Object; +struct StreamedSource; +template class CustomArguments; +class PropertyCallbackArguments; +class FunctionCallbackArguments; +class GlobalHandles; +} // namespace internal + + +/** + * General purpose unique identifier. + */ +class UniqueId { + public: + explicit UniqueId(intptr_t data) + : data_(data) {} + + bool operator==(const UniqueId& other) const { + return data_ == other.data_; + } + + bool operator!=(const UniqueId& other) const { + return data_ != other.data_; + } + + bool operator<(const UniqueId& other) const { + return data_ < other.data_; + } + + private: + intptr_t data_; +}; + +// --- Handles --- + +#define TYPE_CHECK(T, S) \ + while (false) { \ + *(static_cast(0)) = static_cast(0); \ + } + + +/** + * An object reference managed by the v8 garbage collector. + * + * All objects returned from v8 have to be tracked by the garbage + * collector so that it knows that the objects are still alive. Also, + * because the garbage collector may move objects, it is unsafe to + * point directly to an object. Instead, all objects are stored in + * handles which are known by the garbage collector and updated + * whenever an object moves. Handles should always be passed by value + * (except in cases like out-parameters) and they should never be + * allocated on the heap. + * + * There are two types of handles: local and persistent handles. + * Local handles are light-weight and transient and typically used in + * local operations. They are managed by HandleScopes. Persistent + * handles can be used when storing objects across several independent + * operations and have to be explicitly deallocated when they're no + * longer used. + * + * It is safe to extract the object stored in the handle by + * dereferencing the handle (for instance, to extract the Object* from + * a Local); the value will still be governed by a handle + * behind the scenes and the same rules apply to these values as to + * their handles. + */ +template +class Local { + public: + V8_INLINE Local() : val_(0) {} + template + V8_INLINE Local(Local that) + : val_(reinterpret_cast(*that)) { + /** + * This check fails when trying to convert between incompatible + * handles. For example, converting from a Local to a + * Local. + */ + TYPE_CHECK(T, S); + } + + /** + * Returns true if the handle is empty. + */ + V8_INLINE bool IsEmpty() const { return val_ == 0; } + + /** + * Sets the handle to be empty. IsEmpty() will then return true. + */ + V8_INLINE void Clear() { val_ = 0; } + + V8_INLINE T* operator->() const { return val_; } + + V8_INLINE T* operator*() const { return val_; } + + /** + * Checks whether two handles are the same. + * Returns true if both are empty, or if the objects + * to which they refer are identical. + * The handles' references are not checked. + */ + template + V8_INLINE bool operator==(const Local& that) const { + internal::Object** a = reinterpret_cast(this->val_); + internal::Object** b = reinterpret_cast(that.val_); + if (a == 0) return b == 0; + if (b == 0) return false; + return *a == *b; + } + + template V8_INLINE bool operator==( + const PersistentBase& that) const { + internal::Object** a = reinterpret_cast(this->val_); + internal::Object** b = reinterpret_cast(that.val_); + if (a == 0) return b == 0; + if (b == 0) return false; + return *a == *b; + } + + /** + * Checks whether two handles are different. + * Returns true if only one of the handles is empty, or if + * the objects to which they refer are different. + * The handles' references are not checked. + */ + template + V8_INLINE bool operator!=(const Local& that) const { + return !operator==(that); + } + + template V8_INLINE bool operator!=( + const Persistent& that) const { + return !operator==(that); + } + + template V8_INLINE static Local Cast(Local that) { +#ifdef V8_ENABLE_CHECKS + // If we're going to perform the type check then we have to check + // that the handle isn't empty before doing the checked cast. + if (that.IsEmpty()) return Local(); +#endif + return Local(T::Cast(*that)); + } + + template + V8_INLINE Local As() const { + return Local::Cast(*this); + } + + /** + * Create a local handle for the content of another handle. + * The referee is kept alive by the local handle even when + * the original handle is destroyed/disposed. + */ + V8_INLINE static Local New(Isolate* isolate, Local that); + V8_INLINE static Local New(Isolate* isolate, + const PersistentBase& that); + + private: + friend class Utils; + template friend class Eternal; + template friend class PersistentBase; + template friend class Persistent; + template friend class Local; + template + friend class MaybeLocal; + template friend class FunctionCallbackInfo; + template friend class PropertyCallbackInfo; + friend class String; + friend class Object; + friend class Context; + friend class Private; + template friend class internal::CustomArguments; + friend Local Undefined(Isolate* isolate); + friend Local Null(Isolate* isolate); + friend Local True(Isolate* isolate); + friend Local False(Isolate* isolate); + friend class HandleScope; + friend class EscapableHandleScope; + template + friend class PersistentValueMapBase; + template friend class PersistentValueVector; + template + friend class ReturnValue; + + explicit V8_INLINE Local(T* that) : val_(that) {} + V8_INLINE static Local New(Isolate* isolate, T* that); + T* val_; +}; + + +#if !defined(V8_IMMINENT_DEPRECATION_WARNINGS) +// Handle is an alias for Local for historical reasons. +template +using Handle = Local; +#endif + + +/** + * A MaybeLocal<> is a wrapper around Local<> that enforces a check whether + * the Local<> is empty before it can be used. + * + * If an API method returns a MaybeLocal<>, the API method can potentially fail + * either because an exception is thrown, or because an exception is pending, + * e.g. because a previous API call threw an exception that hasn't been caught + * yet, or because a TerminateExecution exception was thrown. In that case, an + * empty MaybeLocal is returned. + */ +template +class MaybeLocal { + public: + V8_INLINE MaybeLocal() : val_(nullptr) {} + template + V8_INLINE MaybeLocal(Local that) + : val_(reinterpret_cast(*that)) { + TYPE_CHECK(T, S); + } + + V8_INLINE bool IsEmpty() const { return val_ == nullptr; } + + template + V8_WARN_UNUSED_RESULT V8_INLINE bool ToLocal(Local* out) const { + out->val_ = IsEmpty() ? nullptr : this->val_; + return !IsEmpty(); + } + + // Will crash if the MaybeLocal<> is empty. + V8_INLINE Local ToLocalChecked(); + + template + V8_INLINE Local FromMaybe(Local default_value) const { + return IsEmpty() ? default_value : Local(val_); + } + + private: + T* val_; +}; + + +// Eternal handles are set-once handles that live for the life of the isolate. +template class Eternal { + public: + V8_INLINE Eternal() : index_(kInitialValue) { } + template + V8_INLINE Eternal(Isolate* isolate, Local handle) : index_(kInitialValue) { + Set(isolate, handle); + } + // Can only be safely called if already set. + V8_INLINE Local Get(Isolate* isolate); + V8_INLINE bool IsEmpty() { return index_ == kInitialValue; } + template V8_INLINE void Set(Isolate* isolate, Local handle); + + private: + static const int kInitialValue = -1; + int index_; +}; + + +static const int kInternalFieldsInWeakCallback = 2; + + +template +class WeakCallbackInfo { + public: + typedef void (*Callback)(const WeakCallbackInfo& data); + + WeakCallbackInfo(Isolate* isolate, T* parameter, + void* internal_fields[kInternalFieldsInWeakCallback], + Callback* callback) + : isolate_(isolate), parameter_(parameter), callback_(callback) { + for (int i = 0; i < kInternalFieldsInWeakCallback; ++i) { + internal_fields_[i] = internal_fields[i]; + } + } + + V8_INLINE Isolate* GetIsolate() const { return isolate_; } + V8_INLINE T* GetParameter() const { return parameter_; } + V8_INLINE void* GetInternalField(int index) const; + + V8_INLINE V8_DEPRECATED("use indexed version", + void* GetInternalField1() const) { + return internal_fields_[0]; + } + V8_INLINE V8_DEPRECATED("use indexed version", + void* GetInternalField2() const) { + return internal_fields_[1]; + } + + V8_DEPRECATED("Not realiable once SetSecondPassCallback() was used.", + bool IsFirstPass() const) { + return callback_ != nullptr; + } + + // When first called, the embedder MUST Reset() the Global which triggered the + // callback. The Global itself is unusable for anything else. No v8 other api + // calls may be called in the first callback. Should additional work be + // required, the embedder must set a second pass callback, which will be + // called after all the initial callbacks are processed. + // Calling SetSecondPassCallback on the second pass will immediately crash. + void SetSecondPassCallback(Callback callback) const { *callback_ = callback; } + + private: + Isolate* isolate_; + T* parameter_; + Callback* callback_; + void* internal_fields_[kInternalFieldsInWeakCallback]; +}; + + +// kParameter will pass a void* parameter back to the callback, kInternalFields +// will pass the first two internal fields back to the callback, kFinalizer +// will pass a void* parameter back, but is invoked before the object is +// actually collected, so it can be resurrected. In the last case, it is not +// possible to request a second pass callback. +enum class WeakCallbackType { kParameter, kInternalFields, kFinalizer }; + +/** + * A reporter class that embedder will use to report reachable references found + * by EmbedderHeapTracer. + */ +class V8_EXPORT EmbedderReachableReferenceReporter { + public: + virtual void ReportExternalReference(Value* object) = 0; + virtual ~EmbedderReachableReferenceReporter() = default; +}; + +/** + * An object reference that is independent of any handle scope. Where + * a Local handle only lives as long as the HandleScope in which it was + * allocated, a PersistentBase handle remains valid until it is explicitly + * disposed. + * + * A persistent handle contains a reference to a storage cell within + * the v8 engine which holds an object value and which is updated by + * the garbage collector whenever the object is moved. A new storage + * cell can be created using the constructor or PersistentBase::Reset and + * existing handles can be disposed using PersistentBase::Reset. + * + */ +template class PersistentBase { + public: + /** + * If non-empty, destroy the underlying storage cell + * IsEmpty() will return true after this call. + */ + V8_INLINE void Reset(); + /** + * If non-empty, destroy the underlying storage cell + * and create a new one with the contents of other if other is non empty + */ + template + V8_INLINE void Reset(Isolate* isolate, const Local& other); + + /** + * If non-empty, destroy the underlying storage cell + * and create a new one with the contents of other if other is non empty + */ + template + V8_INLINE void Reset(Isolate* isolate, const PersistentBase& other); + + V8_INLINE bool IsEmpty() const { return val_ == NULL; } + V8_INLINE void Empty() { val_ = 0; } + + V8_INLINE Local Get(Isolate* isolate) const { + return Local::New(isolate, *this); + } + + template + V8_INLINE bool operator==(const PersistentBase& that) const { + internal::Object** a = reinterpret_cast(this->val_); + internal::Object** b = reinterpret_cast(that.val_); + if (a == NULL) return b == NULL; + if (b == NULL) return false; + return *a == *b; + } + + template + V8_INLINE bool operator==(const Local& that) const { + internal::Object** a = reinterpret_cast(this->val_); + internal::Object** b = reinterpret_cast(that.val_); + if (a == NULL) return b == NULL; + if (b == NULL) return false; + return *a == *b; + } + + template + V8_INLINE bool operator!=(const PersistentBase& that) const { + return !operator==(that); + } + + template + V8_INLINE bool operator!=(const Local& that) const { + return !operator==(that); + } + + /** + * Install a finalization callback on this object. + * NOTE: There is no guarantee as to *when* or even *if* the callback is + * invoked. The invocation is performed solely on a best effort basis. + * As always, GC-based finalization should *not* be relied upon for any + * critical form of resource management! + */ + template + V8_INLINE void SetWeak(P* parameter, + typename WeakCallbackInfo

::Callback callback, + WeakCallbackType type); + + /** + * Turns this handle into a weak phantom handle without finalization callback. + * The handle will be reset automatically when the garbage collector detects + * that the object is no longer reachable. + * A related function Isolate::NumberOfPhantomHandleResetsSinceLastCall + * returns how many phantom handles were reset by the garbage collector. + */ + V8_INLINE void SetWeak(); + + template + V8_INLINE P* ClearWeak(); + + // TODO(dcarney): remove this. + V8_INLINE void ClearWeak() { ClearWeak(); } + + /** + * Deprecated. + * TODO(hlopko): remove once migration to reporter is finished. + */ + V8_INLINE void RegisterExternalReference(Isolate* isolate) const {} + + /** + * Allows the embedder to tell the v8 garbage collector that a certain object + * is alive. Only allowed when the embedder is asked to trace its heap by + * EmbedderHeapTracer. + */ + V8_INLINE void RegisterExternalReference( + EmbedderReachableReferenceReporter* reporter) const; + + /** + * Marks the reference to this object independent. Garbage collector is free + * to ignore any object groups containing this object. Weak callback for an + * independent handle should not assume that it will be preceded by a global + * GC prologue callback or followed by a global GC epilogue callback. + */ + V8_INLINE void MarkIndependent(); + + /** + * Marks the reference to this object partially dependent. Partially dependent + * handles only depend on other partially dependent handles and these + * dependencies are provided through object groups. It provides a way to build + * smaller object groups for young objects that represent only a subset of all + * external dependencies. This mark is automatically cleared after each + * garbage collection. + */ + V8_INLINE V8_DEPRECATED( + "deprecated optimization, do not use partially dependent groups", + void MarkPartiallyDependent()); + + /** + * Marks the reference to this object as active. The scavenge garbage + * collection should not reclaim the objects marked as active. + * This bit is cleared after the each garbage collection pass. + */ + V8_INLINE void MarkActive(); + + V8_INLINE bool IsIndependent() const; + + /** Checks if the handle holds the only reference to an object. */ + V8_INLINE bool IsNearDeath() const; + + /** Returns true if the handle's reference is weak. */ + V8_INLINE bool IsWeak() const; + + /** + * Assigns a wrapper class ID to the handle. See RetainedObjectInfo interface + * description in v8-profiler.h for details. + */ + V8_INLINE void SetWrapperClassId(uint16_t class_id); + + /** + * Returns the class ID previously assigned to this handle or 0 if no class ID + * was previously assigned. + */ + V8_INLINE uint16_t WrapperClassId() const; + + PersistentBase(const PersistentBase& other) = delete; // NOLINT + void operator=(const PersistentBase&) = delete; + + private: + friend class Isolate; + friend class Utils; + template friend class Local; + template friend class Persistent; + template + friend class Global; + template friend class PersistentBase; + template friend class ReturnValue; + template + friend class PersistentValueMapBase; + template friend class PersistentValueVector; + friend class Object; + + explicit V8_INLINE PersistentBase(T* val) : val_(val) {} + V8_INLINE static T* New(Isolate* isolate, T* that); + + T* val_; +}; + + +/** + * Default traits for Persistent. This class does not allow + * use of the copy constructor or assignment operator. + * At present kResetInDestructor is not set, but that will change in a future + * version. + */ +template +class NonCopyablePersistentTraits { + public: + typedef Persistent > NonCopyablePersistent; + static const bool kResetInDestructor = false; + template + V8_INLINE static void Copy(const Persistent& source, + NonCopyablePersistent* dest) { + Uncompilable(); + } + // TODO(dcarney): come up with a good compile error here. + template V8_INLINE static void Uncompilable() { + TYPE_CHECK(O, Primitive); + } +}; + + +/** + * Helper class traits to allow copying and assignment of Persistent. + * This will clone the contents of storage cell, but not any of the flags, etc. + */ +template +struct CopyablePersistentTraits { + typedef Persistent > CopyablePersistent; + static const bool kResetInDestructor = true; + template + static V8_INLINE void Copy(const Persistent& source, + CopyablePersistent* dest) { + // do nothing, just allow copy + } +}; + + +/** + * A PersistentBase which allows copy and assignment. + * + * Copy, assignment and destructor bevavior is controlled by the traits + * class M. + * + * Note: Persistent class hierarchy is subject to future changes. + */ +template class Persistent : public PersistentBase { + public: + /** + * A Persistent with no storage cell. + */ + V8_INLINE Persistent() : PersistentBase(0) { } + /** + * Construct a Persistent from a Local. + * When the Local is non-empty, a new storage cell is created + * pointing to the same object, and no flags are set. + */ + template + V8_INLINE Persistent(Isolate* isolate, Local that) + : PersistentBase(PersistentBase::New(isolate, *that)) { + TYPE_CHECK(T, S); + } + /** + * Construct a Persistent from a Persistent. + * When the Persistent is non-empty, a new storage cell is created + * pointing to the same object, and no flags are set. + */ + template + V8_INLINE Persistent(Isolate* isolate, const Persistent& that) + : PersistentBase(PersistentBase::New(isolate, *that)) { + TYPE_CHECK(T, S); + } + /** + * The copy constructors and assignment operator create a Persistent + * exactly as the Persistent constructor, but the Copy function from the + * traits class is called, allowing the setting of flags based on the + * copied Persistent. + */ + V8_INLINE Persistent(const Persistent& that) : PersistentBase(0) { + Copy(that); + } + template + V8_INLINE Persistent(const Persistent& that) : PersistentBase(0) { + Copy(that); + } + V8_INLINE Persistent& operator=(const Persistent& that) { // NOLINT + Copy(that); + return *this; + } + template + V8_INLINE Persistent& operator=(const Persistent& that) { // NOLINT + Copy(that); + return *this; + } + /** + * The destructor will dispose the Persistent based on the + * kResetInDestructor flags in the traits class. Since not calling dispose + * can result in a memory leak, it is recommended to always set this flag. + */ + V8_INLINE ~Persistent() { + if (M::kResetInDestructor) this->Reset(); + } + + // TODO(dcarney): this is pretty useless, fix or remove + template + V8_INLINE static Persistent& Cast(const Persistent& that) { // NOLINT +#ifdef V8_ENABLE_CHECKS + // If we're going to perform the type check then we have to check + // that the handle isn't empty before doing the checked cast. + if (!that.IsEmpty()) T::Cast(*that); +#endif + return reinterpret_cast&>(const_cast&>(that)); + } + + // TODO(dcarney): this is pretty useless, fix or remove + template + V8_INLINE Persistent& As() const { // NOLINT + return Persistent::Cast(*this); + } + + private: + friend class Isolate; + friend class Utils; + template friend class Local; + template friend class Persistent; + template friend class ReturnValue; + + explicit V8_INLINE Persistent(T* that) : PersistentBase(that) {} + V8_INLINE T* operator*() const { return this->val_; } + template + V8_INLINE void Copy(const Persistent& that); +}; + + +/** + * A PersistentBase which has move semantics. + * + * Note: Persistent class hierarchy is subject to future changes. + */ +template +class Global : public PersistentBase { + public: + /** + * A Global with no storage cell. + */ + V8_INLINE Global() : PersistentBase(nullptr) {} + /** + * Construct a Global from a Local. + * When the Local is non-empty, a new storage cell is created + * pointing to the same object, and no flags are set. + */ + template + V8_INLINE Global(Isolate* isolate, Local that) + : PersistentBase(PersistentBase::New(isolate, *that)) { + TYPE_CHECK(T, S); + } + /** + * Construct a Global from a PersistentBase. + * When the Persistent is non-empty, a new storage cell is created + * pointing to the same object, and no flags are set. + */ + template + V8_INLINE Global(Isolate* isolate, const PersistentBase& that) + : PersistentBase(PersistentBase::New(isolate, that.val_)) { + TYPE_CHECK(T, S); + } + /** + * Move constructor. + */ + V8_INLINE Global(Global&& other) : PersistentBase(other.val_) { // NOLINT + other.val_ = nullptr; + } + V8_INLINE ~Global() { this->Reset(); } + /** + * Move via assignment. + */ + template + V8_INLINE Global& operator=(Global&& rhs) { // NOLINT + TYPE_CHECK(T, S); + if (this != &rhs) { + this->Reset(); + this->val_ = rhs.val_; + rhs.val_ = nullptr; + } + return *this; + } + /** + * Pass allows returning uniques from functions, etc. + */ + Global Pass() { return static_cast(*this); } // NOLINT + + /* + * For compatibility with Chromium's base::Bind (base::Passed). + */ + typedef void MoveOnlyTypeForCPP03; + + Global(const Global&) = delete; + void operator=(const Global&) = delete; + + private: + template + friend class ReturnValue; + V8_INLINE T* operator*() const { return this->val_; } +}; + + +// UniquePersistent is an alias for Global for historical reason. +template +using UniquePersistent = Global; + + + /** + * A stack-allocated class that governs a number of local handles. + * After a handle scope has been created, all local handles will be + * allocated within that handle scope until either the handle scope is + * deleted or another handle scope is created. If there is already a + * handle scope and a new one is created, all allocations will take + * place in the new handle scope until it is deleted. After that, + * new handles will again be allocated in the original handle scope. + * + * After the handle scope of a local handle has been deleted the + * garbage collector will no longer track the object stored in the + * handle and may deallocate it. The behavior of accessing a handle + * for which the handle scope has been deleted is undefined. + */ +class V8_EXPORT HandleScope { + public: + explicit HandleScope(Isolate* isolate); + + ~HandleScope(); + + /** + * Counts the number of allocated handles. + */ + static int NumberOfHandles(Isolate* isolate); + + V8_INLINE Isolate* GetIsolate() const { + return reinterpret_cast(isolate_); + } + + HandleScope(const HandleScope&) = delete; + void operator=(const HandleScope&) = delete; + void* operator new(size_t size) = delete; + void operator delete(void*, size_t) = delete; + + protected: + V8_INLINE HandleScope() {} + + void Initialize(Isolate* isolate); + + static internal::Object** CreateHandle(internal::Isolate* isolate, + internal::Object* value); + + private: + // Uses heap_object to obtain the current Isolate. + static internal::Object** CreateHandle(internal::HeapObject* heap_object, + internal::Object* value); + + internal::Isolate* isolate_; + internal::Object** prev_next_; + internal::Object** prev_limit_; + + // Local::New uses CreateHandle with an Isolate* parameter. + template friend class Local; + + // Object::GetInternalField and Context::GetEmbedderData use CreateHandle with + // a HeapObject* in their shortcuts. + friend class Object; + friend class Context; +}; + + +/** + * A HandleScope which first allocates a handle in the current scope + * which will be later filled with the escape value. + */ +class V8_EXPORT EscapableHandleScope : public HandleScope { + public: + explicit EscapableHandleScope(Isolate* isolate); + V8_INLINE ~EscapableHandleScope() {} + + /** + * Pushes the value into the previous scope and returns a handle to it. + * Cannot be called twice. + */ + template + V8_INLINE Local Escape(Local value) { + internal::Object** slot = + Escape(reinterpret_cast(*value)); + return Local(reinterpret_cast(slot)); + } + + EscapableHandleScope(const EscapableHandleScope&) = delete; + void operator=(const EscapableHandleScope&) = delete; + void* operator new(size_t size) = delete; + void operator delete(void*, size_t) = delete; + + private: + internal::Object** Escape(internal::Object** escape_value); + internal::Object** escape_slot_; +}; + +class V8_EXPORT SealHandleScope { + public: + SealHandleScope(Isolate* isolate); + ~SealHandleScope(); + + SealHandleScope(const SealHandleScope&) = delete; + void operator=(const SealHandleScope&) = delete; + void* operator new(size_t size) = delete; + void operator delete(void*, size_t) = delete; + + private: + internal::Isolate* const isolate_; + internal::Object** prev_limit_; + int prev_sealed_level_; +}; + + +// --- Special objects --- + + +/** + * The superclass of values and API object templates. + */ +class V8_EXPORT Data { + private: + Data(); +}; + + +/** + * The optional attributes of ScriptOrigin. + */ +class ScriptOriginOptions { + public: + V8_INLINE ScriptOriginOptions(bool is_embedder_debug_script = false, + bool is_shared_cross_origin = false, + bool is_opaque = false) + : flags_((is_embedder_debug_script ? kIsEmbedderDebugScript : 0) | + (is_shared_cross_origin ? kIsSharedCrossOrigin : 0) | + (is_opaque ? kIsOpaque : 0)) {} + V8_INLINE ScriptOriginOptions(int flags) + : flags_(flags & + (kIsEmbedderDebugScript | kIsSharedCrossOrigin | kIsOpaque)) {} + bool IsEmbedderDebugScript() const { + return (flags_ & kIsEmbedderDebugScript) != 0; + } + bool IsSharedCrossOrigin() const { + return (flags_ & kIsSharedCrossOrigin) != 0; + } + bool IsOpaque() const { return (flags_ & kIsOpaque) != 0; } + int Flags() const { return flags_; } + + private: + enum { + kIsEmbedderDebugScript = 1, + kIsSharedCrossOrigin = 1 << 1, + kIsOpaque = 1 << 2 + }; + const int flags_; +}; + +/** + * The origin, within a file, of a script. + */ +class ScriptOrigin { + public: + V8_INLINE ScriptOrigin( + Local resource_name, + Local resource_line_offset = Local(), + Local resource_column_offset = Local(), + Local resource_is_shared_cross_origin = Local(), + Local script_id = Local(), + Local resource_is_embedder_debug_script = Local(), + Local source_map_url = Local(), + Local resource_is_opaque = Local()); + V8_INLINE Local ResourceName() const; + V8_INLINE Local ResourceLineOffset() const; + V8_INLINE Local ResourceColumnOffset() const; + /** + * Returns true for embedder's debugger scripts + */ + V8_INLINE Local ScriptID() const; + V8_INLINE Local SourceMapUrl() const; + V8_INLINE ScriptOriginOptions Options() const { return options_; } + + private: + Local resource_name_; + Local resource_line_offset_; + Local resource_column_offset_; + ScriptOriginOptions options_; + Local script_id_; + Local source_map_url_; +}; + + +/** + * A compiled JavaScript script, not yet tied to a Context. + */ +class V8_EXPORT UnboundScript { + public: + /** + * Binds the script to the currently entered context. + */ + Local