Browse Source

Merge pull request #6691 in CORE/base-third from release/11.0 to bugfix/11.0

* commit 'b7603c29a7e9bae515c25f38df319a667c00a38f':
  KERNEL-12469 js引擎j2v8剥离成独立插件
bugfix/11.0
superman 2 years ago
parent
commit
0f2b822f14
  1. 1
      base-third-project/base-third-step1/pom.xml
  2. 3
      build.third_step1-jdk11.gradle
  3. 3
      build.third_step1.gradle
  4. 6
      fine-j2v8/.gitignore
  5. 18
      fine-j2v8/pom.xml
  6. 37
      fine-j2v8/src/main/java/com/eclipsesource/v8/JavaCallback.java
  7. 33
      fine-j2v8/src/main/java/com/eclipsesource/v8/JavaVoidCallback.java
  8. 243
      fine-j2v8/src/main/java/com/eclipsesource/v8/LibraryLoader.java
  9. 239
      fine-j2v8/src/main/java/com/eclipsesource/v8/NodeJS.java
  10. 12
      fine-j2v8/src/main/java/com/eclipsesource/v8/Platform.java
  11. 319
      fine-j2v8/src/main/java/com/eclipsesource/v8/PlatformDetector.java
  12. 34
      fine-j2v8/src/main/java/com/eclipsesource/v8/ReferenceHandler.java
  13. 30
      fine-j2v8/src/main/java/com/eclipsesource/v8/Releasable.java
  14. 5
      fine-j2v8/src/main/java/com/eclipsesource/v8/SignatureProvider.java
  15. 1687
      fine-j2v8/src/main/java/com/eclipsesource/v8/V8.java
  16. 1189
      fine-j2v8/src/main/java/com/eclipsesource/v8/V8Array.java
  17. 472
      fine-j2v8/src/main/java/com/eclipsesource/v8/V8ArrayBuffer.java
  18. 98
      fine-j2v8/src/main/java/com/eclipsesource/v8/V8Function.java
  19. 113
      fine-j2v8/src/main/java/com/eclipsesource/v8/V8Locker.java
  20. 1005
      fine-j2v8/src/main/java/com/eclipsesource/v8/V8Object.java
  21. 17
      fine-j2v8/src/main/java/com/eclipsesource/v8/V8OutOfMemoryError.java
  22. 32
      fine-j2v8/src/main/java/com/eclipsesource/v8/V8ResultUndefined.java
  23. 27
      fine-j2v8/src/main/java/com/eclipsesource/v8/V8RuntimeException.java
  24. 24
      fine-j2v8/src/main/java/com/eclipsesource/v8/V8ScriptCompilationException.java
  25. 165
      fine-j2v8/src/main/java/com/eclipsesource/v8/V8ScriptException.java
  26. 40
      fine-j2v8/src/main/java/com/eclipsesource/v8/V8ScriptExecutionException.java
  27. 183
      fine-j2v8/src/main/java/com/eclipsesource/v8/V8TypedArray.java
  28. 391
      fine-j2v8/src/main/java/com/eclipsesource/v8/V8Value.java
  29. 55
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/BreakEvent.java
  30. 20
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/BreakHandler.java
  31. 24
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/CompileEvent.java
  32. 363
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/DebugHandler.java
  33. 40
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/EventData.java
  34. 24
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/ExceptionEvent.java
  35. 100
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/ExecutionState.java
  36. 94
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/ScriptBreakPoint.java
  37. 25
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/StepAction.java
  38. 693
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/V8DebugServer.java
  39. 40
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/ArrayMirror.java
  40. 33
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/BooleanMirror.java
  41. 225
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/Frame.java
  42. 56
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/FunctionMirror.java
  43. 294
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/Mirror.java
  44. 35
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/NullMirror.java
  45. 34
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/NumberMirror.java
  46. 98
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/ObjectMirror.java
  47. 73
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/PropertiesArray.java
  48. 52
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/PropertyMirror.java
  49. 156
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/Scope.java
  50. 84
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/SourceLocation.java
  51. 34
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/StringMirror.java
  52. 35
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/UndefinedMirror.java
  53. 40
      fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/ValueMirror.java
  54. 7
      fine-j2v8/src/main/java/com/eclipsesource/v8/inspector/DebuggerConnectionListener.java
  55. 67
      fine-j2v8/src/main/java/com/eclipsesource/v8/inspector/V8Inspector.java
  56. 7
      fine-j2v8/src/main/java/com/eclipsesource/v8/inspector/V8InspectorDelegate.java
  57. 69
      fine-j2v8/src/main/java/com/eclipsesource/v8/utils/ArrayBuffer.java
  58. 94
      fine-j2v8/src/main/java/com/eclipsesource/v8/utils/ConcurrentV8.java
  59. 138
      fine-j2v8/src/main/java/com/eclipsesource/v8/utils/MemoryManager.java
  60. 55
      fine-j2v8/src/main/java/com/eclipsesource/v8/utils/SingleTypeAdapter.java
  61. 39
      fine-j2v8/src/main/java/com/eclipsesource/v8/utils/TypeAdapter.java
  62. 73
      fine-j2v8/src/main/java/com/eclipsesource/v8/utils/TypedArray.java
  63. 253
      fine-j2v8/src/main/java/com/eclipsesource/v8/utils/V8Executor.java
  64. 185
      fine-j2v8/src/main/java/com/eclipsesource/v8/utils/V8Map.java
  65. 703
      fine-j2v8/src/main/java/com/eclipsesource/v8/utils/V8ObjectUtils.java
  66. 176
      fine-j2v8/src/main/java/com/eclipsesource/v8/utils/V8PropertyMap.java
  67. 29
      fine-j2v8/src/main/java/com/eclipsesource/v8/utils/V8Runnable.java
  68. 57
      fine-j2v8/src/main/java/com/eclipsesource/v8/utils/V8Thread.java
  69. BIN
      fine-j2v8/src/main/resources/libj2v8-linux-aarch_64.so
  70. BIN
      fine-j2v8/src/main/resources/libj2v8-linux-x86_64.so
  71. BIN
      fine-j2v8/src/main/resources/libj2v8-macosx-x86_64.dylib
  72. BIN
      fine-j2v8/src/main/resources/libj2v8-windows-x86_64.dll

1
base-third-project/base-third-step1/pom.xml

@ -27,7 +27,6 @@
<module>../../fine-iconloader</module>
<module>../../fine-icu4j</module>
<module>../../fine-imageJ</module>
<module>../../fine-j2v8</module>
<!-- <module>../../fine-jai</module>-->
<module>../../fine-jboss-transaction-api</module>
<module>../../fine-jgit</module>

3
build.third_step1-jdk11.gradle

@ -43,7 +43,6 @@ sourceSets{
"${srcDir}/fine-hsqldb/src/main/java",
"${srcDir}/fine-iconloader/src/main/java",
"${srcDir}/fine-icu4j/src/main/java",
"${srcDir}/fine-j2v8/src/main/java",
// "${srcDir}/fine-jai/src/main/java",
"${srcDir}/fine-jboss-transaction-api/src/main/java",
"${srcDir}/fine-jgit/src/main/java",
@ -95,8 +94,6 @@ def resourceDirs = [
"${srcDir}/fine-iconloader/src/main/resources",
"${srcDir}/fine-icu4j/src/main/java",
"${srcDir}/fine-icu4j/src/main/resources",
"${srcDir}/fine-j2v8/src/main/java",
"${srcDir}/fine-j2v8/src/main/resources",
// "${srcDir}/fine-jai/src/main/java",
"${srcDir}/fine-jboss-transaction-api/src/main/java",
"${srcDir}/fine-jboss-transaction-api/src/main/resources",

3
build.third_step1.gradle

@ -44,7 +44,6 @@ sourceSets{
"${srcDir}/fine-hsqldb/src/main/java",
"${srcDir}/fine-iconloader/src/main/java",
"${srcDir}/fine-icu4j/src/main/java",
"${srcDir}/fine-j2v8/src/main/java",
// "${srcDir}/fine-jai/src/main/java",
"${srcDir}/fine-jboss-transaction-api/src/main/java",
"${srcDir}/fine-jgit/src/main/java",
@ -142,8 +141,6 @@ task copyFiles(type:Copy,dependsOn:'compileJava'){
with dataContent.call("${srcDir}/fine-hsqldb/src/main/resources")
with dataContent.call("${srcDir}/fine-icu4j/src/main/java")
with dataContent.call("${srcDir}/fine-icu4j/src/main/resources")
with dataContent.call("${srcDir}/fine-j2v8/src/main/java")
with dataContent.call("${srcDir}/fine-j2v8/src/main/resources")
// with dataContent.call("${srcDir}/fine-jai/src/main/java")
with dataContent.call("${srcDir}/fine-jboss-transaction-api/src/main/java")
with dataContent.call("${srcDir}/fine-jboss-transaction-api/src/main/resources")

6
fine-j2v8/.gitignore vendored

@ -1,6 +0,0 @@
*.iml
.idea/
.DS_Store
.project
.classpath
*.gradle

18
fine-j2v8/pom.xml

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.fr.third</groupId>
<artifactId>step1</artifactId>
<version>${revision}</version>
<relativePath>../base-third-project/base-third-step1</relativePath>
</parent>
<artifactId>fine-j2v8</artifactId>
<version>${revision}</version>
</project>

37
fine-j2v8/src/main/java/com/eclipsesource/v8/JavaCallback.java

@ -1,37 +0,0 @@
/*******************************************************************************
* Copyright (c) 2014 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8;
/**
* Classes that implement this interface provide a method
* which can be invoked from JavaScript. The method can return
* a result.
*
* After creating an instance of a class that implements this
* interface it can be registered as a Callback on a V8Object.
*/
public interface JavaCallback {
/**
* Called when a JS Function invokes a the registered Java
* method.
*
* @param receiver The V8Object that the function was called on.
* @param parameters The parameters passed to the JS Function. The
* parameter array does not need to be released, by any objects accessed
* from the array must be.
*
* @return A result that should be passed back to JavaScript. The
* result must be either an Integer, Double, Boolean, String or V8Value.
*/
public Object invoke(V8Object receiver, V8Array parameters);
}

33
fine-j2v8/src/main/java/com/eclipsesource/v8/JavaVoidCallback.java

@ -1,33 +0,0 @@
/*******************************************************************************
* Copyright (c) 2014 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8;
/**
* Classes that implement this interface provide a method
* which can be invoked from JavaScript.
*
* After creating an instance of a class that implements this
* interface it can be registered as a Callback on a V8Object.
*/
public interface JavaVoidCallback {
/**
* Called when a JS Function invokes a the registered Java
* method.
*
* @param receiver The V8Object that the function was called on.
* @param parameters The parameters passed to the JS Function. The
* parameter array does not need to be released, by any objects accessed
* from the array must be.
*/
public void invoke(V8Object receiver, V8Array parameters);
}

243
fine-j2v8/src/main/java/com/eclipsesource/v8/LibraryLoader.java

@ -1,243 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
* Wolfgang Steiner - code separation PlatformDetector/LibraryLoader
******************************************************************************/
package com.eclipsesource.v8;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
class LibraryLoader {
static final String SEPARATOR;
static final String DELIMITER;
static final String SWT_LIB_DIR = ".j2v8";
static final String MINIMUM_VERSION = "6.2";
static {
DELIMITER = System.getProperty("line.separator"); //$NON-NLS-1$
SEPARATOR = System.getProperty("file.separator"); //$NON-NLS-1$
}
/**
* Returns the base-name for the native J2V8 library file.
* @param withLinuxVendor include/exclude the {vendor} part from the returned filename
* <p>NOTE: Vendors are only included for linux systems</p>
* @return The filename string has the following structure:
* <pre><code>{arch}-[vendor]-{operating_system}</pre></code>
*/
public static String computeLibraryShortName(boolean withLinuxVendor) {
String prefix = "j2v8";
String vendor = withLinuxVendor && PlatformDetector.OS.isLinux() ? PlatformDetector.Vendor.getName() : null;
String os = PlatformDetector.OS.getName();
String arch = PlatformDetector.Arch.getName();
final String separator = "-";
return
prefix +
(vendor != null ? separator + vendor : "") +
separator + os +
separator + arch;
}
public static String computeLibraryFullName(boolean withLinuxVendor) {
return "lib" + computeLibraryShortName(withLinuxVendor) + "." + PlatformDetector.OS.getLibFileExtension();
}
static boolean tryLoad(boolean withLinuxVendor, StringBuffer message) {
String libShortName = computeLibraryShortName(withLinuxVendor);
String libFullName = computeLibraryFullName(withLinuxVendor);
String ideLocation = System.getProperty("user.dir") + SEPARATOR + "jni" + SEPARATOR + libFullName;
/* Try loading library from java library path */
if (load(libFullName, message)) {
return true;
}
if (load(libShortName, message)) {
return true;
}
/* Try loading library from the IDE location */
if (new File(ideLocation).exists()) {
if (load(ideLocation, message)) {
return true;
}
}
return false;
}
static void loadLibrary(final String tempDirectory) {
if (PlatformDetector.OS.isAndroid()) {
System.loadLibrary("j2v8");
return;
}
StringBuffer message = new StringBuffer();
// try loading a vendor-specific library first
if (tryLoad(true, message))
return;
// if there is no vendor-specific library, just try to load the default OS library
if (tryLoad(false, message))
return;
String path = null;
if (tempDirectory != null) {
path = tempDirectory;
} else {
path = System.getProperty("java.io.tmpdir"); //$NON-NLS-1$
}
// try extracting a vendor-specific library first
if (extract(path, true, message))
return;
// if there is no vendor-specific library, just try to extract the default OS library
if (extract(path, false, message))
return;
/* Failed to find the library */
throw new UnsatisfiedLinkError("Could not load J2V8 library. Reasons: " + message.toString()); //$NON-NLS-1$
}
static boolean load(final String libName, final StringBuffer message) {
try {
if (libName.indexOf(SEPARATOR) != -1) {
System.load(libName);
} else {
System.loadLibrary(libName);
}
return true;
} catch (UnsatisfiedLinkError e) {
if (message.length() == 0) {
message.append(DELIMITER);
}
message.append('\t');
message.append(e.getMessage());
message.append(DELIMITER);
}
return false;
}
static boolean extract(String libPath, boolean withLinuxVendor, StringBuffer message) {
String libFullName = computeLibraryFullName(withLinuxVendor);
return extract(libPath + SEPARATOR + libFullName, libFullName, message);
}
static boolean extract(final String fileName, final String mappedName, final StringBuffer message) {
FileOutputStream os = null;
InputStream is = null;
File file = new File(fileName);
//这部分自己修改过,主要是以为linux通过System.getProperty("java.io.tmpdir")获取到的是相对路径,但是System.load方法加载需要文件的绝对路径。
String absoluteName = file.getAbsolutePath();
boolean extracted = false;
try {
if (file.exists()) {
file.delete();
}
is = LibraryLoader.class.getResourceAsStream("/" + mappedName); //$NON-NLS-1$
if (is != null) {
extracted = true;
int read;
byte[] buffer = new byte[4096];
os = new FileOutputStream(fileName);
while ((read = is.read(buffer)) != -1) {
os.write(buffer, 0, read);
}
os.close();
is.close();
chmod("755", fileName);
if (load(absoluteName, message)) {
return true;
}
}
} catch (Throwable e) {
try {
if (os != null) {
os.close();
}
} catch (IOException e1) {
}
try {
if (is != null) {
is.close();
}
} catch (IOException e1) {
}
if (extracted && file.exists()) {
file.delete();
}
}
return false;
}
static void chmod(final String permision, final String path) {
if (PlatformDetector.OS.isWindows()) {
return;
}
try {
Runtime.getRuntime().exec(new String[] { "chmod", permision, path }).waitFor(); //$NON-NLS-1$
} catch (Throwable e) {
}
}
//内核版本windows NT6.2以下存在加载dll之后无法正常退出的问题,注册钩子函数退出时杀掉进程
static void checkExceptionVersion() {
String version = System.getProperty("os.version");
if (PlatformDetector.OS.isWindows() && belowMinimumVersion(version)) {
registerExit();
}
}
//低于指定版本,6.2以下
private static boolean belowMinimumVersion(String version) {
return compareVersion(version, MINIMUM_VERSION) < 0;
}
private static int compareVersion(String version1, String version2) {
String[] versionArray1 = version1.split("\\.");//注意此处为正则匹配,不能用".";
String[] versionArray2 = version2.split("\\.");
int idx = 0;
int minLength = Math.min(versionArray1.length, versionArray2.length);//取最小长度值
int diff = 0;
while (idx < minLength
&& (diff = versionArray1[idx].length() - versionArray2[idx].length()) == 0//先比较长度
&& (diff = versionArray1[idx].compareTo(versionArray2[idx])) == 0) {//再比较字符
++idx;
}
//如果已经分出大小,则直接返回,如果未分出大小,则再比较位数,有子版本的为大;
diff = (diff != 0) ? diff : versionArray1.length - versionArray2.length;
return diff;
}
//低于指定版本,6.2以下
private static void registerExit() {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
String name = ManagementFactory.getRuntimeMXBean().getName();
String pid = name.split("@")[0];
try {
Runtime.getRuntime().exec("taskkill /F /PID " + pid);
} catch (Exception ignore) {
}
}
});
}
}

239
fine-j2v8/src/main/java/com/eclipsesource/v8/NodeJS.java

@ -1,239 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
/**
* An isolate NodeJS runtime.
*
* This class is only available on some platforms. In particular any methods
* on this class, on an Android device, will lead to an UnsupportedOperationException.
*/
public class NodeJS {
private static final String TMP_JS_EXT = ".js.tmp";
private static final String NEXT_TICK = "nextTick";
private static final String PROCESS = "process";
private static final String GLOBAL = "global";
private static final String STARTUP_CALLBACK = "__run";
private static final String STARTUP_SCRIPT = "global." + STARTUP_CALLBACK + "(require, exports, module, __filename, __dirname);";
private static final String STARTUP_SCRIPT_NAME = "startup";
private static final String VERSIONS = "versions";
private static final String NODE = "node";
private String nodeVersion = null;
private V8 v8;
private V8Function require;
/**
* Creates a NodeJS Runtime
*
* @return The NodeJS runtime.
*
* May throw an UnsupportedOperationException if node.js integration has not
* been compiled for your platform.
*/
public static NodeJS createNodeJS() {
return createNodeJS(null);
}
/**
* Returns the version of Node.js that is runtime is built against.
* This uses process.versions.node to get the version.
*
* @return The version of Node.js.
*/
public String getNodeVersion() {
if (nodeVersion != null) {
return nodeVersion;
}
V8Object process = null;
V8Object versions = null;
try {
process = v8.getObject(PROCESS);
versions = process.getObject(VERSIONS);
nodeVersion = versions.getString(NODE);
} finally {
safeRelease(process);
safeRelease(versions);
}
return nodeVersion;
}
/**
* Creates a NodeJS runtime and executes a JS Script
*
* @param file The JavaScript to execute or null for no script.
* @return The NodeJS runtime.
*
* May throw an UnsupportedOperationException if node.js integration has not
* been compiled for your platform.
*/
public static NodeJS createNodeJS(final File file) {
V8 v8 = V8.createV8Runtime(GLOBAL);
final NodeJS node = new NodeJS(v8);
v8.registerJavaMethod(new JavaVoidCallback() {
@Override
public void invoke(final V8Object receiver, final V8Array parameters) {
V8Function require = (V8Function) parameters.get(0);
try {
node.init(require.twin());
} finally {
require.close();
}
}
}, STARTUP_CALLBACK);
try {
File startupScript = createTemporaryScriptFile(STARTUP_SCRIPT, STARTUP_SCRIPT_NAME);
try {
v8.createNodeRuntime(startupScript.getAbsolutePath());
} finally {
startupScript.delete();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
if (file != null) {
node.exec(file);
}
return node;
}
/**
* Returns the V8 runtime being used for this NodeJS instance.
*
* @return The V8 Runtime.
*/
public V8 getRuntime() {
return v8;
}
/**
* Handles the next message in the message loop. Returns True
* if there are more messages to handle, false otherwise.
*
* @return True if there are more messages to handle, false otherwise.
*/
public boolean handleMessage() {
v8.checkThread();
return v8.pumpMessageLoop();
}
/**
* Releases the NodeJS runtime.
*/
public void release() {
v8.checkThread();
if (!require.isReleased()) {
require.close();
}
if (!v8.isReleased()) {
v8.close();
}
}
/**
* Returns true if there are more messages to process, false otherwise.
*
* @return True if there are more messages to process, false otherwise.
*/
public boolean isRunning() {
v8.checkThread();
return v8.isRunning();
}
/**
* Invokes NodeJS require() on the specified file. This will load the module, execute
* it and return the exports object to the caller. The exports object must be released.
*
* @param file The module to load.
* @return The exports object.
*/
public V8Object require(final File file) {
v8.checkThread();
V8Array requireParams = new V8Array(v8);
try {
requireParams.push(file.getAbsolutePath());
return (V8Object) require.call(null, requireParams);
} finally {
requireParams.close();
}
}
/**
* Execute a NodeJS script. This will load the script and execute it on the
* next tick. This is the same as how NodeJS executes scripts at startup. Since
* the script won't actually run until the next tick, this method does not return
* a result.
*
* @param file The script to execute.
*/
public void exec(final File file) {
V8Function scriptExecution = createScriptExecutionCallback(file);
V8Object process = null;
V8Array parameters = null;
try {
process = v8.getObject(PROCESS);
parameters = new V8Array(v8);
parameters.push(scriptExecution);
process.executeObjectFunction(NEXT_TICK, parameters);
} finally {
safeRelease(process);
safeRelease(parameters);
safeRelease(scriptExecution);
}
}
private V8Function createScriptExecutionCallback(final File file) {
V8Function v8Function = new V8Function(v8, new JavaCallback() {
@Override
public Object invoke(final V8Object receiver, final V8Array parameters) {
V8Array requireParams = new V8Array(v8);
try {
requireParams.push(file.getAbsolutePath());
return require.call(null, requireParams);
} finally {
requireParams.close();
}
}
});
return v8Function;
}
private void safeRelease(final Releasable releasable) {
if (releasable != null) {
releasable.release();
}
}
private NodeJS(final V8 v8) {
this.v8 = v8;
}
private void init(final V8Function require) {
this.require = require;
}
private static File createTemporaryScriptFile(final String script, final String name) throws IOException {
File tempFile = File.createTempFile(name, TMP_JS_EXT);
PrintWriter writer = new PrintWriter(tempFile, "UTF-8");
try {
writer.print(script);
} finally {
writer.close();
}
return tempFile;
}
}

12
fine-j2v8/src/main/java/com/eclipsesource/v8/Platform.java

@ -1,12 +0,0 @@
package com.eclipsesource.v8;
public class Platform {
public static final String ANDROID = "android";
public static final String LINUX = "linux";
public static final String MACOSX = "macosx";
public static final String WINDOWS = "windows";
public static final String NATIVE_CLIENT = "nacl";
public static final String UNKNOWN = "unknown";
}

319
fine-j2v8/src/main/java/com/eclipsesource/v8/PlatformDetector.java

@ -1,319 +0,0 @@
/*******************************************************************************
* Copyright (c) 2017 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Trustin Lee - original OS/Arch/Vendor detection code (see: https://github.com/trustin/os-maven-plugin)
* Wolfgang Steiner - initial API and implementation
*
* Copyright 2014 Trustin Heuiseung Lee.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.eclipsesource.v8;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Locale;
public class PlatformDetector {
public static class Arch {
public static String getName() {
final String archProperty = System.getProperty("os.arch");
final String archName = normalizeArch(archProperty);
if (archName.equals(Platform.UNKNOWN)) {
throw new UnsatisfiedLinkError("Unsupported arch: " + archProperty);
}
return archName;
}
}
public static class OS {
public static String getName() {
final String osProperty = System.getProperty("os.name");
final String osName = normalizeOs(osProperty);
final String vendorProperty = System.getProperty("java.specification.vendor");
final String vendorName = normalize(vendorProperty);
// special handling for android
if (vendorName.contains("android") || osName.contains("android")) {
return Platform.ANDROID;
}
if (osName.equals(Platform.UNKNOWN)) {
throw new UnsatisfiedLinkError("Unsupported platform/vendor: " + osProperty + " / " + vendorProperty);
}
return osName;
}
public static boolean isWindows() {
return getName().equals(Platform.WINDOWS);
}
public static boolean isMac() {
return getName().equals(Platform.MACOSX);
}
public static boolean isLinux() {
return getName().equals(Platform.LINUX);
}
public static boolean isNativeClient() {
return getName().equals(Platform.NATIVE_CLIENT);
}
public static boolean isAndroid() {
return getName().equals(Platform.ANDROID);
}
public static String getLibFileExtension() {
if (isWindows()) {
return "dll";
}
if (isMac()) {
return "dylib";
}
if (isLinux()
|| isAndroid()
|| isNativeClient()) {
return "so";
}
throw new UnsatisfiedLinkError("Unsupported platform library-extension for: " + getName());
}
}
public static class Vendor {
private static final String[] LINUX_OS_RELEASE_FILES = {"/etc/os-release", "/usr/lib/os-release"};
private static final String REDHAT_RELEASE_FILE = "/etc/redhat-release";
private static final String LINUX_ID_PREFIX = "ID=";
public static String getName() {
if (OS.isWindows()) {
return "microsoft";
}
if (OS.isMac()) {
return "apple";
}
if (OS.isLinux()) {
return getLinuxOsReleaseId();
}
if (OS.isAndroid()) {
return "google";
}
//如果if条件全部不符合,就会陷入死循环,代码存在风险
//throw new UnsatisfiedLinkError("Unsupported vendor: " + getName());
return null;
}
private static String getLinuxOsReleaseId() {
// First, look for the os-release file.
for (String osReleaseFileName : LINUX_OS_RELEASE_FILES) {
File file = new File(osReleaseFileName);
if (file.exists()) {
return parseLinuxOsReleaseFile(file);
}
}
// Older versions of redhat don't have /etc/os-release. In this case, try
// parsing this file.
File file = new File(REDHAT_RELEASE_FILE);
if (file.exists()) {
return parseLinuxRedhatReleaseFile(file);
}
//linux系统下如果缺失/etc/os-release,/usr/lib/os-release,/etc/redhat-release三个文件,就会和getName方法就会一直互相调用
//throw new UnsatisfiedLinkError("Unsupported linux vendor: " + getName());
return null;
}
private static String parseLinuxOsReleaseFile(final File file) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "utf-8"));
String id = null;
String line;
while((line = reader.readLine()) != null) {
// Parse the ID line.
if (line.startsWith(LINUX_ID_PREFIX)) {
// Set the ID for this version.
id = normalizeOsReleaseValue(line.substring(LINUX_ID_PREFIX.length()));
break;
}
}
return id;
} catch (IOException ignored) {
// Just absorb. Don't treat failure to read /etc/os-release as an error.
} finally {
closeQuietly(reader);
}
return null;
}
private static String parseLinuxRedhatReleaseFile(final File file) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "utf-8"));
// There is only a single line in this file.
String line = reader.readLine();
if (line != null) {
line = line.toLowerCase(Locale.US);
String id;
if (line.contains("centos")) {
id = "centos";
} else if (line.contains("fedora")) {
id = "fedora";
} else if (line.contains("red hat enterprise linux")) {
id = "rhel";
} else {
// Other variants are not currently supported.
return null;
}
return id;
}
} catch (IOException ignored) {
// Just absorb. Don't treat failure to read /etc/os-release as an error.
} finally {
closeQuietly(reader);
}
return null;
}
private static void closeQuietly(final Closeable obj) {
try {
if (obj != null) {
obj.close();
}
} catch (IOException ignored) {
// Ignore.
}
}
}
private static String normalizeOsReleaseValue(final String value) {
// Remove any quotes from the string.
return value.trim().replace("\"", "");
}
private static String normalizeOs(String value) {
value = normalize(value);
if (value.startsWith("aix")) {
return "aix";
}
if (value.startsWith("hpux")) {
return "hpux";
}
if (value.startsWith("os400")) {
// Avoid the names such as os4000
if ((value.length() <= 5) || !Character.isDigit(value.charAt(5))) {
return "os400";
}
}
if (value.startsWith("android")) {
return Platform.ANDROID;
}
if (value.startsWith("linux")) {
return Platform.LINUX;
}
if (value.startsWith("nacl")) {
return Platform.NATIVE_CLIENT;
}
if (value.startsWith("macosx") || value.startsWith("osx")) {
return Platform.MACOSX;
}
if (value.startsWith("freebsd")) {
return "freebsd";
}
if (value.startsWith("openbsd")) {
return "openbsd";
}
if (value.startsWith("netbsd")) {
return "netbsd";
}
if (value.startsWith("solaris") || value.startsWith("sunos")) {
return "sunos";
}
if (value.startsWith("windows")) {
return Platform.WINDOWS;
}
return Platform.UNKNOWN;
}
private static String normalizeArch(String value) {
value = normalize(value);
if (value.matches("^(x8664|amd64|ia32e|em64t|x64)$")) {
return "x86_64";
}
if (value.matches("^(x8632|x86|i[3-6]86|ia32|x32)$")) {
return "x86_32";
}
if (value.matches("^(ia64|itanium64)$")) {
return "itanium_64";
}
if (value.matches("^(sparc|sparc32)$")) {
return "sparc_32";
}
if (value.matches("^(sparcv9|sparc64)$")) {
return "sparc_64";
}
if (value.matches("^(arm|arm32)$") || value.startsWith("armv7")) {
return "arm_32";
}
if ("aarch64".equals(value) || value.startsWith("armv8")) {
return "aarch_64";
}
if (value.matches("^(ppc|ppc32)$")) {
return "ppc_32";
}
if ("ppc64".equals(value)) {
return "ppc_64";
}
if ("ppc64le".equals(value)) {
return "ppcle_64";
}
if ("s390".equals(value)) {
return "s390_32";
}
if ("s390x".equals(value)) {
return "s390_64";
}
return Platform.UNKNOWN;
}
private static String normalize(final String value) {
if (value == null) {
return "";
}
return value.toLowerCase(Locale.US).replaceAll("[^a-z0-9]+", "");
}
}

34
fine-j2v8/src/main/java/com/eclipsesource/v8/ReferenceHandler.java

@ -1,34 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8;
/**
* Callback used to track when native handles are created and released.
*/
public interface ReferenceHandler {
/**
* Called when a native handle is first created. The V8Value
* referenced by that handle is passed as a parameter.
*
* @param object The V8Value referenced by the handle
*/
public void v8HandleCreated(V8Value object);
/**
* Called when a native handle is released. The V8Value
* referenced by that handle is passed as a parameter.
*
* @param object The V8Value referenced by the handle
*/
public void v8HandleDisposed(V8Value object);
}

30
fine-j2v8/src/main/java/com/eclipsesource/v8/Releasable.java

@ -1,30 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8;
import java.io.Closeable;
/**
* An interface used to denote all V8 Classes which can be released.
*/
public interface Releasable extends Closeable {
/**
* Release the underlying resources. Once an object is released
* it typically cannot be used again.
*/
void close();
/**
* Synonym for {@link #close()}.
*/
void release();
}

5
fine-j2v8/src/main/java/com/eclipsesource/v8/SignatureProvider.java

@ -1,5 +0,0 @@
package com.eclipsesource.v8;
public interface SignatureProvider {
public byte[] getSignature(String uri);
}

1687
fine-j2v8/src/main/java/com/eclipsesource/v8/V8.java

File diff suppressed because it is too large Load Diff

1189
fine-j2v8/src/main/java/com/eclipsesource/v8/V8Array.java

File diff suppressed because it is too large Load Diff

472
fine-j2v8/src/main/java/com/eclipsesource/v8/V8ArrayBuffer.java

@ -1,472 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/**
* V8ArrayBuffers represent ArrayBuffers from V8, but are backed by a
* java.nio.ByteBuffer. This means that any data stored in a TypedArray
* can be accessed by the java.nio.ByteBuffer. This significantly improves
* performance of data access from Java to JavaScript.
*
* V8ArrayBuffers can either be constructed in Java, or returned from
* JavaScript.
*
*/
public class V8ArrayBuffer extends V8Value {
ByteBuffer byteBuffer;
/**
* Creates a new V8ArrayBuffer on a given V8Runtime with a
* given capacity.
*
* @param v8 The runtime on which to create the ArrayBuffer
* @param capacity The capacity of the buffer
*/
public V8ArrayBuffer(final V8 v8, final int capacity) {
super(v8);
initialize(v8.getV8RuntimePtr(), capacity);
byteBuffer = v8.createV8ArrayBufferBackingStore(v8.getV8RuntimePtr(), objectHandle, capacity);
byteBuffer.order(ByteOrder.nativeOrder());
}
public V8ArrayBuffer(final V8 v8, ByteBuffer byteBuffer) {
super(v8);
if (byteBuffer == null) {
byteBuffer = ByteBuffer.allocateDirect(0);
}
if (!byteBuffer.isDirect()) {
throw new IllegalArgumentException("ByteBuffer must be a allocated as a direct ByteBuffer");
}
initialize(v8.getV8RuntimePtr(), byteBuffer);
this.byteBuffer = byteBuffer;
byteBuffer.order(ByteOrder.nativeOrder());
}
@Override
protected void initialize(final long runtimePtr, final Object data) {
v8.checkThread();
if (data instanceof ByteBuffer) {
ByteBuffer buffer = (ByteBuffer) data;
int capacity = buffer.limit();
objectHandle = v8.initNewV8ArrayBuffer(v8.getV8RuntimePtr(), buffer, capacity);
} else {
int capacity = (Integer) data;
objectHandle = v8.initNewV8ArrayBuffer(v8.getV8RuntimePtr(), capacity);
}
released = false;
addObjectReference(objectHandle);
}
@Override
protected V8Value createTwin() {
return new V8ArrayBuffer(v8, byteBuffer);
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#twin()
*/
@Override
public V8ArrayBuffer twin() {
v8.checkThread();
checkReleased();
return (V8ArrayBuffer) super.twin();
}
/**
* Returns the buffers limit
*
* @return the buffers limit
*/
public int limit() {
v8.checkThread();
checkReleased();
return byteBuffer.limit();
}
/**
* Returns the buffers capacity
*
* @return the buffers capacity
*/
public final int capacity() {
v8.checkThread();
checkReleased();
return byteBuffer.capacity();
}
/**
*
* @return
*/
public final int position() {
v8.checkThread();
checkReleased();
return byteBuffer.position();
}
public final V8ArrayBuffer position(final int newPosition) {
v8.checkThread();
checkReleased();
byteBuffer.position(newPosition);
return this;
}
public final V8ArrayBuffer limit(final int newLimit) {
v8.checkThread();
checkReleased();
byteBuffer.limit(newLimit);
return this;
}
public final V8ArrayBuffer mark() {
v8.checkThread();
checkReleased();
byteBuffer.mark();
return this;
}
public final V8ArrayBuffer reset() {
v8.checkThread();
checkReleased();
byteBuffer.reset();
return this;
}
public final V8ArrayBuffer clear() {
v8.checkThread();
checkReleased();
byteBuffer.clear();
return this;
}
public final V8ArrayBuffer flip() {
v8.checkThread();
checkReleased();
byteBuffer.flip();
return this;
}
public final V8ArrayBuffer rewind() {
v8.checkThread();
checkReleased();
byteBuffer.rewind();
return this;
}
public final int remaining() {
v8.checkThread();
checkReleased();
return byteBuffer.remaining();
}
public final boolean hasRemaining() {
v8.checkThread();
checkReleased();
return byteBuffer.hasRemaining();
}
public boolean isReadOnly() {
v8.checkThread();
checkReleased();
return byteBuffer.isReadOnly();
}
public byte get() {
v8.checkThread();
checkReleased();
return byteBuffer.get();
}
public V8ArrayBuffer put(final byte b) {
v8.checkThread();
checkReleased();
byteBuffer.put(b);
return this;
}
public byte get(final int index) {
v8.checkThread();
checkReleased();
return byteBuffer.get(index);
}
public V8ArrayBuffer put(final int index, final byte b) {
v8.checkThread();
checkReleased();
byteBuffer.put(index, b);
return this;
}
public V8ArrayBuffer get(final byte[] dst, final int offset, final int length) {
v8.checkThread();
checkReleased();
byteBuffer.get(dst, offset, length);
return this;
}
public V8ArrayBuffer get(final byte[] dst) {
v8.checkThread();
checkReleased();
byteBuffer.get(dst);
return this;
}
public V8ArrayBuffer put(final ByteBuffer src) {
v8.checkThread();
checkReleased();
byteBuffer.put(src);
return this;
}
public V8ArrayBuffer put(final byte[] src, final int offset, final int length) {
v8.checkThread();
checkReleased();
byteBuffer.put(src, offset, length);
return this;
}
public final V8ArrayBuffer put(final byte[] src) {
v8.checkThread();
checkReleased();
byteBuffer.put(src);
return this;
}
public final boolean hasArray() {
v8.checkThread();
checkReleased();
return byteBuffer.hasArray();
}
public final byte[] array() {
v8.checkThread();
checkReleased();
return byteBuffer.array();
}
public final int arrayOffset() {
v8.checkThread();
checkReleased();
return byteBuffer.arrayOffset();
}
public V8ArrayBuffer compact() {
v8.checkThread();
checkReleased();
byteBuffer.compact();
return this;
}
public boolean isDirect() {
v8.checkThread();
checkReleased();
return byteBuffer.isDirect();
}
public final ByteOrder order() {
v8.checkThread();
checkReleased();
return byteBuffer.order();
}
public final V8ArrayBuffer order(final ByteOrder bo) {
v8.checkThread();
checkReleased();
byteBuffer.order(bo);
return this;
}
public char getChar() {
v8.checkThread();
checkReleased();
return byteBuffer.getChar();
}
public V8ArrayBuffer putChar(final char value) {
v8.checkThread();
checkReleased();
byteBuffer.putChar(value);
return this;
}
public char getChar(final int index) {
v8.checkThread();
checkReleased();
return byteBuffer.getChar(index);
}
public V8ArrayBuffer putChar(final int index, final char value) {
v8.checkThread();
checkReleased();
byteBuffer.putChar(index, value);
return this;
}
public short getShort() {
v8.checkThread();
checkReleased();
return byteBuffer.getShort();
}
public V8ArrayBuffer putShort(final short value) {
v8.checkThread();
checkReleased();
byteBuffer.putShort(value);
return this;
}
public short getShort(final int index) {
v8.checkThread();
checkReleased();
return byteBuffer.getShort(index);
}
public V8ArrayBuffer putShort(final int index, final short value) {
v8.checkThread();
checkReleased();
byteBuffer.putShort(index, value);
return this;
}
public int getInt() {
v8.checkThread();
checkReleased();
return byteBuffer.getInt();
}
public V8ArrayBuffer putInt(final int value) {
v8.checkThread();
checkReleased();
byteBuffer.putInt(value);
return this;
}
public int getInt(final int index) {
v8.checkThread();
checkReleased();
return byteBuffer.getInt(index);
}
public V8ArrayBuffer putInt(final int index, final int value) {
v8.checkThread();
checkReleased();
byteBuffer.asIntBuffer().put(index, value);
return this;
}
public long getLong() {
v8.checkThread();
checkReleased();
return byteBuffer.getLong();
}
public V8ArrayBuffer putLong(final long value) {
v8.checkThread();
checkReleased();
byteBuffer.putLong(value);
return this;
}
public long getLong(final int index) {
v8.checkThread();
checkReleased();
return byteBuffer.getLong(index);
}
public V8ArrayBuffer putLong(final int index, final long value) {
v8.checkThread();
checkReleased();
byteBuffer.putLong(index, value);
return this;
}
public float getFloat() {
v8.checkThread();
checkReleased();
return byteBuffer.getFloat();
}
public V8ArrayBuffer putFloat(final float value) {
v8.checkThread();
checkReleased();
byteBuffer.putFloat(value);
return this;
}
public float getFloat(final int index) {
v8.checkThread();
checkReleased();
return byteBuffer.getFloat(index);
}
public V8ArrayBuffer putFloat(final int index, final float value) {
v8.checkThread();
checkReleased();
byteBuffer.putFloat(index, value);
return this;
}
public double getDouble() {
v8.checkThread();
checkReleased();
return byteBuffer.getDouble();
}
public V8ArrayBuffer putDouble(final double value) {
v8.checkThread();
checkReleased();
byteBuffer.putDouble(value);
return this;
}
public double getDouble(final int index) {
v8.checkThread();
checkReleased();
return byteBuffer.getDouble(index);
}
public V8ArrayBuffer putDouble(final int index, final double value) {
v8.checkThread();
checkReleased();
byteBuffer.putDouble(index, value);
return this;
}
public int floatLimit() {
v8.checkThread();
checkReleased();
return byteBuffer.asFloatBuffer().limit();
}
public int intLimit() {
v8.checkThread();
checkReleased();
return byteBuffer.asIntBuffer().limit();
}
public int shortLimit() {
v8.checkThread();
checkReleased();
return byteBuffer.asShortBuffer().limit();
}
public int doubleLimit() {
v8.checkThread();
checkReleased();
return byteBuffer.asDoubleBuffer().limit();
}
}

98
fine-j2v8/src/main/java/com/eclipsesource/v8/V8Function.java

@ -1,98 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8;
/**
* A V8Value that represents a JavaScript function.
* JavaScript functions cannot be created in Java, but
* can be returned as the result of invoking a JS script
* or JS Function.
*/
public class V8Function extends V8Object {
/**
* Create a JavaScript function, that when invoked will call
* the javaCallback passed to the receiver.
*
* @param v8 The v8 runtime on which to create this function
* @param javaCallback The callback to invoke
*/
public V8Function(final V8 v8, final JavaCallback javaCallback) {
super(v8, javaCallback);
}
protected V8Function(final V8 v8) {
this(v8, null);
}
@Override
protected V8Value createTwin() {
return new V8Function(v8);
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#toString()
*/
@Override
public String toString() {
if (released || v8.isReleased()) {
return "[Function released]";
}
return super.toString();
}
@Override
protected void initialize(final long runtimePtr, final Object data) {
if (data == null) {
super.initialize(runtimePtr, null);
return;
}
JavaCallback javaCallback = (JavaCallback) data;
long[] pointers = v8.initNewV8Function(runtimePtr);
// position 0 is the object reference, position 1 is the function reference
v8.createAndRegisterMethodDescriptor(javaCallback, pointers[1]);
released = false;
addObjectReference(pointers[0]);
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#twin()
*/
@Override
public V8Function twin() {
return (V8Function) super.twin();
}
/**
* Invoke the JavaScript function on the current runtime.
*
* @param receiver The object on which to call the function on. The
* receiver will be mapped to 'this' in JavaScript. If receiver is null
* or undefined, then the V8 runtime will be used instead.
* @param parameters The parameters passed to the JS Function.
*
* @return The result of JavaScript function.
*/
@SuppressWarnings("resource")
public Object call(V8Object receiver, final V8Array parameters) {
v8.checkThread();
checkReleased();
v8.checkRuntime(receiver);
v8.checkRuntime(parameters);
receiver = receiver != null ? receiver : v8;
long parametersHandle = parameters == null ? 0 : parameters.getHandle();
long receiverHandle = receiver.isUndefined() ? v8.getHandle() : receiver.getHandle();
return v8.executeFunction(v8.getV8RuntimePtr(), receiverHandle, objectHandle, parametersHandle);
}
}

113
fine-j2v8/src/main/java/com/eclipsesource/v8/V8Locker.java

@ -1,113 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8;
/**
* Represents a lock for a V8Runtime that can be moved between
* threads. When instantiated, the lock is automatically assigned
* to the current thread. If another thread wishes to acquire the
* lock, it must first be released.
*/
public class V8Locker {
private Thread thread = null;
private boolean released = false;
private V8 runtime;
V8Locker(final V8 runtime) {
this.runtime = runtime;
acquire();
}
/**
* Returns the current thread associated with locker.
*
* @return The currently locked thread.
*/
public Thread getThread() {
return thread;
}
/**
* Acquire the lock if it's currently not acquired by another
* thread. If it's currently held by another thread, an
* Error will be thrown.
*/
public synchronized void acquire() {
if ((thread != null) && (thread != Thread.currentThread())) {
throw new Error("Invalid V8 thread access: current thread is " + Thread.currentThread() + " while the locker has thread " + thread);
} else if ((thread == Thread.currentThread())) {
return;
}
runtime.acquireLock(runtime.getV8RuntimePtr());
thread = Thread.currentThread();
released = false;
}
/**
* Acquire the lock if it's currently not acquired by another
* thread. If it's currently held by another thread, tryAcquire
* will return false, otherwise true is returned.
*
* @return Returns true if the lock was acquired, false otherwise.
*/
public synchronized boolean tryAcquire() {
if ((thread != null) && (thread != Thread.currentThread())) {
return false;
} else if (thread == Thread.currentThread()) {
return true;
}
runtime.acquireLock(runtime.getV8RuntimePtr());
thread = Thread.currentThread();
released = false;
return true;
}
/**
* Release the lock if it's currently held by the calling thread.
* If the current thread does not hold the lock, and error will be
* thrown. If no thread holds the lock then nothing will happen.
*/
public synchronized void release() {
if ((released && (thread == null)) || runtime.isReleased()) {
return;
}
checkThread();
runtime.releaseLock(runtime.getV8RuntimePtr());
thread = null;
released = true;
}
/**
* Checks if the locker has access to the current thread.
* If the locker holds a different thread, than an Error
* is thrown.
*/
public void checkThread() {
if(released && (thread == null)){
throw new Error("Invalid V8 thread access: the locker has been released!");
}
if ((thread != Thread.currentThread())) {
throw new Error("Invalid V8 thread access: current thread is " + Thread.currentThread() + " while the locker has thread " + thread);
}
}
/**
* Check if the current thread holds this lock.
*
* @return Returns true if the current thread holds the lock,
* false otherwise.
*/
public boolean hasLock() {
return thread == Thread.currentThread();
}
}

1005
fine-j2v8/src/main/java/com/eclipsesource/v8/V8Object.java

File diff suppressed because it is too large Load Diff

17
fine-j2v8/src/main/java/com/eclipsesource/v8/V8OutOfMemoryError.java

@ -1,17 +0,0 @@
package com.eclipsesource.v8;
/**
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2020-11-26
*/
public class V8OutOfMemoryError extends V8RuntimeException {
V8OutOfMemoryError(final String message) {
super(message);
}
V8OutOfMemoryError() {
super();
}
}

32
fine-j2v8/src/main/java/com/eclipsesource/v8/V8ResultUndefined.java

@ -1,32 +0,0 @@
/*******************************************************************************
* Copyright (c) 2014 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8;
/**
* An exception that's used to indicate that method that should have returned a
* primitive, returned an Undefined instead.
*
* In Java, Undefined cannot be returned for all methods, especially if
* the method returns a primitive (int, double, boolean) or a String.
* In this case, if an Undefined should be returned from JS, then an instance
* of this exception is thrown.
*/
@SuppressWarnings("serial")
public class V8ResultUndefined extends V8RuntimeException {
V8ResultUndefined(final String message) {
super(message);
}
V8ResultUndefined() {
super();
}
}

27
fine-j2v8/src/main/java/com/eclipsesource/v8/V8RuntimeException.java

@ -1,27 +0,0 @@
/*******************************************************************************
* Copyright (c) 2014 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8;
/**
* A top-level exception used to indicate that a script failed. In most cases
* a more specific exception will be thrown.
*/
@SuppressWarnings("serial")
public class V8RuntimeException extends RuntimeException {
V8RuntimeException() {
}
V8RuntimeException(final String message) {
super(message);
}
}

24
fine-j2v8/src/main/java/com/eclipsesource/v8/V8ScriptCompilationException.java

@ -1,24 +0,0 @@
/*******************************************************************************
* Copyright (c) 2014 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8;
/**
* An exception used to indicate that a script failed to compile.
*/
@SuppressWarnings("serial")
public class V8ScriptCompilationException extends V8ScriptException {
V8ScriptCompilationException(final String fileName, final int lineNumber,
final String message, final String sourceLine, final int startColumn, final int endColumn) {
super(fileName, lineNumber, message, sourceLine, startColumn, endColumn, null, null);
}
}

165
fine-j2v8/src/main/java/com/eclipsesource/v8/V8ScriptException.java

@ -1,165 +0,0 @@
/*******************************************************************************
* Copyright (c) 2014 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8;
/**
* An exception that indicates that the execution of a script failed.
* Details about the exception, such as the line number, stack trace, and
* message can retrieved using the accessors.
*/
@SuppressWarnings("serial")
public abstract class V8ScriptException extends V8RuntimeException {
private final String fileName;
private final int lineNumber;
private final String jsMessage;
private final String sourceLine;
private final int startColumn;
private final int endColumn;
private final String jsStackTrace;
V8ScriptException(final String fileName,
final int lineNumber,
final String jsMessage,
final String sourceLine,
final int startColumn,
final int endColumn,
final String jsStackTrace,
final Throwable cause) {
this.fileName = fileName;
this.lineNumber = lineNumber;
this.jsMessage = jsMessage;
this.sourceLine = sourceLine;
this.startColumn = startColumn;
this.endColumn = endColumn;
this.jsStackTrace = jsStackTrace;
if (cause != null) {
initCause(cause);
}
}
/**
* Get the JavaScript Stack as a String.
*
* @return The JavaScript stack.
*/
public String getJSStackTrace() {
return jsStackTrace;
}
/**
* Get the file name contains the script that was currently executing.
*
* @return The file name that contains the script.
*/
public String getFileName() {
return fileName;
}
/**
* Get the line number that the failure occurred on.
*
* @return The line number the failure occurred on.
*/
public int getLineNumber() {
return lineNumber;
}
/**
* Get the JavaScript column where the error begins.
*
* @return The JavaScript column where the error begins.
*/
public int getStartColumn() {
return startColumn;
}
/**
* Get the JavaScript column where the error ends.
*
* @return The JavaScript column where the error ends.
*/
public int getEndColumn() {
return endColumn;
}
/**
* Get the JavaScript line of source that caused the error.
*
* @return The JavaScript line of source that caused the error.
*/
public String getSourceLine() {
return sourceLine;
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
result.append(createMessageLine());
result.append(createMessageDetails());
result.append(createJSStackDetails());
result.append("\n");
result.append(this.getClass().getName());
return result.toString();
}
/*
* (non-Javadoc)
* @see java.lang.Throwable#getMessage()
*/
@Override
public String getMessage() {
return createMessageLine();
}
/**
* Get the message set by the JavaScript exception.
*
* @return The message set by the JavaScript exception.
*/
public String getJSMessage() {
return jsMessage;
}
private String createMessageLine() {
return fileName + ":" + lineNumber + ": " + jsMessage;
}
private String createJSStackDetails() {
if (jsStackTrace != null) {
return "\n" + jsStackTrace;
}
return "";
}
private String createMessageDetails() {
StringBuilder result = new StringBuilder();
if ((sourceLine != null) && !sourceLine.isEmpty()) {
result.append('\n');
result.append(sourceLine);
result.append('\n');
if (startColumn >= 0) {
result.append(createCharSequence(startColumn, ' '));
result.append(createCharSequence(endColumn - startColumn, '^'));
}
}
return result.toString();
}
private char[] createCharSequence(final int length, final char c) {
char[] result = new char[length];
for (int i = 0; i < length; i++) {
result[i] = c;
}
return result;
}
}

40
fine-j2v8/src/main/java/com/eclipsesource/v8/V8ScriptExecutionException.java

@ -1,40 +0,0 @@
/*******************************************************************************
* Copyright (c) 2014 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8;
/**
* An exception used to indicate that a script failed to execute.
*/
@SuppressWarnings("serial")
public class V8ScriptExecutionException extends V8ScriptException {
V8ScriptExecutionException(final String fileName,
final int lineNumber,
final String message,
final String sourceLine,
final int startColumn,
final int endColumn,
final String jsStackTrace) {
this(fileName, lineNumber, message, sourceLine, startColumn, endColumn, jsStackTrace, null);
}
V8ScriptExecutionException(final String fileName,
final int lineNumber,
final String message,
final String sourceLine,
final int startColumn,
final int endColumn,
final String jsStackTrace,
final Throwable cause) {
super(fileName, lineNumber, message, sourceLine, startColumn, endColumn, jsStackTrace, cause);
}
}

183
fine-j2v8/src/main/java/com/eclipsesource/v8/V8TypedArray.java

@ -1,183 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8;
/**
* A representation of a JS TypedArray in Java. The typed array is simply a 'view' onto
* a back buffer.
*/
public class V8TypedArray extends V8Array {
/**
* Create a new TypedArray from a specified ArrayBuffer, type, offset and size. For
* example, a V8Int32Array is a typed array where each value is a 32-bit integer. The
* typed array is backed by the V8ArrayBuffer.
*
* @param v8 The V8Runtime on which to create this Int32Array
* @param type The type of Array to create. Currently Integer and Byte are supported.
* @param buffer The buffer used to back the typed array
* @param offset The offset into the buffer at which to start the the array
* @param size The size of the typed array
*/
public V8TypedArray(final V8 v8, final V8ArrayBuffer buffer, final int type, final int offset, final int size) {
super(v8, new V8ArrayData(buffer, offset, size, type));
}
private V8TypedArray(final V8 v8) {
super(v8);
}
@Override
protected V8Value createTwin() {
v8.checkThread();
checkReleased();
return new V8TypedArray(v8);
}
@Override
public Object get(final int index) {
v8.checkThread();
checkReleased();
int type = getType();
switch (type) {
case FLOAT_32_ARRAY:
return ((Number) super.get(index)).floatValue();
case FLOAT_64_ARRAY:
return super.get(index);
case INT_32_ARRAY:
return super.get(index);
case INT_16_ARRAY:
return ((Number) super.get(index)).shortValue();
case INT_8_ARRAY:
return ((Number) super.get(index)).byteValue();
case UNSIGNED_INT_16_ARRAY:
return 0xFFFF & (Integer) super.get(index);
case UNSIGNED_INT_32_ARRAY:
return 0x00000000FFFFFFFF & ((Number) super.get(index)).longValue();
case UNSIGNED_INT_8_CLAMPED_ARRAY:
return (short) (0x00FF & ((Number) super.get(index)).byteValue());
case UNSIGNED_INT_8_ARRAY:
return (short) (0x00FF & ((Number) super.get(index)).shortValue());
}
return null;
}
/**
* Provide access to the underlying ByteBuffer used for this TypedArray.
* The V8ArrayBuffer must be released.
*
* @return The V8ArrayBuffer used to back this TypedArray.
*/
public V8ArrayBuffer getBuffer() {
return (V8ArrayBuffer) get("buffer");
}
@Override
protected void initialize(final long runtimePtr, final Object data) {
v8.checkThread();
if (data == null) {
super.initialize(runtimePtr, data);
return;
}
V8ArrayData arrayData = (V8ArrayData) data;
checkArrayProperties(arrayData);
long handle = createTypedArray(runtimePtr, arrayData);
released = false;
addObjectReference(handle);
}
private long createTypedArray(final long runtimePtr, final V8ArrayData arrayData) {
switch (arrayData.type) {
case V8Value.FLOAT_32_ARRAY:
return v8.initNewV8Float32Array(runtimePtr, arrayData.buffer.objectHandle, arrayData.offset, arrayData.size);
case V8Value.FLOAT_64_ARRAY:
return v8.initNewV8Float64Array(runtimePtr, arrayData.buffer.objectHandle, arrayData.offset, arrayData.size);
case V8Value.UNSIGNED_INT_32_ARRAY:
return v8.initNewV8UInt32Array(runtimePtr, arrayData.buffer.objectHandle, arrayData.offset, arrayData.size);
case V8Value.INT_16_ARRAY:
return v8.initNewV8Int16Array(runtimePtr, arrayData.buffer.objectHandle, arrayData.offset, arrayData.size);
case V8Value.UNSIGNED_INT_16_ARRAY:
return v8.initNewV8UInt16Array(runtimePtr, arrayData.buffer.objectHandle, arrayData.offset, arrayData.size);
case V8Value.INTEGER:
return v8.initNewV8Int32Array(runtimePtr, arrayData.buffer.objectHandle, arrayData.offset, arrayData.size);
case V8Value.UNSIGNED_INT_8_ARRAY:
return v8.initNewV8UInt8Array(runtimePtr, arrayData.buffer.objectHandle, arrayData.offset, arrayData.size);
case V8Value.INT_8_ARRAY:
return v8.initNewV8Int8Array(runtimePtr, arrayData.buffer.objectHandle, arrayData.offset, arrayData.size);
case V8Value.UNSIGNED_INT_8_CLAMPED_ARRAY:
return v8.initNewV8UInt8ClampedArray(runtimePtr, arrayData.buffer.objectHandle, arrayData.offset, arrayData.size);
default:
throw new IllegalArgumentException("Cannot create a typed array of type " + V8Value.getStringRepresentation(arrayData.type));
}
}
/**
* Computes the size of the structures required for each TypedArray variation.
*
* @param type The type of the TypeArray
* @return The size of the structures required
*/
public static int getStructureSize(final int type) {
switch (type) {
case V8Value.FLOAT_64_ARRAY:
return 8;
case V8Value.INT_32_ARRAY:
case V8Value.UNSIGNED_INT_32_ARRAY:
case V8Value.FLOAT_32_ARRAY:
return 4;
case V8Value.UNSIGNED_INT_16_ARRAY:
case V8Value.INT_16_ARRAY:
return 2;
case V8Value.INT_8_ARRAY:
case V8Value.UNSIGNED_INT_8_ARRAY:
case V8Value.UNSIGNED_INT_8_CLAMPED_ARRAY:
return 1;
default:
throw new IllegalArgumentException("Cannot create a typed array of type " + V8Value.getStringRepresentation(type));
}
}
private void checkArrayProperties(final V8ArrayData arrayData) {
checkOffset(arrayData);
checkSize(arrayData);
}
private void checkSize(final V8ArrayData arrayData) {
if (arrayData.size < 0) {
throw new IllegalStateException("RangeError: Invalid typed array length");
}
int limit = (arrayData.size * getStructureSize(arrayData.type)) + arrayData.offset;
if (limit > arrayData.buffer.limit()) {
throw new IllegalStateException("RangeError: Invalid typed array length");
}
}
private void checkOffset(final V8ArrayData arrayData) {
if ((arrayData.offset % getStructureSize(arrayData.type)) != 0) {
throw new IllegalStateException("RangeError: Start offset of Int32Array must be a multiple of " + getStructureSize(arrayData.type));
}
}
private static class V8ArrayData {
private V8ArrayBuffer buffer;
private int offset;
private int size;
private int type;
public V8ArrayData(final V8ArrayBuffer buffer, final int offset, final int size, final int type) {
this.buffer = buffer;
this.offset = offset;
this.size = size;
this.type = type;
}
}
}

391
fine-j2v8/src/main/java/com/eclipsesource/v8/V8Value.java

@ -1,391 +0,0 @@
/*******************************************************************************
* Copyright (c) 2014 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8;
/**
* A base class for all V8 resources. V8 resources must
* be closed/released. The rules for releasing resources is as
* follows:
*
* 1. If you created it, you must close it, with one exception;
* if the object is being passed pack via a return statement,
* the system will release it for you.
*
* 2. If the system created it, you dont need to worry about it,
* with one caveat; if the object was returned to you as a
* result of a method call, you must close it.
*/
abstract public class V8Value implements Releasable {
public static final int NULL = 0;
public static final int UNKNOWN = 0;
public static final int INTEGER = 1;
public static final int INT_32_ARRAY = 1;
public static final int DOUBLE = 2;
public static final int FLOAT_64_ARRAY = 2;
public static final int BOOLEAN = 3;
public static final int STRING = 4;
public static final int V8_ARRAY = 5;
public static final int V8_OBJECT = 6;
public static final int V8_FUNCTION = 7;
public static final int V8_TYPED_ARRAY = 8;
public static final int BYTE = 9;
public static final int INT_8_ARRAY = 9;
public static final int V8_ARRAY_BUFFER = 10;
public static final int UNSIGNED_INT_8_ARRAY = 11;
public static final int UNSIGNED_INT_8_CLAMPED_ARRAY = 12;
public static final int INT_16_ARRAY = 13;
public static final int UNSIGNED_INT_16_ARRAY = 14;
public static final int UNSIGNED_INT_32_ARRAY = 15;
public static final int FLOAT_32_ARRAY = 16;
public static final int UNDEFINED = 99;
protected V8 v8;
protected long objectHandle;
protected boolean released = true;
protected V8Value() {
super();
}
protected V8Value(final V8 v8) {
if (v8 == null) {
this.v8 = (V8) this;
} else {
this.v8 = v8;
}
}
protected void initialize(final long runtimePtr, final Object data) {
long objectHandle = v8.initNewV8Object(runtimePtr);
released = false;
addObjectReference(objectHandle);
}
protected void addObjectReference(final long objectHandle) throws Error {
this.objectHandle = objectHandle;
try {
v8.addObjRef(this);
} catch (Error e) {
release();
throw e;
} catch (RuntimeException e) {
release();
throw e;
}
}
/**
* Returns a string representation of the V8 Type.
* @param type Type to return as a string. See constants in V8Value.
* @return The V8Value type as a string.
* @deprecated Use
*/
@Deprecated
public static String getStringRepresentaion(final int type) {
return getStringRepresentation(type);
}
/**
* Returns a string representation of the V8 Type.
* @param type Type to return as a string. See constants in V8Value.
* @return The V8Value type as a string.
*/
public static String getStringRepresentation(final int type) {
switch (type) {
case NULL:
return "Null";
case INTEGER:
return "Integer";
case DOUBLE:
return "Double";
case BOOLEAN:
return "Boolean";
case STRING:
return "String";
case V8_ARRAY:
return "V8Array";
case V8_OBJECT:
return "V8Object";
case V8_FUNCTION:
return "V8Function";
case V8_TYPED_ARRAY:
return "V8TypedArray";
case BYTE:
return "Byte";
case V8_ARRAY_BUFFER:
return "V8ArrayBuffer";
case UNSIGNED_INT_8_ARRAY:
return "UInt8Array";
case UNSIGNED_INT_8_CLAMPED_ARRAY:
return "UInt8ClampedArray";
case INT_16_ARRAY:
return "Int16Array";
case UNSIGNED_INT_16_ARRAY:
return "UInt16Array";
case UNSIGNED_INT_32_ARRAY:
return "UInt32Array";
case FLOAT_32_ARRAY:
return "Float32Array";
case UNDEFINED:
return "Undefined";
default:
throw new IllegalArgumentException("Invalid V8 type: " + type);
}
}
/**
* Returns a constructor name of the V8 Value.
*
* @return The V8Value constructor name as a string.
*/
public String getConstructorName() {
v8.checkThread();
v8.checkReleased();
return v8.getConstructorName(v8.getV8RuntimePtr(), objectHandle);
}
/**
* Determines if this value is undefined.
*
* @return Returns true if the value is undefined, false otherwise
*/
public boolean isUndefined() {
return false;
}
/**
* Gets the runtime this Value was created on.
*
* @return Returns the V8 runtime this value is associated with.
*/
public V8 getRuntime() {
return v8;
}
/**
* Returns the 'type' of this V8Value. The available types are defined
* as constants in {@link V8Value}. Only types that inherit from
* {@link V8Value} can be returned here.
*
* @return The 'type of this V8Value.
*/
public int getV8Type() {
if (isUndefined()) {
return UNDEFINED;
}
v8.checkThread();
v8.checkReleased();
return v8.getType(v8.getV8RuntimePtr(), objectHandle);
}
/**
* Creates a new Java object pointing at the same V8 Value
* as this. If the value is mutated (by adding new members or
* changing existing ones) then both the original and twin
* will be updated. Twins are .equal and .strict equals, but
* not == in Java.
*
* Twins must be closed separately since they have their own
* native resources.
*
* @return A new Java object pointing at the same V8 Value
* as this.
*/
public V8Value twin() {
if (isUndefined()) {
return this;
}
v8.checkThread();
v8.checkReleased();
V8Value twin = createTwin();
v8.createTwin(this, twin);
return twin;
}
/**
* Sets the V8Value as weak reference. A weak reference will eventually
* be closed when no more references exist to this object. Once setWeak
* is called, you should check if {@link V8Value#isReleased()} is true
* before invoking any methods on this object.
*
* If any other references exist to this object, the object will not be
* reclaimed. Even if no reference exist, V8 does not give any guarantee
* the object will be closed, so this should only be used if there is no
* other way to track object usage.
*
* @return The receiver.
*/
public V8Value setWeak() {
v8.checkThread();
v8.checkReleased();
v8.v8WeakReferences.put(getHandle(), this);
v8.setWeak(v8.getV8RuntimePtr(), getHandle());
return this;
}
/**
* Clears any weak reference set on this V8Value and makes this a strong
* reference. Strong references will not be garbage collected and this
* Object must be explicitly released.
*
* Calling clearWeak does nothing if the object is not currently set
* to weak.
*
* @return The receiver.
*/
public V8Value clearWeak() {
v8.checkThread();
v8.checkReleased();
v8.v8WeakReferences.remove(getHandle());
v8.clearWeak(v8.getV8RuntimePtr(), getHandle());
return this;
}
/**
* If {@link V8Value#setWeak()} has been called on this Object, this method
* will return true. Otherwise it will return false.
*
* @return Returns true if this object has been set 'Weak', return false otherwise.
*/
public boolean isWeak() {
v8.checkThread();
v8.checkReleased();
return v8.isWeak(v8.getV8RuntimePtr(), getHandle());
}
/*
* (non-Javadoc)
* @see java.io.Closeable#close()
*/
@Override
public void close() {
v8.checkThread();
if (!released) {
try {
v8.releaseObjRef(this);
} finally {
released = true;
v8.release(v8.getV8RuntimePtr(), objectHandle);
}
}
}
/**
* Releases the native resources associated with this V8Value.
*
* @deprecated use close() instead.
*/
@Override
@Deprecated
public void release() {
close();
}
/**
* Determine if the native resources have been released. Once released
* a V8 Value can no longer be used.
*
* @return Returns true if this object has been released, false otherwise.
*/
public boolean isReleased() {
return released;
}
/**
* Performs a JS === on the parameter and the receiver.
*
* @param that The Object to compare this object against.
* @return Returns true iff this === that
*/
public boolean strictEquals(final Object that) {
v8.checkThread();
checkReleased();
if (that == this) {
return true;
}
if (that == null) {
return false;
}
if (!(that instanceof V8Value)) {
return false;
}
if (isUndefined() && ((V8Value) that).isUndefined()) {
return true;
}
if (((V8Value) that).isUndefined()) {
return false;
}
return v8.strictEquals(v8.getV8RuntimePtr(), getHandle(), ((V8Value) that).getHandle());
}
protected long getHandle() {
checkReleased();
return objectHandle;
}
protected abstract V8Value createTwin();
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object that) {
return strictEquals(that);
}
/**
* Performs a JS == on the parameter and the receiver.
*
* @param that The Object to compare this object against.
* @return Returns true iff this == that
*/
public boolean jsEquals(final Object that) {
v8.checkThread();
checkReleased();
if (that == this) {
return true;
}
if (that == null) {
return false;
}
if (!(that instanceof V8Value)) {
return false;
}
if (isUndefined() && ((V8Value) that).isUndefined()) {
return true;
}
if (((V8Value) that).isUndefined()) {
return false;
}
return v8.equals(v8.getV8RuntimePtr(), getHandle(), ((V8Value) that).getHandle());
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
v8.checkThread();
checkReleased();
return v8.identityHash(v8.getV8RuntimePtr(), getHandle());
}
protected void checkReleased() {
if (released) {
throw new IllegalStateException("Object released");
}
}
}

55
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/BreakEvent.java

@ -1,55 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug;
import com.eclipsesource.v8.V8Object;
/**
* Holds information about break events.
*/
public class BreakEvent extends EventData {
private static final String SOURCE_LINE_TEXT = "sourceLineText";
private static final String SOURCE_COLUMN = "sourceColumn";
private static final String SOURCE_LINE = "sourceLine";
BreakEvent(final V8Object eventData) {
super(eventData);
}
/**
* Returns the source line that this break event occurred on.
*
* @return The line number that this break event occurred on.
*/
public int getSourceLine() {
return v8Object.executeIntegerFunction(SOURCE_LINE, null);
}
/**
* Returns the source column that this break event occurred on.
*
* @return The column number that this break event occurred on.
*/
public int getSourceColumn() {
return v8Object.executeIntegerFunction(SOURCE_COLUMN, null);
}
/**
* Returns the text of the line that this event occurred on.
*
* @return The text of the line that this event occurred on.
*/
public String getSourceLineText() {
return v8Object.executeStringFunction(SOURCE_LINE_TEXT, null);
}
}

20
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/BreakHandler.java

@ -1,20 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug;
import com.eclipsesource.v8.V8Object;
import com.eclipsesource.v8.debug.DebugHandler.DebugEvent;
public interface BreakHandler {
public void onBreak(DebugEvent type, ExecutionState state, EventData eventData, V8Object data);
}

24
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/CompileEvent.java

@ -1,24 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug;
import com.eclipsesource.v8.V8Object;
/**
* Holds information about Compile Events.
*/
public class CompileEvent extends EventData {
CompileEvent(final V8Object eventData) {
super(eventData);
}
}

363
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/DebugHandler.java

@ -1,363 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug;
import java.util.ArrayList;
import java.util.List;
import com.eclipsesource.v8.JavaVoidCallback;
import com.eclipsesource.v8.Releasable;
import com.eclipsesource.v8.V8;
import com.eclipsesource.v8.V8Array;
import com.eclipsesource.v8.V8Function;
import com.eclipsesource.v8.V8Object;
/**
* The entry point for the Debug API. The debug API is a Java API
* that exposes V8's JavaScript API.
*
* The API requires that V8 be initialized with the runtime flag
* '--expose-debug-as=__j2v8_debug_handler'.
*/
public class DebugHandler implements Releasable {
public static enum DebugEvent {
Undefined(0), Break(1), Exception(2), NewFunction(3), BeforeCompile(4), AfterCompile(5), CompileError(6), PromiseError(7), AsyncTaskEvent(8);
int index;
DebugEvent(final int index) {
this.index = index;
}
}
public static String DEBUG_OBJECT_NAME = "__j2v8_Debug";
private static final String DEBUG_BREAK_HANDLER = "__j2v8_debug_handler";
private static final String SET_SCRIPT_BREAK_POINT_BY_NAME = "setScriptBreakPointByName";
private static final String SET_BREAK_POINT = "setBreakPoint";
private static final String SET_LISTENER = "setListener";
private static final String V8_DEBUG_OBJECT = "Debug";
private static final String DISABLE_SCRIPT_BREAK_POINT = "disableScriptBreakPoint";
private static final String ENABLE_SCRIPT_BREAK_POINT = "enableScriptBreakPoint";
private static final String CLEAR_BREAK_POINT = "clearBreakPoint";
private static final String DISABLE_ALL_BREAK_POINTS = "disableAllBreakPoints";
private static final String SCRIPT_BREAK_POINTS = "scriptBreakPoints";
private static final String FIND_SCRIPT_BREAK_POINT = "findScriptBreakPoint";
private static final String NUMBER = "number";
private static final String CHANGE_BREAK_POINT_CONDITION = "changeBreakPointCondition";
private V8 runtime;
private V8Object debugObject;
private List<BreakHandler> breakHandlers = new ArrayList<BreakHandler>();
/**
* Creates the Debug Handler for a particular V8 runtime.
* Before the runtime was created, V8.setFlags("expose-debug-as=__j2v8_debug_handler");
* must be called.
*
* @param runtime The runtime on which to create the Debug Handler.
*/
public DebugHandler(final V8 runtime) {
this.runtime = runtime;
setupDebugObject(runtime);
setupBreakpointHandler();
}
/**
* Adds a handler to be notified when a breakpoint is hit.
*
* @param handler The handler to notify.
*/
public void addBreakHandler(final BreakHandler handler) {
runtime.getLocker().checkThread();
breakHandlers.add(handler);
}
/**
* Removes a handler from the list of breakpoint handlers.
* If the handler is not present in the list, the list is unchanged.
*
* @param handler The handler to remove.
*/
public void removeBreakHandler(final BreakHandler handler) {
runtime.getLocker().checkThread();
breakHandlers.remove(handler);
}
/**
* Registers a function breakpoint. When the JavaScript function
* is invoked, the breakpoint will be 'hit'.
*
* @param function The function on which to register the breakpoint.
* @return The berakpointID.
*/
public int setBreakpoint(final V8Function function) {
V8Array parameters = new V8Array(runtime);
parameters.push(function);
try {
return debugObject.executeIntegerFunction(SET_BREAK_POINT, parameters);
} finally {
parameters.close();
}
}
/**
* Registers a breakpoint given a scriptID and line number. The breakpoint
* will be 'hit' when the script is executed and the given line is reached.
*
* @param scriptID The ID of the script on which to set the breakpoint.
* @param lineNumber The line number on which to set the breakpoint.
* @return The berakpointID.
*/
public int setScriptBreakpoint(final String scriptID, final int lineNumber) {
V8Array parameters = new V8Array(runtime);
parameters.push(scriptID);
parameters.push(lineNumber);
try {
return debugObject.executeIntegerFunction(SET_SCRIPT_BREAK_POINT_BY_NAME, parameters);
} finally {
parameters.close();
}
}
/**
* Enables a breakpoint.
*
* @param breakpointID The breakpoint to enable.
*/
public void enableScriptBreakPoint(final int breakpointID) {
V8Array parameters = new V8Array(runtime);
parameters.push(breakpointID);
try {
debugObject.executeVoidFunction(ENABLE_SCRIPT_BREAK_POINT, parameters);
} finally {
parameters.close();
}
}
/**
* Disables a breakpoint.
*
* @param breakpointID The breakpoint to disable
*/
public void disableScriptBreakPoint(final int breakpointID) {
V8Array parameters = new V8Array(runtime);
parameters.push(breakpointID);
try {
debugObject.executeVoidFunction(DISABLE_SCRIPT_BREAK_POINT, parameters);
} finally {
parameters.close();
}
}
/**
* Removes a Breakpoint.
*
* @param breakpointID The ID of the breakpoint to remove.
*/
public void clearBreakPoint(final int breakpointID) {
V8Array parameters = new V8Array(runtime);
parameters.push(breakpointID);
try {
debugObject.executeVoidFunction(CLEAR_BREAK_POINT, parameters);
} finally {
parameters.close();
}
}
/**
* Disables all breakpoints.
*/
public void disableAllBreakPoints() {
debugObject.executeVoidFunction(DISABLE_ALL_BREAK_POINTS, null);
}
/**
* Returns a count of all the breakpoints
*
* @return A V8Array of Breakpoints.
*/
public int getScriptBreakPointCount() {
V8Array breakPoints = debugObject.executeArrayFunction(SCRIPT_BREAK_POINTS, null);
try {
return breakPoints.length();
} finally {
breakPoints.close();
}
}
/**
* Get all the BreakPoint IDs as an array.
*
* @return A list of BreakPoint IDs.
*/
public int[] getScriptBreakPointIDs() {
V8Array breakPoints = debugObject.executeArrayFunction(SCRIPT_BREAK_POINTS, null);
try {
int[] result = new int[breakPoints.length()];
for (int i = 0; i < breakPoints.length(); i++) {
V8Object breakPoint = breakPoints.getObject(i);
try {
result[i] = breakPoint.executeIntegerFunction(NUMBER, null);
} finally {
breakPoint.close();
}
}
return result;
} finally {
breakPoints.close();
}
}
/**
* Get the BreakPoint as referenced by the given ID.
*
* @param breakPointID The BreakPoint ID.
* @return The BreakPoint as referenced by the given ID.
*/
public ScriptBreakPoint getScriptBreakPoint(final int breakPointID) {
V8Array parameters = new V8Array(runtime);
parameters.push(breakPointID);
parameters.push(false);
V8Object scriptBreakPoint = null;
try {
scriptBreakPoint = debugObject.executeObjectFunction(FIND_SCRIPT_BREAK_POINT, parameters);
return new ScriptBreakPoint(scriptBreakPoint);
} finally {
parameters.close();
if (scriptBreakPoint != null) {
scriptBreakPoint.close();
}
}
}
/**
* Changes the current condition on the breakpoint as specified by the breakpoint ID
*
* @param breakpointID The ID of the breakpoint of which to change the condition on
* @param condition The new condition to set
*/
public void changeBreakPointCondition(final int breakpointID, final String condition) {
V8Array parameters = new V8Array(runtime);
parameters.push(breakpointID);
parameters.push(condition);
try {
debugObject.executeVoidFunction(CHANGE_BREAK_POINT_CONDITION, parameters);
} finally {
parameters.close();
}
}
/*
* (non-Javadoc)
* @see java.io.Closeable#close()
*/
@Override
public void close() {
debugObject.close();
}
@Override
@Deprecated
public void release() {
close();
}
private void setupDebugObject(final V8 runtime) {
V8Object outerDebug = runtime.getObject(DEBUG_OBJECT_NAME);
try {
debugObject = outerDebug.getObject(V8_DEBUG_OBJECT);
} finally {
outerDebug.close();
}
}
private void setupBreakpointHandler() {
BreakpointHandler handler = new BreakpointHandler();
debugObject.registerJavaMethod(handler, DEBUG_BREAK_HANDLER);
V8Function debugHandler = null;
V8Array parameters = null;
try {
debugHandler = (V8Function) debugObject.getObject(DEBUG_BREAK_HANDLER);
parameters = new V8Array(runtime);
parameters.push(debugHandler);
debugObject.executeFunction(SET_LISTENER, parameters);
} finally {
if ((debugHandler != null) && !debugHandler.isReleased()) {
debugHandler.close();
}
if ((parameters != null) && !parameters.isReleased()) {
parameters.close();
}
}
}
private class BreakpointHandler implements JavaVoidCallback {
@Override
public void invoke(final V8Object receiver, final V8Array parameters) {
if ((parameters == null) || parameters.isUndefined()) {
return;
}
int event = parameters.getInteger(0);
for (BreakHandler handler : breakHandlers) {
invokeHandler(parameters, event, handler);
}
}
private void invokeHandler(final V8Array parameters, final int event, final BreakHandler handler) {
V8Object execState = null;
V8Object eventData = null;
V8Object data = null;
ExecutionState state = null;
EventData typedEventData = null;
try {
execState = parameters.getObject(1);
eventData = parameters.getObject(2);
data = parameters.getObject(3);
state = new ExecutionState(execState);
DebugEvent type = DebugEvent.values()[event];
typedEventData = createDebugEvent(type, eventData);
handler.onBreak(type, state, typedEventData, data);
} finally {
safeRelease(execState);
safeRelease(eventData);
safeRelease(data);
safeRelease(state);
safeRelease(typedEventData);
}
}
private EventData createDebugEvent(final DebugEvent type, final V8Object eventData) {
switch (type) {
case Break:
return new BreakEvent(eventData);
case BeforeCompile:
return new CompileEvent(eventData);
case AfterCompile:
return new CompileEvent(eventData);
case Exception:
return new ExceptionEvent(eventData);
default:
break;
}
return new EventData(eventData);
}
private void safeRelease(final Releasable object) {
if ((object != null)) {
object.release();
}
}
}
}

40
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/EventData.java

@ -1,40 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug;
import com.eclipsesource.v8.Releasable;
import com.eclipsesource.v8.V8Object;
/**
* Typed information about different debug events.
*/
public class EventData implements Releasable {
protected V8Object v8Object;
EventData(final V8Object eventData) {
v8Object = eventData.twin();
}
@Override
public void close() {
if (!v8Object.isReleased()) {
v8Object.close();
}
}
@Override
@Deprecated
public void release() {
close();
}
}

24
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/ExceptionEvent.java

@ -1,24 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug;
import com.eclipsesource.v8.V8Object;
/**
* Holds information about Exception Events.
*/
public class ExceptionEvent extends EventData {
ExceptionEvent(final V8Object eventData) {
super(eventData);
}
}

100
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/ExecutionState.java

@ -1,100 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug;
import com.eclipsesource.v8.Releasable;
import com.eclipsesource.v8.V8Array;
import com.eclipsesource.v8.V8Object;
import com.eclipsesource.v8.debug.mirror.Frame;
/**
* Represents the current execution state at a break.
* The execution state provides methods for inspecting
* the stack, variables and scopes.
*
* The ExecutionState should not be persisted as it
* will be released when the debugger continues.
*
*/
public class ExecutionState implements Releasable {
private static final String FRAME = "frame";
private static final String PREPARE_STEP = "prepareStep";
private static final String FRAME_COUNT = "frameCount";
private V8Object v8Object;
ExecutionState(final V8Object v8Object) {
this.v8Object = v8Object.twin();
}
/**
* Returns the current stack frame count.
*
* @return The stack frame count.
*/
public int getFrameCount() {
return v8Object.executeIntegerFunction(FRAME_COUNT, null);
}
/**
* Indicates to the debugger how to proceed. If not called,
* the debugger will continue running until the next breakpoint
* is hit.
*
* @param action The step action to use.
*/
public void prepareStep(final StepAction action) {
V8Array parameters = new V8Array(v8Object.getRuntime());
parameters.push(action.index);
try {
v8Object.executeVoidFunction(PREPARE_STEP, parameters);
} finally {
parameters.close();
}
}
/**
* Returns the Frame at a given index
*
* @param index The stack index
* @return The stack frame at a given index
*/
public Frame getFrame(final int index) {
V8Array parameters = new V8Array(v8Object.getRuntime());
parameters.push(index);
V8Object frame = null;
try {
frame = v8Object.executeObjectFunction(FRAME, parameters);
return new Frame(frame);
} finally {
parameters.close();
if (frame != null) {
frame.close();
}
}
}
@Override
public void close() {
if ((v8Object != null) && !v8Object.isReleased()) {
v8Object.close();
v8Object = null;
}
}
@Override
@Deprecated
public void release() {
close();
}
}

94
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/ScriptBreakPoint.java

@ -1,94 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug;
import com.eclipsesource.v8.Releasable;
import com.eclipsesource.v8.V8Array;
import com.eclipsesource.v8.V8Object;
import com.eclipsesource.v8.V8ResultUndefined;
/**
* Represents a BreakPoint.
*/
public class ScriptBreakPoint implements Releasable {
private static final String CONDITION = "condition";
private static final String LINE = "line";
private static final String NUMBER = "number";
private static final String SET_CONDITION = "setCondition";
private V8Object v8Object;
ScriptBreakPoint(final V8Object v8Object) {
this.v8Object = v8Object.twin();
}
/**
* Returns the ID of this breakpoint.
*
* @return The ID (breakpoint number) of this breakpoint.
*/
public int getBreakPointNumber() {
return v8Object.executeIntegerFunction(NUMBER, null);
}
/**
* Returns the line number of this breakpoint.
*
* @return The line number of this breakpoint.
*/
public int getLine() {
return v8Object.executeIntegerFunction(LINE, null);
}
/**
* Sets a condition to be evaluated before determining if
* the breakpoint event should be fired.
*
* @param condition A JavaScript condition to be evaluated.
*/
public void setCondition(final String condition) {
V8Array parameters = new V8Array(v8Object.getRuntime());
parameters.push(condition);
try {
v8Object.executeVoidFunction(SET_CONDITION, parameters);
} finally {
parameters.close();
}
}
/**
* Returns the condition set on this breakpoint or the String
* 'undefined' if a condition was not set.
*
* @return The condition set on this breakpoint.
*/
public String getCondition() {
try {
return v8Object.executeStringFunction(CONDITION, null);
} catch (V8ResultUndefined e) {
return "undefined";
}
}
@Override
public void close() {
if ((v8Object != null) && !v8Object.isReleased()) {
v8Object.close();
v8Object = null;
}
}
@Override
public void release() {
close();
}
}

25
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/StepAction.java

@ -1,25 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug;
/**
* An enumeration of possible Step Actions. A step action indicates to the
* debugger how to proceed with the next step.
*/
public enum StepAction {
STEP_OUT(0), STEP_NEXT(1), STEP_IN(2), STEP_FRAME(3);
int index;
StepAction(final int index) {
this.index = index;
}
}

693
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/V8DebugServer.java

@ -1,693 +0,0 @@
/**
* Copyright 2016, Genuitec, LLC
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Genuitec LLC - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
import java.util.LinkedList;
import java.util.List;
import com.eclipsesource.v8.JavaVoidCallback;
import com.eclipsesource.v8.Releasable;
import com.eclipsesource.v8.V8;
import com.eclipsesource.v8.V8Array;
import com.eclipsesource.v8.V8Function;
import com.eclipsesource.v8.V8Object;
/**
* <p>V8DebugServer enables debuggers to connect to J2V8 via V8 server sockets debug protocol.
* Server has to be created in the same thread as the provided V8 runtime has been created (the V8 thread).
* You can specify port and whether the {@link #start()} method should
* block until a client connects. {@link #setTraceCommunication(boolean)} allows to output
* communication details for debugging purposes. Before creating V8 runtime you need to set V8 flag to expose
* debug object. If you do not intend to set other flags, than you can use {@link #configureV8ForDebugging()}
* method, otherwise set {@code -expose-debug-as=__j2v8_Debug} flag through {@link V8#setFlags(String)}.
*
* <p>Client connection is handled in a separate thread, however, commands are processed in the V8 thread.
* Therefore it is vital to provide an opportunity to process requests by calling
* {@link #processRequests(long)} method from the V8 thread. This will for instance
* allow to install breakpoints before the JavaScript code starts to execute. It is also good to call that
* method when V8 thread is idle to promptly provide responses to the debugger to avoid timeouts.
*
* <p>Example code:
*
* <code><br>
* &nbsp;&nbsp;//configure for debugging before creating runtime<br>
* &nbsp;&nbsp;V8DebugServer.configureV8ForDebugging();<br>
* <br>
* &nbsp;&nbsp;//create V8 runtime<br>
* &nbsp;&nbsp;V8 runtime = V8.createV8Runtime();<br>
* <br>
* &nbsp;&nbsp;//create and start debug server<br>
* &nbsp;&nbsp;int port = 0;<br>
* &nbsp;&nbsp;boolean waitForConnection = true;<br>
* &nbsp;&nbsp;server = new V8DebugServer(runtime, port, waitForConnection);<br>
* &nbsp;&nbsp;System.out.println("V8 Debug Server listening on port "<br>
* &nbsp;&nbsp;&nbsp;&nbsp;+ server.getPort());<br>
* &nbsp;&nbsp;server.start();<br>
* <br>
* &nbsp;&nbsp;//execute script and provide name for it<br>
* &nbsp;&nbsp;runtime.executeVoidScript("var i = 15", "myscript.js", 0);<br>
*
* </code>
*
* @author piotr@genuitec.com
*/
@SuppressWarnings("nls")
public class V8DebugServer {
/**
* Name under which internal V8 debug object is going to be exposed in the runtime.
* You can change the name if you are passing a different one through {@code -expose-debug-as}
* flag.
*/
public static String DEBUG_OBJECT_NAME = "__j2v8_Debug";
private static final String DEBUG_BREAK_HANDLER = "__j2v8_debug_handler";
private static final String MAKE_BREAK_EVENT = "__j2v8_MakeBreakEvent";
private static final String MAKE_COMPILE_EVENT = "__j2v8_MakeCompileEvent";
private static final String SET_LISTENER = "setListener";
private static final String V8_DEBUG_OBJECT = "Debug";
//Headers
private static final String HEADER_TYPE = "Type: ";
private static final String HEADER_V8_VERSION = "V8-Version: ";
private static final String HEADER_PROTOCOL_VERSION = "Protocol-Version: ";
private static final String HEADER_EMBEDDING_HOST = "Embedding-Host: ";
private static final String V8_VERSION = "4.10.253";
private static final String J2V8_VERSION = "4.0.0";
private static final String PROTOCOL_VERSION = "1";
//Protocol consts
private static final Charset PROTOCOL_CHARSET = Charset.forName("UTF-8");
private static final String PROTOCOL_EOL = "\r\n";
private static final byte[] PROTOCOL_EOL_BYTES = PROTOCOL_EOL.getBytes(PROTOCOL_CHARSET);
private static final String PROTOCOL_CONTENT_LENGTH_HEADER = "Content-Length:";
private static final byte[] PROTOCOL_CONTENT_LENGTH_BYTES = PROTOCOL_CONTENT_LENGTH_HEADER.getBytes(PROTOCOL_CHARSET);
private static final int PROTOCOL_BUFFER_SIZE = 4096;
/**
* Utility method for simplification of configuring V8 for debugging support.
*/
public static void configureV8ForDebugging() {
try {
V8.setFlags("-expose-debug-as=" + DEBUG_OBJECT_NAME);
} catch (Throwable t) {
t.printStackTrace();
}
}
private ServerSocket server;
private Socket client;
private Object clientLock = new Object();
private V8 runtime;
private V8Object debugObject;
private V8Object runningStateDcp;
private V8Object stoppedStateDcp;
private boolean waitForConnection;
private boolean traceCommunication = false;
private List<String> requests = new LinkedList<String>();
/**
* Creates V8DebugServer.
*
* @param runtime
* @param port
* @param waitForConnection
*/
public V8DebugServer(final V8 runtime, final int port, final boolean waitForConnection) {
this.runtime = runtime;
this.waitForConnection = waitForConnection;
V8Object debugScope = runtime.getObject(DEBUG_OBJECT_NAME);
if (debugScope == null) {
System.err.println("Cannot initialize debugger server - global debug object not found.");
return;
}
try {
debugObject = debugScope.getObject(V8_DEBUG_OBJECT);
} finally {
debugScope.close();
}
runtime.executeVoidScript("(function() {\n"
+ " " + DEBUG_OBJECT_NAME + ".Debug. " + MAKE_BREAK_EVENT + " = function (break_id,breakpoints_hit) {\n"
+ " return new " + DEBUG_OBJECT_NAME + ".BreakEvent(break_id,breakpoints_hit);\n"
+ " }\n"
+ " " + DEBUG_OBJECT_NAME + ".Debug. " + MAKE_COMPILE_EVENT + " = function(script,type) {\n"
+ " var scripts = " + DEBUG_OBJECT_NAME + ".Debug.scripts()\n"
+ " for (var i in scripts) {\n"
+ " if (scripts[i].id == script.id()) {\n"
+ " return new " + DEBUG_OBJECT_NAME + ".CompileEvent(scripts[i], type);\n"
+ " }\n"
+ " }\n"
+ " return {toJSONProtocol: function() {return ''}}\n"
+ " }\n"
+ "})()");
try {
server = new ServerSocket(port);
} catch (Exception e) {
logError(e);
}
}
/**
* Returns port on which server is listening or -1 if server failed to bound to a port.
* @return port or -1 if server failed to bound to a port
*/
public int getPort() {
return (server != null) && server.isBound() ? server.getLocalPort() : -1;
}
/**
* Output all communication to the console. For purpose of debugging V8DebugServer itself.
* @param value
*/
public void setTraceCommunication(final boolean value) {
traceCommunication = value;
}
/**
* Starts accepting client connections and blocks until a client connects
* if {@code waitForConnection} has been passed to V8DebugServer constructor.
*/
public void start() {
if (server == null) {
return;
}
boolean waitForConnection = this.waitForConnection;
Thread clientThread = new Thread(new ClientLoop(), "J2V8 Debugger Server");
clientThread.setDaemon(true);
clientThread.start();
setupEventHandler();
runningStateDcp = runtime.executeObjectScript("(function() {return new " + DEBUG_OBJECT_NAME + ".DebugCommandProcessor(null, true)})()");
if (waitForConnection) {
synchronized (clientLock) {
while (this.waitForConnection) {
try {
clientLock.wait();
} catch (InterruptedException e) {
//ignore
}
}
}
//Process initial requests
//Give 100ms for initial debugger connection setup
try {
processRequests(100);
} catch (InterruptedException e) {
//ignore
}
}
}
public void stop() {
try {
server.close();
synchronized (clientLock) {
if (client != null) {
client.close();
client = null;
}
}
} catch (IOException e) {
logError(e);
}
//release resources
if (runningStateDcp != null) {
runningStateDcp.close();
runningStateDcp = null;
}
if (debugObject != null) {
debugObject.close();
debugObject = null;
}
if (stoppedStateDcp != null) {
stoppedStateDcp.close();
stoppedStateDcp = null;
}
};
private void sendJson(String json) throws IOException {
json = json.replace("\\/", "/"); // Unescape slashes.
sendMessage("", json);
}
protected void logError(final Throwable t) {
t.printStackTrace();
}
private void sendMessage(final String header, final String contents) throws IOException {
synchronized (clientLock) {
if (!isConnected()) {
throw new IOException("There is no connected client.");
}
byte[] contentBytes = contents.getBytes(PROTOCOL_CHARSET);
StringBuilder sb = new StringBuilder();
//append custom headers
sb.append(header);
//append content length header
sb.append(PROTOCOL_CONTENT_LENGTH_HEADER);
sb.append(Integer.toString(contentBytes.length));
sb.append(PROTOCOL_EOL);
//skip tools info
sb.append(PROTOCOL_EOL);
//send headers to the client
client.getOutputStream().write(sb.toString().getBytes(
PROTOCOL_CHARSET));
//send contents to the client
if (contentBytes.length > 0) {
client.getOutputStream().write(contentBytes);
}
}
}
private boolean isConnected() {
synchronized (clientLock) {
return (server != null) && (client != null) && client.isConnected();
}
}
public void processRequests(final long timeout) throws InterruptedException {
if (server == null) {
return;
}
long start = System.currentTimeMillis();
do {
String[] reqs;
do {
synchronized (requests) {
reqs = requests.toArray(new String[requests.size()]);
requests.clear();
}
for (String req : reqs) {
try {
processRequest(req);
} catch (Exception e) {
logError(e);
}
}
} while (reqs.length > 0);
if (timeout > 0) {
Thread.sleep(10);
}
} while ((timeout > 0) && ((start + timeout) > System.currentTimeMillis()));
}
private void processRequest(final String message) throws IOException {
if (traceCommunication) {
System.out.println("Got message: \n" + message.substring(0, Math.min(message.length(), 1000)));
}
V8Array params = new V8Array(runtime);
params.push(message);
@SuppressWarnings("resource")
V8Object dcp = stoppedStateDcp != null ? stoppedStateDcp : runningStateDcp;
Object result = dcp.executeFunction("processDebugJSONRequest", params);
String json = result.toString();
if ((stoppedStateDcp == null) && json.contains("\"running\":false")) {
//XXX Need to implement functionality by adding to V8 class
// breakpoints before initial script or function execution
json = json.replace("\"running\":false", "\"running\":true")
.replace("\"success\":true", "\"success\":false")
.replace("{\"", "{\"message\":\"Client requested suspension is not supported on J2V8.\",\"");
dcp.add("running_", true);
}
if (traceCommunication) {
System.out.println("Returning response: \n" + json.substring(0, Math.min(json.length(), 1000)));
}
sendJson(json);
}
private void setupEventHandler() {
EventHandler handler = new EventHandler();
debugObject.registerJavaMethod(handler, DEBUG_BREAK_HANDLER);
V8Function debugHandler = null;
V8Array parameters = null;
try {
debugHandler = (V8Function) debugObject.getObject(DEBUG_BREAK_HANDLER);
parameters = new V8Array(runtime);
parameters.push(debugHandler);
debugObject.executeFunction(SET_LISTENER, parameters);
} finally {
if ((debugHandler != null) && !debugHandler.isReleased()) {
debugHandler.close();
}
if ((parameters != null) && !parameters.isReleased()) {
parameters.close();
}
}
}
private void enterBreakLoop(final V8Object execState, final V8Object eventData) throws IOException {
try {
V8Array params = new V8Array(runtime);
try {
params.push(false);
stoppedStateDcp = execState.executeObjectFunction("debugCommandProcessor", params);
} finally {
params.close();
}
//send event to debugger
int breakId = execState.getInteger("break_id");
V8Array breakpointsHit = eventData.getArray("break_points_hit_");
V8Object event = null;
params = new V8Array(runtime);
try {
params.push(breakId);
params.push(breakpointsHit);
event = debugObject.executeObjectFunction(MAKE_BREAK_EVENT, params);
String json = event.executeStringFunction("toJSONProtocol", null);
if (traceCommunication) {
System.out.println("Sending event (Break):\n" + json);
}
sendJson(json);
} finally {
params.close();
breakpointsHit.close();
if (event != null) {
event.close();
}
}
//process requests until one of the resumes execution
while (isConnected() && !stoppedStateDcp.executeBooleanFunction("isRunning", null)) {
try {
processRequests(10);
} catch (InterruptedException e) {
//ignore
}
}
} finally {
stoppedStateDcp.close();
stoppedStateDcp = null;
}
}
private void sendCompileEvent(final V8Object eventData) throws IOException {
if (!isConnected()) {
return;
}
//send event to debugger
int type = eventData.getInteger("type_");
V8Object script = eventData.getObject("script_");
V8Object event = null;
V8Array params = new V8Array(runtime);
try {
params.push(script);
params.push(type);
event = debugObject.executeObjectFunction(MAKE_COMPILE_EVENT, params);
String json = event.executeStringFunction("toJSONProtocol", null);
if (traceCommunication) {
System.out.println("Sending event (CompileEvent):\n" + json.substring(0, Math.min(json.length(), 1000)));
}
if (json.length() > 0) {
sendJson(json);
}
} finally {
params.close();
script.close();
if (event != null) {
event.close();
}
}
}
private class EventHandler implements JavaVoidCallback {
@Override
public void invoke(final V8Object receiver, final V8Array parameters) {
if ((parameters == null) || parameters.isUndefined()) {
return;
}
V8Object execState = null;
V8Object eventData = null;
try {
int event = parameters.getInteger(0);
execState = parameters.getObject(1);
eventData = parameters.getObject(2);
if (traceCommunication) {
String type = "unknown";
switch (event) {
case 1:
type = "Break";
break;
case 2:
type = "Exception";
break;
case 3:
type = "NewFunction";
break;
case 4:
type = "BeforeCompile";
break;
case 5:
type = "AfterCompile";
break;
case 6:
type = "CompileError";
break;
case 7:
type = "PromiseEvent";
break;
case 8:
type = "AsyncTaskEvent";
break;
}
System.out.println("V8 has emmitted an event of type " + type);
}
if (!isConnected()) {
return;
}
switch (event) {
case 1: //Break
enterBreakLoop(execState, eventData);
break;
case 5: //afterCompile
case 6: //compileError
sendCompileEvent(eventData);
break;
case 2: //exception
default:
}
} catch (Exception e) {
logError(e);
} finally {
safeRelease(execState);
safeRelease(eventData);
}
}
private void safeRelease(final Releasable object) {
if ((object != null)) {
object.release();
}
}
}
private class ClientLoop implements Runnable {
private int from;
@Override
public void run() {
while (true) {
try {
Socket socket = server.accept();
socket.setTcpNoDelay(true);
synchronized (clientLock) {
client = socket;
waitForConnection = false;
clientLock.notifyAll();
}
startHandshake();
processClientRequests();
} catch (Exception e) {
synchronized (clientLock) {
if (client != null) {
try {
client.close();
} catch (IOException ex) {
//ignore
}
client = null;
}
}
logError(e);
}
}
}
private void startHandshake() throws IOException {
StringBuilder sb = new StringBuilder();
sb.append(HEADER_V8_VERSION);
sb.append(V8_VERSION);
sb.append(PROTOCOL_EOL);
sb.append(HEADER_PROTOCOL_VERSION);
sb.append(PROTOCOL_VERSION);
sb.append(PROTOCOL_EOL);
sb.append(HEADER_EMBEDDING_HOST);
sb.append("j2v8 ");
sb.append(J2V8_VERSION);
sb.append(PROTOCOL_EOL);
sb.append(HEADER_TYPE);
sb.append("connect");
sb.append(PROTOCOL_EOL);
sendMessage(sb.toString(), "");
}
private void processClientRequests() throws IOException {
final byte[] EMPTY_ARR = new byte[] {};
byte[] buf = new byte[PROTOCOL_BUFFER_SIZE];
int bytesRead;
int offset = 0;
//Message data
boolean toolInfoSkipped = false;
byte[] messageBytes = EMPTY_ARR;
int contentLength = -1;
InputStream cIn;
synchronized (clientLock) {
cIn = client.getInputStream();
}
while ((bytesRead = cIn.read(buf, offset, PROTOCOL_BUFFER_SIZE - offset)) > 0) {
bytesRead += offset;
from = 0;
do {
if (contentLength < 0) {
contentLength = readContentLength(buf, bytesRead);
if (contentLength < 0) {
break;
}
}
if (!toolInfoSkipped) {
toolInfoSkipped = skipToolInfo(buf, bytesRead);
if (!toolInfoSkipped) {
break;
}
}
int length = Math.min(contentLength - messageBytes.length, bytesRead - from);
messageBytes = join(messageBytes, buf, from, length);
from += length;
if (messageBytes.length == contentLength) {
String message = new String(messageBytes, PROTOCOL_CHARSET);
synchronized (requests) {
requests.add(message);
}
contentLength = -1;
toolInfoSkipped = false;
messageBytes = EMPTY_ARR;
}
} while (from < bytesRead);
if (from < bytesRead) {
System.arraycopy(buf, from, buf, 0, bytesRead - from);
offset = bytesRead - from;
} else {
offset = 0;
}
}
}
private int readContentLength(final byte[] bytes, final int to) throws IOException {
int pos = indexOf(PROTOCOL_CONTENT_LENGTH_BYTES, bytes, from, to);
if (pos < 0) {
return -1;
}
pos += PROTOCOL_CONTENT_LENGTH_BYTES.length;
int end = indexOf(PROTOCOL_EOL_BYTES, bytes, pos, to);
if (end < 0) {
return -1;
}
String str = new String(bytes, pos, end - pos, PROTOCOL_CHARSET);
int contentLength;
try {
contentLength = Integer.parseInt(str.trim());
} catch (Exception ex) {
throw new IOException("Invalid content length header: '" + str + "' in message" +
new String(bytes, PROTOCOL_CHARSET));
}
from = end + PROTOCOL_EOL_BYTES.length;
return contentLength;
}
private boolean skipToolInfo(final byte[] bytes, final int n) {
int end = indexOf(PROTOCOL_EOL_BYTES, bytes, from, n);
if (end < 0) {
return false;
}
from = end + PROTOCOL_EOL_BYTES.length;
return true;
}
private int indexOf(final byte[] pattern, final byte[] array, final int start, final int end) {
int len = pattern.length;
for (int i = start; i < end; i++) {
for (int j = 0; j <= len; j++) {
if (j == len) {
//pattern matches at i
return i;
}
if (((i + j) >= end) || (array[i + j] != pattern[j])) {
//pattern does not match at i
break;
}
}
}
return -1;
}
private byte[] join(final byte[] arr1, final byte[] arr2, final int startPos, final int length) {
byte[] res = new byte[arr1.length + length];
System.arraycopy(arr1, 0, res, 0, arr1.length);
System.arraycopy(arr2, startPos, res, arr1.length, length);
return res;
}
};
}

40
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/ArrayMirror.java

@ -1,40 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug.mirror;
import com.eclipsesource.v8.V8Object;
/**
* Represents 'Array' mirrors.
*/
public class ArrayMirror extends ObjectMirror {
private static final String LENGTH = "length";
ArrayMirror(final V8Object v8Object) {
super(v8Object);
}
@Override
public boolean isArray() {
return true;
}
/**
* Returns the length of the array pointed to by this Array Mirror
*
* @return The length of the array.
*/
public int length() {
return v8Object.executeIntegerFunction(LENGTH, null);
}
}

33
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/BooleanMirror.java

@ -1,33 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug.mirror;
import com.eclipsesource.v8.V8Object;
/**
* Represents JavaScript 'Boolean' Mirrors
*/
public class BooleanMirror extends ValueMirror {
BooleanMirror(final V8Object v8Object) {
super(v8Object);
}
@Override
public boolean isBoolean() {
return true;
}
@Override
public String toString() {
return v8Object.executeStringFunction("toText", null);
}
}

225
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/Frame.java

@ -1,225 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug.mirror;
import com.eclipsesource.v8.V8Array;
import com.eclipsesource.v8.V8Object;
/**
* Represents a single stack frame accessible from the
* current execution state.
*/
public class Frame extends Mirror {
private static final String SOURCE_TEXT = "sourceText";
private static final String FUNC = "func";
private static final String COLUMN = "column";
private static final String LINE = "line";
private static final String POSITION = "position";
private static final String NAME = "name";
private static final String SCRIPT = "script";
private static final String SCOPE = "scope";
private static final String ARGUMENT_VALUE = "argumentValue";
private static final String ARGUMENT_NAME = "argumentName";
private static final String LOCAL_COUNT = "localCount";
private static final String ARGUMENT_COUNT = "argumentCount";
private static final String SCOPE_COUNT = "scopeCount";
private static final String LOCAL_NAME = "localName";
private static final String LOCAL_VALUE = "localValue";
private static final String SOURCE_LOCATION = "sourceLocation";
public Frame(final V8Object v8Object) {
super(v8Object);
}
/**
* Returns the number of accessible scopes from this stack frame.
*
* @return The number of accessible scopes
*/
public int getScopeCount() {
return v8Object.executeIntegerFunction(SCOPE_COUNT, null);
}
/**
* Returns the SourceLocation of this Frame.
*
* @return The SourceLocation of this Frame.
*/
public SourceLocation getSourceLocation() {
V8Object sourceLocation = v8Object.executeObjectFunction(SOURCE_LOCATION, null);
FunctionMirror function = getFunction();
String functionScriptName = function.getScriptName();
try {
String scriptName = null;
V8Object scriptObject = (V8Object) sourceLocation.get(SCRIPT);
if (scriptObject != null) {
scriptName = scriptObject.getString(NAME);
scriptObject.close();
}
if ((scriptName == null) && (functionScriptName != null)) {
scriptName = functionScriptName;
} else {
scriptName = "undefined";
}
return new SourceLocation(scriptName,
sourceLocation.getInteger(POSITION),
sourceLocation.getInteger(LINE),
sourceLocation.getInteger(COLUMN),
sourceLocation.getString(SOURCE_TEXT));
} finally {
function.close();
sourceLocation.close();
}
}
/**
* Returns the number of arguments to this frame.
*
* @return The number of arguments passed to this frame.
*/
public int getArgumentCount() {
return v8Object.executeIntegerFunction(ARGUMENT_COUNT, null);
}
/**
* Returns the name of the argument at the given index.
*
* @param index The index of the argument name to return.
* @return The name of argument at the given index.
*/
public String getArgumentName(final int index) {
V8Array parameters = new V8Array(v8Object.getRuntime());
parameters.push(index);
try {
return v8Object.executeStringFunction(ARGUMENT_NAME, parameters);
} finally {
parameters.close();
}
}
/**
* Returns the value of the argument at the given index.
*
* @param index The index of the argument value to return.
* @return The value of argument at the given index.
*/
public ValueMirror getArgumentValue(final int index) {
V8Array parameters = new V8Array(v8Object.getRuntime());
parameters.push(index);
V8Object result = null;
try {
result = v8Object.executeObjectFunction(ARGUMENT_VALUE, parameters);
if (!isValue(result)) {
throw new IllegalStateException("Argument value is not a ValueMirror");
}
return new ValueMirror(result);
} finally {
parameters.close();
if (result != null) {
result.close();
}
}
}
/**
* Returns the value of the local variable at the given index.
*
* @param index The index of the local to return.
* @return The value of local at the given index.
*/
public ValueMirror getLocalValue(final int index) {
V8Array parameters = new V8Array(v8Object.getRuntime());
parameters.push(index);
V8Object result = null;
try {
result = v8Object.executeObjectFunction(LOCAL_VALUE, parameters);
if (!isValue(result)) {
throw new IllegalStateException("Local value is not a ValueMirror");
}
return createMirror(result);
} finally {
parameters.close();
if (result != null) {
result.close();
}
}
}
/**
* Returns the number of local variables in this frame.
*
* @return The number of local variables accessible from this stack frame.
*/
public int getLocalCount() {
return v8Object.executeIntegerFunction(LOCAL_COUNT, null);
}
/**
* Returns the name of the local variable at the given index.
*
* @param index The index of the local variable name to return.
* @return The name of local variable at the given index.
*/
public String getLocalName(final int index) {
V8Array parameters = new V8Array(v8Object.getRuntime());
parameters.push(index);
try {
return v8Object.executeStringFunction(LOCAL_NAME, parameters);
} finally {
parameters.close();
}
}
/**
* Returns the scope at a given index.
*
* @param index The index
* @return The scope
*/
public Scope getScope(final int index) {
V8Array parameters = new V8Array(v8Object.getRuntime());
parameters.push(index);
V8Object scope = null;
try {
scope = v8Object.executeObjectFunction(SCOPE, parameters);
return new Scope(scope);
} finally {
parameters.close();
if (scope != null) {
scope.close();
}
}
}
/**
* Returns the Function associated with this particular debug frame.
*
* @return The Function for this debug frame.
*/
public FunctionMirror getFunction() {
V8Object function = null;
try {
function = v8Object.executeObjectFunction(FUNC, null);
return new FunctionMirror(function);
} finally {
if (function != null) {
function.close();
}
}
}
@Override
public boolean isFrame() {
return true;
}
}

56
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/FunctionMirror.java

@ -1,56 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug.mirror;
import com.eclipsesource.v8.V8Object;
/**
* Represents JavaScript 'Function' Mirrors
*/
public class FunctionMirror extends ObjectMirror {
private static final String NAME = "name";
private static final String SCRIPT = "script";
FunctionMirror(final V8Object v8Object) {
super(v8Object);
}
/**
* Returns the name of this Function.
*
* @return The name of this function
*/
public String getName() {
return v8Object.executeStringFunction(NAME, null);
}
/**
* Returns the name of the Script associated with
* this FunctionMirror.
*
* @return The name of the script.
*/
public String getScriptName() {
V8Object script = v8Object.executeObjectFunction(SCRIPT, null);
try {
return script.executeStringFunction(NAME, null);
} finally {
script.close();
}
}
@Override
public boolean isFunction() {
return true;
}
}

294
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/Mirror.java

@ -1,294 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug.mirror;
import com.eclipsesource.v8.Releasable;
import com.eclipsesource.v8.V8Object;
import com.eclipsesource.v8.V8ResultUndefined;
/**
* A mirror is used to represent a copy (mirror) of a runtime object
* during a debug session.
*
* Mirror hierarchy:
* - Mirror
* - ValueMirror
* - UndefinedMirror
* - NullMirror
* - NumberMirror
* - StringMirror
* - ObjectMirror
* - FunctionMirror
* - UnresolvedFunctionMirror
* - ArrayMirror
* - DateMirror
* - RegExpMirror
* - ErrorMirror
* - PromiseMirror
* - PropertyMirror
* - InternalPropertyMirror
* - FrameMirror
* - ScriptMirror
*/
public class Mirror implements Releasable {
private static final String IS_UNDEFINED = "isUndefined";
private static final String IS_NULL = "isNull";
private static final String IS_STRING = "isString";
private static final String IS_ARRAY = "isArray";
private static final String IS_FUNCTION = "isFunction";
private static final String IS_BOOLEAN = "isBoolean";
private static final String IS_NUMBER = "isNumber";
private static final String IS_OBJECT = "isObject";
private static final String IS_VALUE = "isValue";
protected V8Object v8Object;
Mirror(final V8Object v8Object) {
this.v8Object = v8Object.twin();
}
/**
* Returns true if this mirror object points to the type 'undefined'.
* False otherwise.
*
* @return True iff this mirror object points to an 'undefined' type.
*/
public boolean isUndefined() {
return v8Object.executeBooleanFunction(IS_UNDEFINED, null);
}
/**
* Returns true if this mirror object points to a 'value' type.
*
* @return True iff this mirror object points to a 'value' type.
*/
public boolean isValue() {
return false;
}
/**
* Returns true if this mirror object points to 'null'.
*
* @return True iff this mirror object points to a 'null'.
*/
public boolean isNull() {
return false;
}
/**
* Returns true if this mirror object points to a 'boolean' type.
*
* @return True iff this mirror object points to a 'boolean' type.
*/
public boolean isBoolean() {
return false;
}
/**
* Returns true if this mirror object points to a 'number' type.
*
* @return True iff this mirror object points to a 'number' type.
*/
public boolean isNumber() {
return false;
}
/**
* Returns true if this mirror object points to a 'String' type.
*
* @return True iff this mirror object points to a 'String' type.
*/
public boolean isString() {
return false;
}
/**
* Returns true if this mirror object points to an 'Object' type.
*
* @return True iff this mirror object points to an 'Object' type.
*/
public boolean isObject() {
return false;
}
/**
* Returns true if this mirror object points to a 'Function' type.
*
* @return True iff this mirror object points to a 'Function' type.
*/
public boolean isFunction() {
return false;
}
/**
* Returns true if this mirror object points to an 'Array' type.
*
* @return True iff this mirror object points to an 'Array' type.
*/
public boolean isArray() {
return false;
}
/**
* Returns true if this mirror object points to a 'Function' type.
*
* @return True iff this mirror object points to a 'Function' type.
*/
public boolean isFrame() {
return false;
}
/**
* Returns true if this mirror object points to a 'Property' type.
*
* @return True iff this mirror object points to a 'Property' type.
*/
public boolean isProperty() {
return false;
}
/*
* (non-Javadoc)
* @see java.io.Closeable#close()
*/
@Override
public void close() {
if ((v8Object != null) && !v8Object.isReleased()) {
v8Object.close();
v8Object = null;
}
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.Releasable#release()
*/
@Override
@Deprecated
public void release() {
close();
}
protected static boolean isValue(final V8Object mirror) {
try {
return mirror.executeBooleanFunction(IS_VALUE, null);
} catch (V8ResultUndefined e) {
return false;
}
}
private static boolean isObject(final V8Object mirror) {
try {
return mirror.executeBooleanFunction(IS_OBJECT, null);
} catch (V8ResultUndefined e) {
return false;
}
}
private static boolean isNumber(final V8Object mirror) {
try {
return mirror.executeBooleanFunction(IS_NUMBER, null);
} catch (V8ResultUndefined e) {
return false;
}
}
private static boolean isBoolean(final V8Object mirror) {
try {
return mirror.executeBooleanFunction(IS_BOOLEAN, null);
} catch (V8ResultUndefined e) {
return false;
}
}
private static boolean isFunction(final V8Object mirror) {
try {
return mirror.executeBooleanFunction(IS_FUNCTION, null);
} catch (V8ResultUndefined e) {
return false;
}
}
private static boolean isArray(final V8Object mirror) {
try {
return mirror.executeBooleanFunction(IS_ARRAY, null);
} catch (V8ResultUndefined e) {
return false;
}
}
private static boolean isString(final V8Object mirror) {
try {
return mirror.executeBooleanFunction(IS_STRING, null);
} catch (V8ResultUndefined e) {
return false;
}
}
private static boolean isUndefined(final V8Object mirror) {
try {
return mirror.executeBooleanFunction(IS_UNDEFINED, null);
} catch (V8ResultUndefined e) {
return false;
}
}
private static boolean isNull(final V8Object mirror) {
try {
return mirror.executeBooleanFunction(IS_NULL, null);
} catch (V8ResultUndefined e) {
return false;
}
}
protected static ValueMirror createMirror(final V8Object mirror) {
if (isNull(mirror)) {
return new NullMirror(mirror);
} else if (isUndefined(mirror)) {
return new UndefinedMirror(mirror);
} else if (isFunction(mirror)) {
return new FunctionMirror(mirror);
} else if (isArray(mirror)) {
return new ArrayMirror(mirror);
} else if (isObject(mirror)) {
return new ObjectMirror(mirror);
} else if (isString(mirror)) {
return new StringMirror(mirror);
} else if (isNumber(mirror)) {
return new NumberMirror(mirror);
} else if (isBoolean(mirror)) {
return new BooleanMirror(mirror);
}
return new ValueMirror(mirror);
}
@Override
public String toString() {
return v8Object.toString();
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof Mirror)) {
return false;
}
return v8Object.equals(((Mirror) obj).v8Object);
}
@Override
public int hashCode() {
return v8Object.hashCode();
}
}

35
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/NullMirror.java

@ -1,35 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug.mirror;
import com.eclipsesource.v8.V8Object;
/**
* Represents 'Null' Mirrors
*/
public class NullMirror extends ValueMirror {
NullMirror(final V8Object v8Object) {
super(v8Object);
}
@Override
public boolean isNull() {
return true;
}
@Override
public String toString() {
return "null";
}
}

34
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/NumberMirror.java

@ -1,34 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug.mirror;
import com.eclipsesource.v8.V8Object;
/**
* Represents JavaScript 'Number' Mirrors
*/
public class NumberMirror extends ValueMirror {
NumberMirror(final V8Object v8Object) {
super(v8Object);
}
@Override
public boolean isNumber() {
return true;
}
@Override
public String toString() {
return v8Object.executeStringFunction("toText", null);
}
}

98
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/ObjectMirror.java

@ -1,98 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug.mirror;
import com.eclipsesource.v8.V8Array;
import com.eclipsesource.v8.V8Object;
/**
* Represents 'Object' mirrors.
*/
public class ObjectMirror extends ValueMirror {
private static final String PROPERTIES = "properties";
private static final String PROPERTY_NAMES = "propertyNames";
public enum PropertyKind {
Named(1), Indexed(2);
int index;
private PropertyKind(final int index) {
this.index = index;
}
}
@Override
public String toString() {
return v8Object.toString();
}
ObjectMirror(final V8Object v8Object) {
super(v8Object);
}
@Override
public boolean isObject() {
return true;
}
/**
* Returns all the property names for the given object.
*
* @param kind Indicate whether named, indexed or both kinds of properties are requested.
* @param limit Limit the number of properties returned to the specified value
* @return All the property names for a given object
*/
public String[] getPropertyNames(final PropertyKind kind, final int limit) {
V8Array parameters = new V8Array(v8Object.getRuntime());
parameters.push(kind.index);
parameters.push(limit);
V8Array propertyNames = null;
try {
propertyNames = v8Object.executeArrayFunction(PROPERTY_NAMES, parameters);
String[] result = new String[propertyNames.length()];
for (int i = 0; i < result.length; i++) {
result[i] = propertyNames.getString(i);
}
return result;
} finally {
parameters.close();
if (propertyNames != null) {
propertyNames.close();
}
}
}
/**
* Return the properties for this object as an array of PropertyMirror objects.
*
* @param kind Indicate whether named, indexed or both kinds of properties are requested
* @param limit Limit the number of properties returned to the specified value
* @return {Array} Property mirrors for this object
*/
public PropertiesArray getProperties(final PropertyKind kind, final int limit) {
V8Array parameters = new V8Array(v8Object.getRuntime());
parameters.push(kind.index);
parameters.push(limit);
V8Array result = null;
try {
result = v8Object.executeArrayFunction(PROPERTIES, parameters);
return new PropertiesArray(result);
} finally {
parameters.close();
if ((result != null) && !result.isReleased()) {
result.close();
result = null;
}
}
}
}

73
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/PropertiesArray.java

@ -1,73 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug.mirror;
import com.eclipsesource.v8.Releasable;
import com.eclipsesource.v8.V8Array;
import com.eclipsesource.v8.V8Object;
/**
* Provides typed access to a set of properties.
*/
public class PropertiesArray implements Releasable {
private V8Array v8Array;
PropertiesArray(final V8Array v8Object) {
v8Array = v8Object.twin();
}
/**
* Returns the PropertyMiror at a given index.
*
* @param index The index of the property
* @return The property at the given index
*/
public PropertyMirror getProperty(final int index) {
V8Object result = v8Array.getObject(index);
try {
return new PropertyMirror(result);
} finally {
result.close();
}
}
/*
* (non-Javadoc)
* @see java.io.Closeable#close()
*/
@Override
public void close() {
if (!v8Array.isReleased()) {
v8Array.close();
}
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.Releasable#release()
*/
@Override
@Deprecated
public void release() {
close();
}
/**
* Returns the number of properties contained in this array.
*
* @return The length of this array.
*/
public int length() {
return v8Array.length();
}
}

52
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/PropertyMirror.java

@ -1,52 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug.mirror;
import com.eclipsesource.v8.V8Object;
/**
* Represents JavaScript 'Property' Mirrors
*/
public class PropertyMirror extends Mirror {
PropertyMirror(final V8Object v8Object) {
super(v8Object);
}
/**
* Returns the name of this property.
*
* @return The name of this property.
*/
public String getName() {
return v8Object.executeStringFunction("name", null);
}
/**
* Returns the value of this property.
*
* @return The value of this property.
*/
public Mirror getValue() {
V8Object mirror = v8Object.executeObjectFunction("value", null);
try {
return createMirror(mirror);
} finally {
mirror.close();
}
}
@Override
public boolean isProperty() {
return true;
}
}

156
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/Scope.java

@ -1,156 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug.mirror;
import com.eclipsesource.v8.V8Array;
import com.eclipsesource.v8.V8Object;
import com.eclipsesource.v8.V8Value;
/**
* Represents a JavaScope scope accessible from the current stack frame
* during debug break.
*
*/
public class Scope extends Mirror {
private static final String SCOPE_OBJECT = "scopeObject";
private static final String SCOPE_TYPE = "scopeType";
private static final String SET_VARIABLE_VALUE = "setVariableValue";
/**
* Represents the different types of scopes available.
*/
public static enum ScopeType {
Global(0), Local(1), With(2), Closure(3), Catch(4), Block(5), Script(6);
int index;
private ScopeType(final int index) {
this.index = index;
}
}
Scope(final V8Object v8Object) {
super(v8Object);
}
/**
* Returns the type of this scope.
*
* @return The type of scope.
*/
public ScopeType getType() {
return ScopeType.values()[v8Object.executeIntegerFunction(SCOPE_TYPE, null)];
}
/**
* Sets the value of a variable in this scope.
*
* @param name The name of the variable
* @param value The value
*/
public void setVariableValue(final String name, final int value) {
V8Array parameters = new V8Array(v8Object.getRuntime());
parameters.push(name);
parameters.push(value);
try {
v8Object.executeVoidFunction(SET_VARIABLE_VALUE, parameters);
} finally {
parameters.close();
}
}
/**
* Sets the value of a variable in this scope.
*
* @param name The name of the variable
* @param value The value
*/
public void setVariableValue(final String name, final V8Value value) {
V8Array parameters = new V8Array(v8Object.getRuntime());
parameters.push(name);
parameters.push(value);
try {
v8Object.executeVoidFunction(SET_VARIABLE_VALUE, parameters);
} finally {
parameters.close();
}
}
/**
* Sets the value of a variable in this scope.
*
* @param name The name of the variable
* @param value The value
*/
public void setVariableValue(final String name, final boolean value) {
V8Array parameters = new V8Array(v8Object.getRuntime());
parameters.push(name);
parameters.push(value);
try {
v8Object.executeVoidFunction(SET_VARIABLE_VALUE, parameters);
} finally {
parameters.close();
}
}
/**
* Sets the value of a variable in this scope.
*
* @param name The name of the variable
* @param value The value
*/
public void setVariableValue(final String name, final String value) {
V8Array parameters = new V8Array(v8Object.getRuntime());
parameters.push(name);
parameters.push(value);
try {
v8Object.executeVoidFunction(SET_VARIABLE_VALUE, parameters);
} finally {
parameters.close();
}
}
/**
* Sets the value of a variable in this scope.
*
* @param name The name of the variable
* @param value The value
*/
public void setVariableValue(final String name, final double value) {
V8Array parameters = new V8Array(v8Object.getRuntime());
parameters.push(name);
parameters.push(value);
try {
v8Object.executeVoidFunction(SET_VARIABLE_VALUE, parameters);
} finally {
parameters.close();
}
}
/**
* Returns the underlying V8Object that represents this scope.
*
* @return The underlying V8Object that represents this scope.
*/
public ObjectMirror getScopeObject() {
V8Object mirror = null;
try {
mirror = v8Object.executeObjectFunction(SCOPE_OBJECT, null);
return (ObjectMirror) createMirror(mirror);
} finally {
if ( mirror != null ) {
mirror.close();
}
}
}
}

84
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/SourceLocation.java

@ -1,84 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug.mirror;
/**
* Represents a JS Script location.
*/
public class SourceLocation {
private final String scriptName;
private final int position;
private final int line;
private final int column;
private String sourceText;
/**
* Represents a JS Script Source Location
* @param scriptName The name of the script
* @param position The position in the script
* @param line The line number
* @param column The column number
* @param sourceText The sourceCode at this location
*/
public SourceLocation(final String scriptName, final int position, final int line, final int column, final String sourceText) {
this.scriptName = scriptName;
this.position = position;
this.line = line;
this.column = column;
this.sourceText = sourceText;
}
@Override
public String toString() {
return scriptName + " : " + position + " : " + line + " : " + column + " : " + sourceText;
}
/**
* Returns the name of the script for this SourceLocation.
* @return The name of the script
*/
public String getScriptName() {
return scriptName;
}
/**
* Returns the position of this SourceLocation.
* @return The position of this SourceLocation.
*/
public int getPosition() {
return position;
}
/**
* Returns the line number of this SourceLocation.
* @return The line number of this SourceLocation.
*/
public int getLine() {
return line;
}
/**
* Returns the column number of this SourceLocation.
* @return The column number of this SourceLocation.
*/
public int getColumn() {
return column;
}
/**
* Returns the source text for this SourceLocation.
* @return The source text for this SourceLocation.
*/
public String getSourceText() {
return sourceText;
}
}

34
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/StringMirror.java

@ -1,34 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug.mirror;
import com.eclipsesource.v8.V8Object;
/**
* Represents JavaScript 'String' Mirrors
*/
public class StringMirror extends ValueMirror {
StringMirror(final V8Object v8Object) {
super(v8Object);
}
@Override
public boolean isString() {
return true;
}
@Override
public String toString() {
return v8Object.executeStringFunction("toText", null);
}
}

35
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/UndefinedMirror.java

@ -1,35 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug.mirror;
import com.eclipsesource.v8.V8Object;
/**
* Represents 'Undefined' Mirrors
*/
public class UndefinedMirror extends ValueMirror {
UndefinedMirror(final V8Object v8Object) {
super(v8Object);
}
@Override
public boolean isUndefined() {
return true;
}
@Override
public String toString() {
return "undefined";
}
}

40
fine-j2v8/src/main/java/com/eclipsesource/v8/debug/mirror/ValueMirror.java

@ -1,40 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.debug.mirror;
import com.eclipsesource.v8.V8Object;
/**
* Represents 'Value' Mirrors (Objects, Numbers, Strings, ...).
*/
public class ValueMirror extends Mirror {
private static final String VALUE = "value";
ValueMirror(final V8Object v8Object) {
super(v8Object);
}
/**
* Returns the Object that this mirror represents.
*
* @return The object that this mirror represents.
*/
public Object getValue() {
return v8Object.executeFunction(VALUE, null);
}
@Override
public boolean isValue() {
return true;
}
}

7
fine-j2v8/src/main/java/com/eclipsesource/v8/inspector/DebuggerConnectionListener.java

@ -1,7 +0,0 @@
package com.eclipsesource.v8.inspector;
public interface DebuggerConnectionListener {
public void onDebuggerConnected();
public void onDebuggerDisconnected();
}

67
fine-j2v8/src/main/java/com/eclipsesource/v8/inspector/V8Inspector.java

@ -1,67 +0,0 @@
package com.eclipsesource.v8.inspector;
import java.util.ArrayList;
import java.util.List;
import com.eclipsesource.v8.V8;
import com.eclipsesource.v8.V8Object;
public class V8Inspector {
private V8 runtime;
private long inspectorPtr = 0;
private boolean waitingForConnection = true;
private List<DebuggerConnectionListener> debuggerConnectionListeners;
protected V8Inspector(final V8 runtime, final V8InspectorDelegate inspectorDelegate, final String contextName) {
this.runtime = runtime;
inspectorPtr = runtime.createInspector(inspectorDelegate, contextName);
debuggerConnectionListeners = new ArrayList<DebuggerConnectionListener>();
}
public static V8Inspector createV8Inspector(final V8 runtime, final V8InspectorDelegate inspectorDelegate, final String contextName) {
return new V8Inspector(runtime, inspectorDelegate, contextName);
}
public static V8Inspector createV8Inspector(final V8 runtime, final V8InspectorDelegate inspectorDelegate) {
return new V8Inspector(runtime, inspectorDelegate, null);
}
public void dispatchProtocolMessage(final String protocolMessage) {
try {
runtime.dispatchProtocolMessage(inspectorPtr, protocolMessage);
if (waitingForConnection) {
verifyDebuggerConnection(protocolMessage);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void addDebuggerConnectionListener(final DebuggerConnectionListener listener) {
debuggerConnectionListeners.add(listener);
}
public void removeDebuggerConnectionListener(final DebuggerConnectionListener listener) {
debuggerConnectionListeners.remove(listener);
}
private void verifyDebuggerConnection(final String protocolMessage) {
V8Object json = null;
try {
json = runtime.executeObjectScript("JSON.parse(JSON.stringify(" + protocolMessage + "))");
if (json.getString("method").equals("Runtime.runIfWaitingForDebugger")) {
waitingForConnection = false;
runtime.schedulePauseOnNextStatement(inspectorPtr, "");
for (DebuggerConnectionListener listener : debuggerConnectionListeners) {
listener.onDebuggerConnected();
}
}
} finally {
if (json != null) {
json.close();
}
}
}
}

7
fine-j2v8/src/main/java/com/eclipsesource/v8/inspector/V8InspectorDelegate.java

@ -1,7 +0,0 @@
package com.eclipsesource.v8.inspector;
public interface V8InspectorDelegate {
public void onResponse(String message);
public void waitFrontendMessageOnPause();
}

69
fine-j2v8/src/main/java/com/eclipsesource/v8/utils/ArrayBuffer.java

@ -1,69 +0,0 @@
package com.eclipsesource.v8.utils;
/*******************************************************************************
* Copyright (c) 2019 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
import java.nio.ByteBuffer;
import com.eclipsesource.v8.V8;
import com.eclipsesource.v8.V8ArrayBuffer;
/**
* A lightweight handle to a V8TypedArray. This handle provides
* access to a V8TypedArray. This handle does not need to be
* closed, but if the type array is accessed using getV8TypedArray
* then the result must be closed.
*
* The underlying V8TypedArray may be reclaimed by the JavaScript
* garbage collector. To check if it's still available, use
* isAvailable.
*/
public class ArrayBuffer {
private V8ArrayBuffer arrayBuffer;
ArrayBuffer(final V8ArrayBuffer arrayBuffer) {
this.arrayBuffer = (V8ArrayBuffer) arrayBuffer.twin().setWeak();
}
/**
* Create a new ArrayBuffer from a java.nio.ByteBuffer
*
* @param v8 the Runtime on which to create the ArrayBuffer
* @param byteBuffer the ByteBuffer to use to back the ArrayBuffer
*/
public ArrayBuffer(final V8 v8, final ByteBuffer byteBuffer) {
V8ArrayBuffer v8ArrayBuffer = new V8ArrayBuffer(v8, byteBuffer);
try {
arrayBuffer = (V8ArrayBuffer) v8ArrayBuffer.twin().setWeak();
} finally {
v8ArrayBuffer.close();
}
}
/**
* Determine if the underlying V8ArrayBuffer is still available, or if it's been cleaned up by the JavaScript
* garbage collector.
*
* @return true if the underlying V8ArrayBuffer is still available, false otherwise.
*/
public boolean isAvailable() {
return !arrayBuffer.isReleased();
}
/**
* Returns the underlying V8ArrayBuffer.
* @return the underlying V8ArrayBuffer.
*/
public V8ArrayBuffer getV8ArrayBuffer() {
return arrayBuffer.twin();
}
}

94
fine-j2v8/src/main/java/com/eclipsesource/v8/utils/ConcurrentV8.java

@ -1,94 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 Brandon Sanders
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Brandon Sanders - initial API and implementation and/or initial documentation
******************************************************************************/
package com.eclipsesource.v8.utils;
import com.eclipsesource.v8.V8;
/**
* Wrapper class for an {@link com.eclipsesource.v8.V8} instance that allows
* a V8 instance to be invoked from across threads without explicitly acquiring
* or releasing locks.
*
* This class does not guarantee the safety of any objects stored in or accessed
* from the wrapped V8 instance; it only enables callers to interact with a V8
* instance from any thread. The V8 instance represented by this class should
* still be treated with thread safety in mind
*
* @author Brandon Sanders [brandon@alicorn.io]
* @author R. Ian Bull - Additional API
*/
public final class ConcurrentV8 {
private V8 v8 = null;
/**
* Create a new ConcurrentV8. A ConcurrentV8 allows multiple
* threads to work with the same V8 engine by releasing
* the locks between calls.
*/
public ConcurrentV8() {
v8 = V8.createV8Runtime();
v8.getLocker().release();
}
/**
* Returns the V8 runtime backing by this ConcurrentV8
*
* @return The V8 runtime backing this ConcurrentV8
*/
public V8 getV8() {
return v8;
}
/**
* Runs an {@link V8Runnable} on the V8 thread.
*
* <b>Note: </b> This method executes synchronously, not asynchronously;
* it will not return until the passed {@link V8Runnable} is done
* executing. The method is also synchronized, so it will block until it
* gets a chance to run.
*
* @param runnable {@link V8Runnable} to run.
*/
public synchronized void run(final V8Runnable runnable) {
try {
v8.getLocker().acquire();
runnable.run(v8);
} finally {
if ((v8 != null) && (v8.getLocker() != null) && v8.getLocker().hasLock()) {
v8.getLocker().release();
}
}
}
/**
* Releases the underlying {@link V8} instance.
*
* This method should be invoked once you're done using this object,
* otherwise a large amount of garbage could be left on the JVM due to
* native resources.
*
* <b>Note:</b> If this method has already been called once, it
* will do nothing.
*/
public void release() {
if ((v8 != null) && !v8.isReleased()) {
// Release the V8 instance from the V8 thread context.
run(new V8Runnable() {
@Override
public void run(final V8 v8) {
if ((v8 != null) && !v8.isReleased()) {
v8.close();
}
}
});
}
}
}

138
fine-j2v8/src/main/java/com/eclipsesource/v8/utils/MemoryManager.java

@ -1,138 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.utils;
import java.util.ArrayList;
import java.util.Iterator;
import com.eclipsesource.v8.ReferenceHandler;
import com.eclipsesource.v8.V8;
import com.eclipsesource.v8.V8Value;
/**
* A memory manager that tracks all V8 Handles while the object is registered.
* Once released, all V8 handles that were created while the memory manager
* was active, will be released.
*
* It is important that no V8 handles (V8Objects, V8Arrays, etc...) that are
* created while the memory manager is active, are persisted.
*
*/
public class MemoryManager {
private MemoryManagerReferenceHandler memoryManagerReferenceHandler;
private V8 v8;
private ArrayList<V8Value> references = new ArrayList<V8Value>();
private boolean releasing = false;
private boolean released = false;
/**
* Creates and registered a Memory Manager. After this, all V8 handles will be
* tracked until release is called.
*
* @param v8 The V8 runtime to register this Memory Manager on
*/
public MemoryManager(final V8 v8) {
this.v8 = v8;
memoryManagerReferenceHandler = new MemoryManagerReferenceHandler();
v8.addReferenceHandler(memoryManagerReferenceHandler);
}
/**
* Returns the number of handles currently being tracked by this
* memory manager.
*
* Throws an IllegalStateException if the memory manager is used after it's
* been released.
*
* @return The object reference count
*/
public int getObjectReferenceCount() {
checkReleased();
return references.size();
}
/**
* Persist an object that is currently being managed by this Manager.
*
* Objects that are being managed by a MemoryManager will be released
* once the MemoryManager is released. If an object is persisted, it will
* be remove from the MemoryManager's control and therefore will not
* be released.
*
* @param object The object to persist
*/
public void persist(final V8Value object) {
v8.getLocker().checkThread();
checkReleased();
references.remove(object);
}
/**
* Checks if the memory manager has been released or not. Released memory
* managers can no longer be used.
*
* @return True if this memory manager has been released, false otherwise.
*/
public boolean isReleased() {
return released;
}
/**
* Releases this Memory Manager and all V8Objects that were created while
* this memory manager was active.
*/
public void release() {
v8.getLocker().checkThread();
if (released) {
return;
}
releasing = true;
try {
for (V8Value reference : references) {
reference.close();
}
v8.removeReferenceHandler(memoryManagerReferenceHandler);
references.clear();
} finally {
releasing = false;
}
released = true;
}
private void checkReleased() {
if (released) {
throw new IllegalStateException("Memory manager released");
}
}
private class MemoryManagerReferenceHandler implements ReferenceHandler {
@Override
public void v8HandleCreated(final V8Value object) {
references.add(object);
}
@Override
public void v8HandleDisposed(final V8Value object) {
if (!releasing) {
Iterator<V8Value> iterator = references.iterator();
while (iterator.hasNext()) {
if (iterator.next() == object) {
iterator.remove();
return;
}
}
}
}
}
}

55
fine-j2v8/src/main/java/com/eclipsesource/v8/utils/SingleTypeAdapter.java

@ -1,55 +0,0 @@
/*******************************************************************************
* Copyright (c) 2017 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.utils;
/**
* Adapt all instances of a single type from JavaScript to Java.
* The TypeAdapter can be used with the V8ObjectUtils to allow users to customize
* the conversion.
*/
public abstract class SingleTypeAdapter implements TypeAdapter {
private int typeToAdapt;
/**
* Create a SingleTypeAdapter
*
* @param typeToAdapt The V8 Type this TypeAdapter should be applied to.
*/
public SingleTypeAdapter(final int typeToAdapt) {
this.typeToAdapt = typeToAdapt;
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.utils.TypeAdapter#adapt(int, java.lang.Object)
*/
@Override
public Object adapt(final int type, final Object value) {
if (type == typeToAdapt) {
return adapt(value);
}
return TypeAdapter.DEFAULT;
}
/**
* Adapt an object from V8 to Java.
*
* If the value is a V8Value (V8Object) then it will be released after
* this method is called. If you wish to retain the object, call
* ((V8Value)value).twin();
*
* @param value The V8 Object to be converted.
* @return The adapted Java Object or {@link TypeAdapter#DEFAULT} for the default conversion.
*/
public abstract Object adapt(final Object value);
}

39
fine-j2v8/src/main/java/com/eclipsesource/v8/utils/TypeAdapter.java

@ -1,39 +0,0 @@
/*******************************************************************************
* Copyright (c) 2017 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.utils;
/**
* An interface which allows a plug-able conversion from V8Value types to Java objects.
* The TypeAdapter can be used with the V8ObjectUtils to allow users to customize
* the conversion.
*/
public interface TypeAdapter {
/**
* A default adapter that if returned in {@link TypeAdapter#adapt(int, Object)}, will result
* in the default type adaption.
*/
public static final Object DEFAULT = new Object();
/**
* Adapt an object from V8 to Java.
*
* If the value is a V8Value (V8Object) then it will be released after
* this method is called. If you wish to retain the object, call
* ((V8Value)value).twin();
*
* @param type The Type of the object to be adapted.
* @param value The V8 Object to be converted.
* @return The adapted Java Object or {@link TypeAdapter#DEFAULT} for the default conversion.
*/
public Object adapt(int type, Object value);
}

73
fine-j2v8/src/main/java/com/eclipsesource/v8/utils/TypedArray.java

@ -1,73 +0,0 @@
package com.eclipsesource.v8.utils;
/*******************************************************************************
* Copyright (c) 2019 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
import com.eclipsesource.v8.V8;
import com.eclipsesource.v8.V8ArrayBuffer;
import com.eclipsesource.v8.V8TypedArray;
/**
* A lightweight handle to a V8TypedArray. This handle provides
* access to a V8TypedArray. This handle does not need to be
* closed, but if the type array is accessed using getV8TypedArray
* then the result must be closed.
*
* The underlying V8TypedArray may be reclaimed by the JavaScript
* garbage collector. To check if it's still available, use
* isAvailable.
*/
public class TypedArray {
private V8TypedArray typedArray;
TypedArray(final V8TypedArray typedArray) {
this.typedArray = (V8TypedArray) typedArray.twin().setWeak();
}
/**
* Create a new TypedArray from an ArrayBuffer.
*
* @param v8 the V8Runtime on which to create the TypedArray
* @param buffer the ArrayBuffer to use to back the TypedArray
* @param type the Type of Array to create
* @param offset the Offset into the ArrayBuffer in which to map the TyepdArray
* @param size the Size of the TypedArray
*/
public TypedArray(final V8 v8, final ArrayBuffer buffer, final int type, final int offset, final int size) {
V8ArrayBuffer v8ArrayBuffer = buffer.getV8ArrayBuffer();
V8TypedArray v8typedArray = new V8TypedArray(v8, v8ArrayBuffer, type, offset, size);
try {
typedArray = (V8TypedArray) v8typedArray.twin().setWeak();
} finally {
v8ArrayBuffer.close();
v8typedArray.close();
}
}
/**
* Determine if the underlying V8TypedArray is still available, or if it's been cleaned up by the JavaScript
* garbage collector.
*
* @return true if the underlying V8TypedArray is still available, false otherwise.
*/
public boolean isAvailable() {
return !typedArray.isReleased();
}
/**
* Returns the underlying V8TypedArray.
* @return the underlying V8TypedArray.
*/
public V8TypedArray getV8TypedArray() {
return (V8TypedArray) typedArray.twin();
}
}

253
fine-j2v8/src/main/java/com/eclipsesource/v8/utils/V8Executor.java

@ -1,253 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.utils;
import java.util.LinkedList;
import com.eclipsesource.v8.JavaVoidCallback;
import com.eclipsesource.v8.Releasable;
import com.eclipsesource.v8.V8;
import com.eclipsesource.v8.V8Array;
import com.eclipsesource.v8.V8Object;
/**
* Executes a JS Script on a new V8 runtime in its own thread, and once finished,
* will optionally wait on a message queue. If the executor is *not* long running,
* when the JS Script finishes, the executor will shutdown. If the executor
* *is* long running, the the script will execute, and when finished, the executor
* will wait for messages to arrive. When messages arrive, the messageHandler
* will be invoked with the contents of the message.
*
* Executors can be shutdown in two different ways. forceTermination() will
* stop any executing scripts and immediately terminate the executor. shutdown()
* will indicate that the executor should shutdown, but this will only happen
* once any scripts finish executing and the message queue becomes empty.
*/
public class V8Executor extends Thread {
private final String script;
private V8 runtime;
private String result;
private volatile boolean terminated = false;
private volatile boolean shuttingDown = false;
private volatile boolean forceTerminating = false;
private Exception exception = null;
private LinkedList<String[]> messageQueue = new LinkedList<String[]>();
private boolean longRunning;
private String messageHandler;
/**
* Create a new executor and execute the given script on it. Once
* the script has finished executing, the executor can optionally
* wait on a message queue.
*
* @param script The script to execute on this executor.
* @param longRunning True to indicate that this executor should be longRunning.
* @param messageHandler The name of the message handler that should be notified
* when messages are delivered.
*/
public V8Executor(final String script, final boolean longRunning, final String messageHandler) {
this.script = script;
this.longRunning = longRunning;
this.messageHandler = messageHandler;
}
/**
* Create a new executor and execute the given script on it.
*
* @param script The script to execute on this executor.
*/
public V8Executor(final String script) {
this(script, false, null);
}
/**
* Override to provide a custom setup for this V8 runtime.
* This method can be overridden to configure the V8 runtime,
* for example, to add callbacks or to add some additional
* functionality to the global scope.
*
* @param runtime The runtime to configure.
*/
protected void setup(final V8 runtime) {
}
/**
* Gets the result of the JavaScript that was executed
* on this executor.
*
* @return The result of the JS Script that was executed on
* this executor.
*/
public String getResult() {
return result;
}
/**
* Posts a message to the receiver to be processed by the executor
* and sent to the V8 runtime via the messageHandler.
*
* @param message The message to send to the messageHandler
*/
public void postMessage(final String... message) {
synchronized (this) {
messageQueue.add(message);
notify();
}
}
/*
* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void run() {
synchronized (this) {
runtime = V8.createV8Runtime();
runtime.registerJavaMethod(new ExecutorTermination(), "__j2v8__checkThreadTerminate");
setup(runtime);
}
try {
if (!forceTerminating) {
Object scriptResult = runtime.executeScript("__j2v8__checkThreadTerminate();\n" + script, getName(), -1);
if (scriptResult != null) {
result = scriptResult.toString();
}
if (scriptResult instanceof Releasable) {
((Releasable) scriptResult).release();
}
}
while (!forceTerminating && longRunning) {
synchronized (this) {
if (messageQueue.isEmpty() && !shuttingDown) {
wait();
}
if ((messageQueue.isEmpty() && shuttingDown) || forceTerminating) {
return;
}
}
if (!messageQueue.isEmpty()) {
String[] message = messageQueue.remove(0);
V8Array parameters = new V8Array(runtime);
V8Array strings = new V8Array(runtime);
try {
for (String string : message) {
strings.push(string);
}
parameters.push(strings);
runtime.executeVoidFunction(messageHandler, parameters);
} finally {
strings.close();
parameters.close();
}
}
}
} catch (Exception e) {
exception = e;
} finally {
synchronized (this) {
if (runtime.getLocker().hasLock()) {
runtime.close();
runtime = null;
}
terminated = true;
}
}
}
/**
* Determines if an exception was thrown during the JavaScript execution.
*
* @return True if an exception was thrown during the JavaScript execution,
* false otherwise.
*/
public boolean hasException() {
return exception != null;
}
/**
* Gets the exception that was thrown during the JavaScript execution.
*
* @return The exception that was thrown during the JavaScript execution,
* or null if no such exception was thrown.
*/
public Exception getException() {
return exception;
}
/**
* Determines if the executor has terminated.
*
* @return True if the executor has terminated, false otherwise.
*/
public boolean hasTerminated() {
return terminated;
}
/**
* Forces the executor to shutdown immediately. Any currently executing
* JavaScript will be interrupted and all outstanding messages will be
* ignored.
*/
public void forceTermination() {
synchronized (this) {
forceTerminating = true;
shuttingDown = true;
if (runtime != null) {
runtime.terminateExecution();
}
notify();
}
}
/**
* Indicates to the executor that it should shutdown. Any currently
* executing JavaScript will be allowed to finish, and any outstanding
* messages will be processed. Only once the message queue is empty,
* will the executor actually shtutdown.
*/
public void shutdown() {
synchronized (this) {
shuttingDown = true;
notify();
}
}
/**
* Returns true if shutdown() or forceTermination() was called to
* shutdown this executor.
*
* @return True if shutdown() or forceTermination() was called, false otherwise.
*/
public boolean isShuttingDown() {
return shuttingDown;
}
/**
* Returns true if forceTermination was called to shutdown
* this executor.
*
* @return True if forceTermination() was called, false otherwise.
*/
public boolean isTerminating() {
return forceTerminating;
}
class ExecutorTermination implements JavaVoidCallback {
@Override
public void invoke(final V8Object receiver, final V8Array parameters) {
if (forceTerminating) {
throw new RuntimeException("V8Thread Termination");
}
}
}
}

185
fine-j2v8/src/main/java/com/eclipsesource/v8/utils/V8Map.java

@ -1,185 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.utils;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.eclipsesource.v8.Releasable;
import com.eclipsesource.v8.V8Value;
/**
* A Map that maps V8Values to arbitrary Java Objects.
* Once stored in the map, the keys (V8Values) can be released
* as the map will handle their resource management for you.
*
* Once the map is no longer needed, it should be released. To
* tie a map to the lifecycle of a V8 runtime, it can be registered
* as a resource with V8.registerResource.
*/
public class V8Map<V> implements Map<V8Value, V>, Releasable {
private Map<V8Value, V> map;
private Map<V8Value, V8Value> twinMap;
/**
* Creates a V8Map.
*/
public V8Map() {
map = new HashMap<V8Value, V>();
twinMap = new HashMap<V8Value, V8Value>();
}
/*
* (non-Javadoc)
* @see java.io.Closeable#close()
*/
@Override
public void close() {
this.clear();
}
/**
* Releases all the resources associated with this map. A
* map can be used again once it's released, although
* if it's used again it should be released again.
*/
@Override
@Deprecated
public void release() {
close();
}
/*
* (non-Javadoc)
* @see java.util.Map#size()
*/
@Override
public int size() {
return map.size();
}
/*
* (non-Javadoc)
* @see java.util.Map#isEmpty()
*/
@Override
public boolean isEmpty() {
return map.isEmpty();
}
/*
* (non-Javadoc)
* @see java.util.Map#containsKey(java.lang.Object)
*/
@Override
public boolean containsKey(final Object key) {
return map.containsKey(key);
}
/*
* (non-Javadoc)
* @see java.util.Map#containsValue(java.lang.Object)
*/
@Override
public boolean containsValue(final Object value) {
return map.containsValue(value);
}
/*
* (non-Javadoc)
* @see java.util.Map#get(java.lang.Object)
*/
@Override
public V get(final Object key) {
return map.get(key);
}
/*
* (non-Javadoc)
* @see java.util.Map#put(java.lang.Object, java.lang.Object)
*/
@Override
public V put(final V8Value key, final V value) {
this.remove(key);
V8Value twin = key.twin();
twinMap.put(twin, twin);
return map.put(twin, value);
}
/*
* (non-Javadoc)
* @see java.util.Map#remove(java.lang.Object)
*/
@Override
public V remove(final Object key) {
V result = map.remove(key);
V8Value twin = twinMap.remove(key);
if (twin != null) {
twin.close();
}
return result;
}
/*
* (non-Javadoc)
* @see java.util.Map#putAll(java.util.Map)
*/
@Override
public void putAll(final Map<? extends V8Value, ? extends V> m) {
for (java.util.Map.Entry<? extends V8Value, ? extends V> entry : m.entrySet()) {
this.put(entry.getKey(), entry.getValue());
}
}
/*
* (non-Javadoc)
* @see java.util.Map#clear()
*/
@Override
public void clear() {
map.clear();
for (V8Value V8Value : twinMap.keySet()) {
V8Value.close();
}
twinMap.clear();
}
/*
* (non-Javadoc)
* @see java.util.Map#keySet()
*/
@Override
public Set<V8Value> keySet() {
return map.keySet();
}
/*
* (non-Javadoc)
* @see java.util.Map#values()
*/
@Override
public Collection<V> values() {
return map.values();
}
/*
* (non-Javadoc)
* @see java.util.Map#entrySet()
*/
@Override
public Set<java.util.Map.Entry<V8Value, V>> entrySet() {
return map.entrySet();
}
}

703
fine-j2v8/src/main/java/com/eclipsesource/v8/utils/V8ObjectUtils.java

@ -1,703 +0,0 @@
/*******************************************************************************
* Copyright (c) 2014 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.utils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.eclipsesource.v8.Releasable;
import com.eclipsesource.v8.V8;
import com.eclipsesource.v8.V8Array;
import com.eclipsesource.v8.V8ArrayBuffer;
import com.eclipsesource.v8.V8Object;
import com.eclipsesource.v8.V8TypedArray;
import com.eclipsesource.v8.V8Value;
/**
* A set of static helper methods to convert V8Objects / V8Arrays to
* java.util Maps and Lists and back again. These conversions
* perform a deep copy.
*/
public class V8ObjectUtils {
private static final Object IGNORE = new Object();
private static final TypeAdapter DEFAULT_TYPE_ADAPTER = new DefaultTypeAdapter();
/**
* Create a Java Object from a result from V8. V8 can return
* basic Java types, or V8Values (V8Object, V8Array, etc...). This method
* will attempt to convert the result into a pure Java object using a
* deep copy.
*
* If the input is basic Java type (Integer, Double, Boolean, String)
* it will be returned. If the input is a V8Value, it will be converted.
*
* All elements in the V8Object are released after they are accessed.
* However, the root object itself is not released.
*
* @param v8Object The input to convert.
* @return A Java object representing the input.
*/
public static Object getValue(final Object v8Object) {
return getValue(v8Object, DEFAULT_TYPE_ADAPTER);
}
/**
* Create a Java Object from a result from V8 using a {@link TypeAdapter} to convert
* objects. V8 can return basic Java types or V8Values (V8Object, V8Array, etc...). This
* method will attempt to convert the result into a pure Java object using
* a deep copy.
*
* If the input is basic Java type (Integer, Double, Boolean, String)
* it will be returned. If the input is a V8Value, it will be converted.
*
* All elements in the V8Object are released after they are accessed.
* However, the root object itself is not released.
*
* @param v8Object The input to convert.
* @param adapter The {@link TypeAdapter} to use for the object conversions.
* @return A Java object representing the input.
*/
public static Object getValue(final Object v8Object, final TypeAdapter adapter) {
V8Map<Object> cache = new V8Map<Object>();
try {
if (v8Object instanceof V8Value) {
int type = ((V8Value) v8Object).getV8Type();
return getValue(v8Object, type, cache, adapter);
} else {
return v8Object;
}
} finally {
cache.close();
}
}
/**
* Creates a Map from a V8Object using a deep copy. All elements
* in the V8Object are released after they are accessed. However, the root
* object itself is not released.
*
* @param object The root of the V8Object graph.
*
* @return A map representing a deep copy of the V8Object rooted at 'object'.
*/
public static Map<String, ? super Object> toMap(final V8Object object) {
return toMap(object, DEFAULT_TYPE_ADAPTER);
}
/**
* Creates a Map from a V8Object using a deep copy and a TypeAdapter to handle
* type conversions. All elements in the V8Object are released after they are accessed.
* However, the root object itself is not released.
*
* @param object The root of the V8Object graph.
* @param adapter The {@link TypeAdapter} to use for the object conversions.
*
* @return A map representing a deep copy of the V8Object rooted at 'object'.
*/
public static Map<String, ? super Object> toMap(final V8Object object, final TypeAdapter adapter) {
V8Map<Object> cache = new V8Map<Object>();
try {
return toMap(object, cache, adapter);
} finally {
cache.close();
}
}
/**
* Creates a List from a V8Array using a deep copy. All elements
* in the V8Array are released after they are accessed. However, the root
* array itself is not released.
*
* @param array The root of the V8Array graph.
*
* @return A list representing a deep copy of the V8Array rooted at 'array'.
*/
public static List<? super Object> toList(final V8Array array) {
return toList(array, DEFAULT_TYPE_ADAPTER);
}
/**
* Creates a List from a V8Array using a deep copy and a TypeAdapter to handle
* type conversions. All elements in the V8Array are released after they are accessed.
* However, the root array itself is not released.
*
* @param array The root of the V8Array graph.
* @param adapter The {@link TypeAdapter} to use for the object conversions.
*
* @return A list representing a deep copy of the V8Array rooted at 'array'.
*/
public static List<? super Object> toList(final V8Array array, final TypeAdapter adapter) {
V8Map<Object> cache = new V8Map<Object>();
try {
return toList(array, cache, adapter);
} finally {
cache.close();
}
}
/**
* Populates a Java array from a V8Array. The type of the array must be specified.
* Currently, only INTEGER, DOUBLE, BOOLEAN and STRING are supported.
* The V8Array must only contain elements of type 'arrayType'. The result
* can be optionally passed in as a parameter.
*
* This method will use J2V8's bulk array copy making it faster than iterating over
* all the elements in the array.
*
* @param array The V8Array to convert to a Java Array.
* @param arrayType The type of the V8Array to convert.
* @param result The array to use as the result. If null, a new array will be created.
*
* @return A Java array representing a V8Array.
*/
public static Object getTypedArray(final V8Array array, final int arrayType, final Object result) {
int length = array.length();
if (arrayType == V8Value.INTEGER) {
int[] intArray = (int[]) result;
if ((intArray == null) || (intArray.length < length)) {
intArray = new int[length];
}
array.getIntegers(0, length, intArray);
return intArray;
} else if (arrayType == V8Value.DOUBLE) {
double[] doubleArray = (double[]) result;
if ((doubleArray == null) || (doubleArray.length < length)) {
doubleArray = new double[length];
}
array.getDoubles(0, length, doubleArray);
return doubleArray;
} else if (arrayType == V8Value.BOOLEAN) {
boolean[] booleanArray = (boolean[]) result;
if ((booleanArray == null) || (booleanArray.length < length)) {
booleanArray = new boolean[length];
}
array.getBooleans(0, length, booleanArray);
return booleanArray;
} else if (arrayType == V8Value.STRING) {
String[] stringArray = (String[]) result;
if ((stringArray == null) || (stringArray.length < length)) {
stringArray = new String[length];
}
array.getStrings(0, length, stringArray);
return stringArray;
} else if (arrayType == V8Value.BYTE) {
byte[] byteArray = (byte[]) result;
if ((byteArray == null) || (byteArray.length < length)) {
byteArray = new byte[length];
}
array.getBytes(0, length, byteArray);
return byteArray;
}
throw new RuntimeException("Unsupported bulk load type: " + arrayType);
}
/**
* Creates a Java array from a V8Array. The type of the Array must be specified.
* Currently, only INTEGER, DOUBLE, BOOLEAN and STRING are supported.
* The V8Array must only contain elements of type 'arrayType'.
*
* This method will use J2V8's bulk array copy making it faster than iterating over
* all the elements in the array.
*
* @param array The V8Array to convert to a Java Array.
* @param arrayType The type of the V8Array to convert.
*
* @return A Java array representing a V8Array.
*/
public static Object getTypedArray(final V8Array array, final int arrayType) {
int length = array.length();
if (arrayType == V8Value.INTEGER) {
return array.getIntegers(0, length);
} else if (arrayType == V8Value.DOUBLE) {
return array.getDoubles(0, length);
} else if (arrayType == V8Value.BOOLEAN) {
return array.getBooleans(0, length);
} else if (arrayType == V8Value.STRING) {
return array.getStrings(0, length);
}
throw new RuntimeException("Unsupported bulk load type: " + arrayType);
}
/**
* Creates a V8Object from a java.util.Map. This is a deep copy, so if the map
* contains other maps (or lists) they will also be converted.
*
* @param v8 The runtime on which to create the result.
* @param map The map to convert to a V8Object.
*
* @return A V8Object representing the map.
*/
public static V8Object toV8Object(final V8 v8, final Map<String, ? extends Object> map) {
Map<Object, V8Value> cache = new Hashtable<Object, V8Value>();
try {
return toV8Object(v8, map, cache).twin();
} finally {
for (V8Value v8Object : cache.values()) {
v8Object.close();
}
}
}
/**
* Creates a V8Array from a java.util.List. This is a deep copy, so if the list
* contains other lists (or maps) they will also be converted.
*
* @param v8 The runtime on which to create the result.
* @param list The list to convert to a V8Array.
*
* @return A V8Array representing the list.
*/
public static V8Array toV8Array(final V8 v8, final List<? extends Object> list) {
Map<Object, V8Value> cache = new Hashtable<Object, V8Value>();
try {
return toV8Array(v8, list, cache).twin();
} finally {
for (V8Value v8Object : cache.values()) {
v8Object.close();
}
}
}
/**
* Returns an object usable with a V8 Runtime which represents
* the parameter 'value'. If 'value' is an Integer, Boolean, Double
* or String, then 'value' is simply returned as these are directly
* usable on V8. If 'value' is a map / list, then it's converted to
* a V8Object / V8Array first.
*
* If the result is a V8Value, it must be released.
*
* @param v8 The runtime on which to create V8Values.
* @param value The value to convert to an object usable with V8
*
* @return An object which can be used directly with a V8 runtime.
*/
public static Object getV8Result(final V8 v8, final Object value) {
if (value == null) {
return null;
}
Map<Object, V8Value> cache = new Hashtable<Object, V8Value>();
try {
Object result = getV8Result(v8, value, cache);
if (result instanceof V8Value) {
return ((V8Value) result).twin();
}
return result;
} finally {
for (V8Value v8Object : cache.values()) {
v8Object.close();
}
}
}
/**
* Pushes a Java Object to a V8Array by first converting it to a V8Value if needed.
* If the value is a boxed primitive, then the primitive will be pushed. If the object
* is a Map / List then a deep copy will be performed, converting the object to a
* V8Object / V8Array first.
*
* @param v8 The runtime on which to create any needed V8Values.
* @param array The array to push the elements to.
* @param value The value to push to the array.
*/
public static void pushValue(final V8 v8, final V8Array array, final Object value) {
Map<Object, V8Value> cache = new Hashtable<Object, V8Value>();
try {
pushValue(v8, array, value, cache);
} finally {
for (V8Value v8Object : cache.values()) {
v8Object.close();
}
}
}
/**
* Gets a Java Object representing the value at the given index in the V8Array.
* If the value is a primitive (int, boolean or double) then a boxed instance
* is returned. If the value is a String, then a String is returned. If
* the value is a V8Object or V8Array, then a Map or List is returned.
*
* @param array The array on which to lookup the value. The array is not
* released.
* @param index The index whose element to lookup.
*
* @return A Java Object representing the value at a given index.
*/
public static Object getValue(final V8Array array, final int index) {
V8Map<Object> cache = new V8Map<Object>();
Object object = null;
int type = V8Value.UNDEFINED;
try {
object = array.get(index);
type = array.getType(index);
Object result = getValue(object, type, cache, DEFAULT_TYPE_ADAPTER);
if ((result == object) && (result instanceof V8Value)) {
return ((V8Value) result).twin();
}
return result;
} finally {
if (object instanceof Releasable) {
((Releasable) object).release();
}
cache.close();
}
}
/**
* Gets a Java Object representing the value at the given index in the V8Array.
* A TypeAdapter is used to convert values from V8Objects to Java Objects.
* If the value is a primitive (int, boolean or double) then a boxed instance
* is returned. If the value is a String, then a String is returned. If
* the value is a V8Object or V8Array, then a Map or List is returned.
*
* @param array The array on which to lookup the value. The array is not
* released.
* @param index The index whose element to lookup.
* @param adapter The {@link TypeAdapter} to use for the object conversions.
*
* @return A Java Object representing the value at a given index.
*/
public static Object getValue(final V8Array array, final int index, final TypeAdapter adapter) {
V8Map<Object> cache = new V8Map<Object>();
Object object = null;
int type = V8Value.UNDEFINED;
try {
object = array.get(index);
type = array.getType(index);
Object result = getValue(object, type, cache, adapter);
if ((result == object) && (result instanceof V8Value)) {
return ((V8Value) result).twin();
}
return result;
} finally {
if (object instanceof Releasable) {
((Releasable) object).release();
}
cache.close();
}
}
/**
* Gets a Java Object representing the value with the given key in the V8Object.
* If the value is a primitive (int, boolean or double) then a boxed instance
* is returned. If the value is a String, then a String is returned. If
* the value is a V8Object or V8Array, then a Map or List is returned.
*
* @param object The object on which to lookup the value. The object is not
* released.
* @param key The key to use to lookup the value.
*
* @return A Java Object representing the value at a given key.
*/
public static Object getValue(final V8Object object, final String key) {
return getValue(object, key, DEFAULT_TYPE_ADAPTER);
}
/**
* Gets a Java Object representing the value with the given key in the V8Object.
* A TypeAdapter is used to convert values from V8Objects to Java Objects.
* If the value is a primitive (int, boolean or double) then a boxed instance
* is returned. If the value is a String, then a String is returned. If
* the value is a V8Object or V8Array, then a Map or List is returned.
*
* @param v8Object The object on which to lookup the value. The object is not
* released.
* @param key The key to use to lookup the value.
* @param adapter The {@link TypeAdapter} to use for the object conversions.
*
* @return A Java Object representing the value at a given key.
*/
public static Object getValue(final V8Object v8Object, final String key, final TypeAdapter adapter) {
V8Map<Object> cache = new V8Map<Object>();
Object object = null;
int type = V8Value.UNDEFINED;
try {
object = v8Object.get(key);
type = v8Object.getType(key);
Object result = getValue(object, type, cache, adapter);
if ((result == object) && (result instanceof V8Value)) {
return ((V8Value) result).twin();
}
return result;
} finally {
if (object instanceof Releasable) {
((Releasable) object).release();
}
cache.close();
}
}
@SuppressWarnings("unchecked")
private static Map<String, ? super Object> toMap(final V8Object v8Object, final V8Map<Object> cache, final TypeAdapter adapter) {
if (v8Object == null) {
return Collections.emptyMap();
}
if (cache.containsKey(v8Object)) {
return (Map<String, ? super Object>) cache.get(v8Object);
}
Map<String, ? super Object> result = new V8PropertyMap<Object>();
cache.put(v8Object, result);
String[] keys = v8Object.getKeys();
for (String key : keys) {
Object object = null;
int type = V8Value.UNDEFINED;
try {
object = v8Object.get(key);
type = v8Object.getType(key);
Object value = getValue(object, type, cache, adapter);
if (value != IGNORE) {
result.put(key, value);
}
} finally {
if (object instanceof Releasable) {
((Releasable) object).release();
}
}
}
return result;
}
@SuppressWarnings("unchecked")
private static List<? super Object> toList(final V8Array array, final V8Map<Object> cache, final TypeAdapter adapter) {
if (array == null) {
return Collections.emptyList();
}
if (cache.containsKey(array)) {
return (List<? super Object>) cache.get(array);
}
List<? super Object> result = new ArrayList<Object>();
cache.put(array, result);
for (int i = 0; i < array.length(); i++) {
Object object = null;
int type = V8Value.UNDEFINED;
try {
object = array.get(i);
type = array.getType(i);
Object value = getValue(object, type, cache, adapter);
if (value != IGNORE) {
result.add(value);
}
} finally {
if (object instanceof Releasable) {
((Releasable) object).release();
}
}
}
return result;
}
private static V8TypedArray toV8TypedArray(final V8 v8, final TypedArray typeArray, final Map<Object, V8Value> cache) {
if (cache.containsKey(typeArray)) {
return (V8TypedArray) cache.get(typeArray);
}
V8TypedArray result = typeArray.getV8TypedArray();
cache.put(typeArray, result);
return result;
}
private static V8ArrayBuffer toV8ArrayBuffer(final V8 v8, final ArrayBuffer arrayBuffer, final Map<Object, V8Value> cache) {
if (cache.containsKey(arrayBuffer)) {
return (V8ArrayBuffer) cache.get(arrayBuffer);
}
V8ArrayBuffer result = arrayBuffer.getV8ArrayBuffer();
cache.put(arrayBuffer, result);
return result;
}
private static V8Object toV8Object(final V8 v8, final Map<String, ? extends Object> map, final Map<Object, V8Value> cache) {
if (cache.containsKey(map)) {
return (V8Object) cache.get(map);
}
V8Object result = new V8Object(v8);
cache.put(map, result);
try {
for (Entry<String, ? extends Object> entry : map.entrySet()) {
setValue(v8, result, entry.getKey(), entry.getValue(), cache);
}
} catch (IllegalStateException e) {
result.close();
throw e;
}
return result;
}
private static V8Array toV8Array(final V8 v8, final List<? extends Object> list, final Map<Object, V8Value> cache) {
if (cache.containsKey(new ListWrapper(list))) {
return (V8Array) cache.get(new ListWrapper(list));
}
V8Array result = new V8Array(v8);
cache.put(new ListWrapper(list), result);
try {
for (int i = 0; i < list.size(); i++) {
Object value = list.get(i);
pushValue(v8, result, value, cache);
}
} catch (IllegalStateException e) {
result.close();
throw e;
}
return result;
}
@SuppressWarnings("unchecked")
private static Object getV8Result(final V8 v8, final Object value, final Map<Object, V8Value> cache) {
if (cache.containsKey(value)) {
return cache.get(value);
}
if (value instanceof Map<?, ?>) {
return toV8Object(v8, (Map<String, ? extends Object>) value, cache);
} else if (value instanceof List<?>) {
return toV8Array(v8, (List<? extends Object>) value, cache);
} else if (value instanceof TypedArray) {
return toV8TypedArray(v8, (TypedArray) value, cache);
} else if (value instanceof ArrayBuffer) {
return toV8ArrayBuffer(v8, (ArrayBuffer) value, cache);
}
return value;
}
@SuppressWarnings({ "unchecked", "rawtypes", "resource" })
private static void pushValue(final V8 v8, final V8Array result, final Object value, final Map<Object, V8Value> cache) {
if (value == null) {
result.pushUndefined();
} else if (value instanceof Integer) {
result.push(value);
} else if (value instanceof Long) {
result.push(new Double((Long) value));
} else if (value instanceof Double) {
result.push(value);
} else if (value instanceof Float) {
result.push(value);
} else if (value instanceof String) {
result.push((String) value);
} else if (value instanceof Boolean) {
result.push(value);
} else if (value instanceof TypedArray) {
V8TypedArray v8TypedArray = toV8TypedArray(v8, (TypedArray) value, cache);
result.push(v8TypedArray);
} else if (value instanceof ArrayBuffer) {
V8ArrayBuffer v8ArrayBuffer = toV8ArrayBuffer(v8, (ArrayBuffer) value, cache);
result.push(v8ArrayBuffer);
} else if (value instanceof V8Value) {
result.push((V8Value) value);
} else if (value instanceof Map) {
V8Object object = toV8Object(v8, (Map) value, cache);
result.push(object);
} else if (value instanceof List) {
V8Array array = toV8Array(v8, (List) value, cache);
result.push(array);
} else {
throw new IllegalStateException("Unsupported Object of type: " + value.getClass());
}
}
@SuppressWarnings({ "unchecked", "rawtypes", "resource" })
private static void setValue(final V8 v8, final V8Object result, final String key, final Object value, final Map<Object, V8Value> cache) {
if (value == null) {
result.addUndefined(key);
} else if (value instanceof Integer) {
result.add(key, (Integer) value);
} else if (value instanceof Long) {
result.add(key, (Long) value);
} else if (value instanceof Double) {
result.add(key, (Double) value);
} else if (value instanceof Float) {
result.add(key, (Float) value);
} else if (value instanceof String) {
result.add(key, (String) value);
} else if (value instanceof Boolean) {
result.add(key, (Boolean) value);
} else if (value instanceof TypedArray) {
V8TypedArray v8TypedArray = toV8TypedArray(v8, (TypedArray) value, cache);
result.add(key, v8TypedArray);
} else if (value instanceof ArrayBuffer) {
V8ArrayBuffer v8ArrayBuffer = toV8ArrayBuffer(v8, (ArrayBuffer) value, cache);
result.add(key, v8ArrayBuffer);
} else if (value instanceof V8Value) {
result.add(key, (V8Value) value);
} else if (value instanceof Map) {
V8Object object = toV8Object(v8, (Map) value, cache);
result.add(key, object);
} else if (value instanceof List) {
V8Array array = toV8Array(v8, (List) value, cache);
result.add(key, array);
} else {
throw new IllegalStateException("Unsupported Object of type: " + value.getClass());
}
}
private static Object getValue(final Object value, final int valueType, final V8Map<Object> cache, final TypeAdapter adapter) {
Object adapterResult = adapter.adapt(valueType, value);
if (TypeAdapter.DEFAULT != adapterResult) {
return adapterResult;
}
switch (valueType) {
case V8Value.INTEGER:
case V8Value.DOUBLE:
case V8Value.BOOLEAN:
case V8Value.STRING:
return value;
case V8Value.V8_FUNCTION:
return IGNORE;
case V8Value.V8_ARRAY_BUFFER:
return new ArrayBuffer((V8ArrayBuffer) value);
case V8Value.V8_TYPED_ARRAY:
return new TypedArray((V8TypedArray) value);
case V8Value.V8_ARRAY:
return toList((V8Array) value, cache, adapter);
case V8Value.V8_OBJECT:
return toMap((V8Object) value, cache, adapter);
case V8Value.NULL:
return null;
case V8Value.UNDEFINED:
return V8.getUndefined();
default:
throw new IllegalStateException("Cannot convert type " + V8Value.getStringRepresentation(valueType));
}
}
private V8ObjectUtils() {
}
static class DefaultTypeAdapter implements TypeAdapter {
@Override
public Object adapt(final int type, final Object value) {
return TypeAdapter.DEFAULT;
}
}
static class ListWrapper {
private List<? extends Object> list;
public ListWrapper(final List<? extends Object> list) {
this.list = list;
}
@Override
public boolean equals(final Object obj) {
if (obj instanceof ListWrapper) {
return ((ListWrapper) obj).list == list;
}
return false;
}
@Override
public int hashCode() {
return System.identityHashCode(list);
}
}
}

176
fine-j2v8/src/main/java/com/eclipsesource/v8/utils/V8PropertyMap.java

@ -1,176 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.utils;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
/**
* A custom map is needed because the existing HashMaps
* do not allow self containment, and Hashtables do not
* allow nulls as values.
*
* This class is not considered API.
*/
class V8PropertyMap<V> implements Map<String, V> {
private Hashtable<String, V> map = new Hashtable<String, V>();
private Set<String> nulls = new HashSet<String>();
/*
* (non-Javadoc)
* @see java.util.Map#size()
*/
@Override
public int size() {
return map.size() + nulls.size();
}
/*
* (non-Javadoc)
* @see java.util.Map#isEmpty()
*/
@Override
public boolean isEmpty() {
return map.isEmpty() && nulls.isEmpty();
}
/*
* (non-Javadoc)
* @see java.util.Map#containsKey(java.lang.Object)
*/
@Override
public boolean containsKey(final Object key) {
return map.containsKey(key) || nulls.contains(key);
}
/*
* (non-Javadoc)
* @see java.util.Map#containsValue(java.lang.Object)
*/
@Override
public boolean containsValue(final Object value) {
if ((value == null) && !nulls.isEmpty()) {
return true;
} else if (value == null) {
return false;
}
return map.containsValue(value);
}
/*
* (non-Javadoc)
* @see java.util.Map#get(java.lang.Object)
*/
@Override
public V get(final Object key) {
if (nulls.contains(key)) {
return null;
}
return map.get(key);
}
/*
* (non-Javadoc)
* @see java.util.Map#put(java.lang.Object, java.lang.Object)
*/
@Override
public V put(final String key, final V value) {
if (value == null) {
if (map.containsKey(key)) {
map.remove(key);
}
nulls.add(key);
return null;
}
if (nulls.contains(key)) {
nulls.remove(key);
}
return map.put(key, value);
}
/*
* (non-Javadoc)
* @see java.util.Map#remove(java.lang.Object)
*/
@Override
public V remove(final Object key) {
if (nulls.contains(key)) {
nulls.remove(key);
return null;
}
return map.remove(key);
}
/*
* (non-Javadoc)
* @see java.util.Map#putAll(java.util.Map)
*/
@Override
public void putAll(final Map<? extends String, ? extends V> m) {
for (Entry<? extends String, ? extends V> entry : m.entrySet()) {
this.put(entry.getKey(), entry.getValue());
}
}
/*
* (non-Javadoc)
* @see java.util.Map#clear()
*/
@Override
public void clear() {
map.clear();
nulls.clear();
}
/*
* (non-Javadoc)
* @see java.util.Map#keySet()
*/
@Override
public Set<String> keySet() {
HashSet<String> result = new HashSet<String>(map.keySet());
result.addAll(nulls);
return result;
}
/*
* (non-Javadoc)
* @see java.util.Map#values()
*/
@Override
public Collection<V> values() {
ArrayList<V> result = new ArrayList<V>(map.values());
for (int i = 0; i < nulls.size(); i++) {
result.add(null);
}
return result;
}
/*
* (non-Javadoc)
* @see java.util.Map#entrySet()
*/
@Override
public Set<Entry<String, V>> entrySet() {
HashSet<Entry<String, V>> result = new HashSet<Map.Entry<String, V>>(map.entrySet());
for (String nullKey : nulls) {
result.add(new SimpleEntry<String, V>(nullKey, null));
}
return result;
}
}

29
fine-j2v8/src/main/java/com/eclipsesource/v8/utils/V8Runnable.java

@ -1,29 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.utils;
import com.eclipsesource.v8.V8;
/**
* Classes can implement this interface to execute arbitrary code on
* isolated V8 runtime on its own thread. Instances of classes that
* implement this interface can be passed to V8Thread.
*/
public interface V8Runnable {
/**
* Execute the code on the provided runtime.
*
* @param runtime The V8 runtime assigned to this runnable.
*/
public void run(final V8 runtime);
}

57
fine-j2v8/src/main/java/com/eclipsesource/v8/utils/V8Thread.java

@ -1,57 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.v8.utils;
import com.eclipsesource.v8.V8;
/**
* A Thread with its own V8 runtime. The thread will create a runtime,
* and execute a runnable on that runtime. When the thread ends,
* the runtime will be released.
*
* It's suggested that you *DO NOT* release the lock on the runtime.
* If the lock is released, you will need to ensure that the runtime
* is properly released.
*/
public class V8Thread extends Thread {
private final V8Runnable target;
private V8 runtime;
/**
* Create as new Thread with its own V8Runtime.
*
* @param target The code to execute with the given runtime.
*/
public V8Thread(final V8Runnable target) {
this.target = target;
}
/*
* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void run() {
runtime = V8.createV8Runtime();
try {
target.run(runtime);
} finally {
synchronized (this) {
if (runtime.getLocker().hasLock()) {
runtime.close();
runtime = null;
}
}
}
}
}

BIN
fine-j2v8/src/main/resources/libj2v8-linux-aarch_64.so

Binary file not shown.

BIN
fine-j2v8/src/main/resources/libj2v8-linux-x86_64.so

Binary file not shown.

BIN
fine-j2v8/src/main/resources/libj2v8-macosx-x86_64.dylib

Binary file not shown.

BIN
fine-j2v8/src/main/resources/libj2v8-windows-x86_64.dll

Binary file not shown.
Loading…
Cancel
Save