Browse Source

引入J2V8

bugfix/10.0
richie 6 years ago
parent
commit
d9529ff852
  1. 37
      fine-j2v8/src/com/eclipsesource/v8/JavaCallback.java
  2. 33
      fine-j2v8/src/com/eclipsesource/v8/JavaVoidCallback.java
  3. 216
      fine-j2v8/src/com/eclipsesource/v8/LibraryLoader.java
  4. 213
      fine-j2v8/src/com/eclipsesource/v8/NodeJS.java
  5. 34
      fine-j2v8/src/com/eclipsesource/v8/ReferenceHandler.java
  6. 24
      fine-j2v8/src/com/eclipsesource/v8/Releasable.java
  7. 1435
      fine-j2v8/src/com/eclipsesource/v8/V8.java
  8. 1127
      fine-j2v8/src/com/eclipsesource/v8/V8Array.java
  9. 103
      fine-j2v8/src/com/eclipsesource/v8/V8ArrayBuffer.java
  10. 83
      fine-j2v8/src/com/eclipsesource/v8/V8Function.java
  11. 70
      fine-j2v8/src/com/eclipsesource/v8/V8Locker.java
  12. 970
      fine-j2v8/src/com/eclipsesource/v8/V8Object.java
  13. 32
      fine-j2v8/src/com/eclipsesource/v8/V8ResultUndefined.java
  14. 27
      fine-j2v8/src/com/eclipsesource/v8/V8RuntimeException.java
  15. 24
      fine-j2v8/src/com/eclipsesource/v8/V8ScriptCompilationException.java
  16. 165
      fine-j2v8/src/com/eclipsesource/v8/V8ScriptException.java
  17. 40
      fine-j2v8/src/com/eclipsesource/v8/V8ScriptExecutionException.java
  18. 169
      fine-j2v8/src/com/eclipsesource/v8/V8TypedArray.java
  19. 289
      fine-j2v8/src/com/eclipsesource/v8/V8Value.java
  20. 55
      fine-j2v8/src/com/eclipsesource/v8/debug/BreakEvent.java
  21. 20
      fine-j2v8/src/com/eclipsesource/v8/debug/BreakHandler.java
  22. 24
      fine-j2v8/src/com/eclipsesource/v8/debug/CompileEvent.java
  23. 352
      fine-j2v8/src/com/eclipsesource/v8/debug/DebugHandler.java
  24. 34
      fine-j2v8/src/com/eclipsesource/v8/debug/EventData.java
  25. 24
      fine-j2v8/src/com/eclipsesource/v8/debug/ExceptionEvent.java
  26. 94
      fine-j2v8/src/com/eclipsesource/v8/debug/ExecutionState.java
  27. 89
      fine-j2v8/src/com/eclipsesource/v8/debug/ScriptBreakPoint.java
  28. 25
      fine-j2v8/src/com/eclipsesource/v8/debug/StepAction.java
  29. 40
      fine-j2v8/src/com/eclipsesource/v8/debug/mirror/ArrayMirror.java
  30. 33
      fine-j2v8/src/com/eclipsesource/v8/debug/mirror/BooleanMirror.java
  31. 215
      fine-j2v8/src/com/eclipsesource/v8/debug/mirror/Frame.java
  32. 38
      fine-j2v8/src/com/eclipsesource/v8/debug/mirror/FunctionMirror.java
  33. 280
      fine-j2v8/src/com/eclipsesource/v8/debug/mirror/Mirror.java
  34. 35
      fine-j2v8/src/com/eclipsesource/v8/debug/mirror/NullMirror.java
  35. 34
      fine-j2v8/src/com/eclipsesource/v8/debug/mirror/NumberMirror.java
  36. 98
      fine-j2v8/src/com/eclipsesource/v8/debug/mirror/ObjectMirror.java
  37. 59
      fine-j2v8/src/com/eclipsesource/v8/debug/mirror/PropertiesArray.java
  38. 52
      fine-j2v8/src/com/eclipsesource/v8/debug/mirror/PropertyMirror.java
  39. 156
      fine-j2v8/src/com/eclipsesource/v8/debug/mirror/Scope.java
  40. 96
      fine-j2v8/src/com/eclipsesource/v8/debug/mirror/SourceLocation.java
  41. 34
      fine-j2v8/src/com/eclipsesource/v8/debug/mirror/StringMirror.java
  42. 35
      fine-j2v8/src/com/eclipsesource/v8/debug/mirror/UndefinedMirror.java
  43. 40
      fine-j2v8/src/com/eclipsesource/v8/debug/mirror/ValueMirror.java
  44. 138
      fine-j2v8/src/com/eclipsesource/v8/utils/MemoryManager.java
  45. 256
      fine-j2v8/src/com/eclipsesource/v8/utils/V8Executor.java
  46. 175
      fine-j2v8/src/com/eclipsesource/v8/utils/V8Map.java
  47. 649
      fine-j2v8/src/com/eclipsesource/v8/utils/V8ObjectUtils.java
  48. 176
      fine-j2v8/src/com/eclipsesource/v8/utils/V8PropertyMap.java
  49. 29
      fine-j2v8/src/com/eclipsesource/v8/utils/V8Runnable.java
  50. 57
      fine-j2v8/src/com/eclipsesource/v8/utils/V8Thread.java
  51. 109
      fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/ArrayBuffer.java
  52. 79
      fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/Float32Array.java
  53. 79
      fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/Float64Array.java
  54. 79
      fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/Int16Array.java
  55. 75
      fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/Int32Array.java
  56. 78
      fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/Int8Array.java
  57. 58
      fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/TypedArray.java
  58. 79
      fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/UInt16Array.java
  59. 79
      fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/UInt32Array.java
  60. 78
      fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/UInt8Array.java
  61. 87
      fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/UInt8ClampedArray.java
  62. BIN
      fine-j2v8/src/libj2v8_linux_x86_64.so
  63. BIN
      fine-j2v8/src/libj2v8_macosx_x86_64.dylib
  64. BIN
      fine-j2v8/src/libj2v8_win32_x86.dll
  65. BIN
      fine-j2v8/src/libj2v8_win32_x86_64.dll

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

@ -0,0 +1,37 @@
/*******************************************************************************
* 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/com/eclipsesource/v8/JavaVoidCallback.java

@ -0,0 +1,33 @@
/*******************************************************************************
* 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);
}

216
fine-j2v8/src/com/eclipsesource/v8/LibraryLoader.java

@ -0,0 +1,216 @@
/*******************************************************************************
* 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.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
class LibraryLoader {
static final String SEPARATOR;
static final String DELIMITER;
static final String SWT_LIB_DIR = ".j2v8";
static {
DELIMITER = System.getProperty("line.separator"); //$NON-NLS-1$
SEPARATOR = System.getProperty("file.separator"); //$NON-NLS-1$
}
private static String computeLibraryShortName() {
String base = "j2v8";
String osSuffix = getOS();
String archSuffix = getArchSuffix();
return base + "_" + osSuffix + "_" + archSuffix;
}
private static String computeLibraryFullName() {
return "lib" + computeLibraryShortName() + "." + getOSFileExtension();
}
static void loadLibrary(final String tempDirectory) {
if ( isAndroid() ) {
System.loadLibrary("j2v8");
return;
}
StringBuffer message = new StringBuffer();
String libShortName = computeLibraryShortName();
String libFullName = computeLibraryFullName();
String ideLocation = System.getProperty("user.dir") + SEPARATOR + "jni" + SEPARATOR + computeLibraryFullName();
String path = null;
/* Try loading library from java library path */
if (load(libShortName, message)) {
return;
}
/* Try loading library from the IDE location */
if (new File(ideLocation).exists()) {
if (load(ideLocation, message)) {
return;
}
}
if (tempDirectory != null) {
path = tempDirectory;
} else {
path = System.getProperty("user.home"); //$NON-NLS-1$
}
if (extract(path + SEPARATOR + libFullName, libFullName, 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(final String fileName, final String mappedName, final StringBuffer message) {
FileOutputStream os = null;
InputStream is = null;
File file = new File(fileName);
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(fileName, 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 (isWindows()) {
return;
}
try {
Runtime.getRuntime().exec(new String[] { "chmod", permision, path }).waitFor(); //$NON-NLS-1$
} catch (Throwable e) {
}
}
static String getOsName() {
return System.getProperty("os.name") + System.getProperty("java.specification.vendor");
}
static boolean isWindows() {
return getOsName().startsWith("Windows");
}
static boolean isMac() {
return getOsName().startsWith("Mac");
}
static boolean isLinux() {
return getOsName().startsWith("Linux");
}
static boolean isNativeClient() {
return getOsName().startsWith("nacl");
}
static boolean isAndroid() {
return getOsName().contains("Android");
}
static String getArchSuffix() {
String arch = System.getProperty("os.arch");
if (arch.equals("i686")) {
return "x86";
} else if (arch.equals("amd64")) {
return "x86_64";
} else if (arch.equals("nacl")) {
return "armv7l";
} else if (arch.equals("aarch64")) {
return "armv7l";
}
return arch;
}
static String getOSFileExtension() {
if (isWindows()) {
return "dll";
} else if (isMac()) {
return "dylib";
} else if (isLinux()) {
return "so";
} else if (isNativeClient()) {
return "so";
}
throw new UnsatisfiedLinkError("Unsupported platform: " + getOsName());
}
static String getOS() {
if (isWindows()) {
return "win32";
} else if (isMac()) {
return "macosx";
} else if (isLinux() && !isAndroid()) {
return "linux";
} else if (isAndroid()) {
return "android";
}
throw new UnsatisfiedLinkError("Unsupported platform: " + getOsName());
}
}

213
fine-j2v8/src/com/eclipsesource/v8/NodeJS.java

@ -0,0 +1,213 @@
/*******************************************************************************
* 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 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);
}
/**
* 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.release();
}
}
}, 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.release();
}
if (!v8.isReleased()) {
v8.release();
}
}
/**
* 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.release();
}
}
/**
* 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.release();
}
}
});
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;
}
}

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

@ -0,0 +1,34 @@
/*******************************************************************************
* 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);
}

24
fine-j2v8/src/com/eclipsesource/v8/Releasable.java

@ -0,0 +1,24 @@
/*******************************************************************************
* 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;
/**
* An interface used to denote all V8 Classes which can be released.
*/
public interface Releasable {
/**
* Release the underlying resources. Once an object is released
* it typically cannot be used again.
*/
void release();
}

1435
fine-j2v8/src/com/eclipsesource/v8/V8.java

File diff suppressed because it is too large Load Diff

1127
fine-j2v8/src/com/eclipsesource/v8/V8Array.java

File diff suppressed because it is too large Load Diff

103
fine-j2v8/src/com/eclipsesource/v8/V8ArrayBuffer.java

@ -0,0 +1,103 @@
/*******************************************************************************
* 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 {
private 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());
}
/**
* Creates a new V8ArrayBuffer with the provided ByteBuffer as the backing store.
* The ByteBuffer must be allocated as a DirectBuffer. If the ByteBuffer is not
* a DirectBuffer an IllegalArgumentException will be thrown.
*
* @param v8 The runtime on which to create the ArrayBuffer
* @param byteBuffer The ByteBuffer to use as the backing store. The ByteBuffer must
* be allocated as a DirectBuffer.
*/
public V8ArrayBuffer(final V8 v8, final ByteBuffer byteBuffer) {
super(v8);
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() {
return (V8ArrayBuffer) super.twin();
}
/**
* Returns the backing store used for this ArrayBuffer.
*
* @return The backing store used for this ArrayBuffer.
*/
public ByteBuffer getBackingStore() {
v8.checkReleased();
v8.checkThread();
return byteBuffer;
}
}

83
fine-j2v8/src/com/eclipsesource/v8/V8Function.java

@ -0,0 +1,83 @@
/*******************************************************************************
* 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);
}
@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.
*/
public Object call(V8Object receiver, final V8Array parameters) {
v8.checkThread();
checkReleased();
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);
}
}

70
fine-j2v8/src/com/eclipsesource/v8/V8Locker.java

@ -0,0 +1,70 @@
/*******************************************************************************
* 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;
V8Locker() {
acquire();
}
/**
* Acquire the lock if it's currently not acquired by another
* thread. If it's current 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");
}
thread = Thread.currentThread();
}
/**
* 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.
*/
public synchronized void release() {
checkThread();
thread = null;
}
/**
* 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 ((thread != Thread.currentThread())) {
throw new Error("Invalid V8 thread access");
}
}
/**
* 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();
}
}

970
fine-j2v8/src/com/eclipsesource/v8/V8Object.java

@ -0,0 +1,970 @@
/*******************************************************************************
* 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;
import java.lang.reflect.Method;
/**
* The concrete class for all V8 Objects. V8Objects are
* JavaScript objects accessible in java. Specialized
* subclasses exist for V8Arrays and V8Functions.
*
* V8Object are JavaScript object with key value pairs.
* Specific get methods exist to access values as primitives.
* General get methods also exist, which return Java Objects
* and can be casted to the correct subclass.
*
* V8Object have native resources and must be released
* when they are no longer need in Java.
*/
public class V8Object extends V8Value {
/**
* Create a new V8Object and associate it with a runtime.
* Once created, it must be released.
*
* @param v8 The runtime on which to associate the V8Object.
*/
public V8Object(final V8 v8) {
this(v8, null);
}
protected V8Object(final V8 v8, final Object data) {
super(v8);
if (v8 != null) {
this.v8.checkThread();
initialize(this.v8.getV8RuntimePtr(), data);
}
}
protected V8Object() {
}
@Override
protected V8Value createTwin() {
return new V8Object(v8);
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Value#twin()
*/
@Override
public V8Object twin() {
return (V8Object) super.twin();
}
/**
* Determine if a key/value pair with this key exists in
* the Object.
*
* @param key The key to check
* @return True if the key exists, false otherwise.
*/
public boolean contains(final String key) {
v8.checkThread();
checkReleased();
return v8.contains(v8.getV8RuntimePtr(), objectHandle, key);
}
/**
* Returns all the keys associated with this JavaScript Object.
* Keys associated with the objects prototype are not returned.
*
* @return The keys associated with this JavaScript Object.
*/
public String[] getKeys() {
v8.checkThread();
checkReleased();
return v8.getKeys(v8.getV8RuntimePtr(), objectHandle);
}
/**
* Returns the type of the value associated with this Key, or
* UNDEFINED if the key does not exist. Types are specified as
* integer constants. The types are all defined in V8Value.
*
* @param key The key whose type to lookup.
*
* @return The Type of the value associated with this key
*/
public int getType(final String key) {
v8.checkThread();
checkReleased();
return v8.getType(v8.getV8RuntimePtr(), objectHandle, key);
}
/**
* Returns the value associated with this key. Values are Java Objects.
* If the value is a primitive, its boxed type is returned. If the
* value is a V8Value, it must be released.
*
* @param key The key whose value to return.
*
* @return The value associated with this key.
*/
public Object get(final String key) {
v8.checkThread();
checkReleased();
return v8.get(v8.getV8RuntimePtr(), V8_OBJECT, objectHandle, key);
}
/**
* Returns the integer value associated with this key. If the value
* associated with this key does not exist, or if it's not an integer, then
* V8ResultUndefined exception is thrown.
*
* @param key The key whose value to return.
*
* @return The integer value associated with this key, or V8ResultUndefined
* if the key does not exist or the value is not an integer.
*/
public int getInteger(final String key) {
v8.checkThread();
checkReleased();
return v8.getInteger(v8.getV8RuntimePtr(), objectHandle, key);
}
/**
* Returns the boolean value associated with this key. If the value
* associated with this key does not exist, or if it's not a boolean, then
* V8ResultUndefined exception is thrown.
*
* @param key The key whose value to return.
*
* @return The boolean value associated with this key, or V8ResultUndefined
* if the key does not exist or the value is not a boolean.
*/
public boolean getBoolean(final String key) {
v8.checkThread();
checkReleased();
return v8.getBoolean(v8.getV8RuntimePtr(), objectHandle, key);
}
/**
* Returns the double value associated with this key. If the value
* associated with this key does not exist, or if it's not a double, then
* V8ResultUndefined exception is thrown.
*
* @param key The key whose value to return.
*
* @return The double value associated with this key, or V8ResultUndefined
* if the key does not exist or the value is not a double.
*/
public double getDouble(final String key) {
v8.checkThread();
checkReleased();
return v8.getDouble(v8.getV8RuntimePtr(), objectHandle, key);
}
/**
* Returns the String value associated with this key. If the value
* associated with this key does not exist, or if it's not a String, then
* V8ResultUndefined exception is thrown.
*
* @param key The key whose value to return.
*
* @return The String value associated with this key, or V8ResultUndefined
* if the key does not exist or the value is not a String.
*/
public String getString(final String key) {
v8.checkThread();
checkReleased();
return v8.getString(v8.getV8RuntimePtr(), objectHandle, key);
}
/**
* Returns the V8Array value associated with this key. If the value
* associated with this key does not exist then UNDEFINED is returned.
* If the value exists but is not an array then
* V8ResultUndefined exception is thrown.
*
* @param key The key whose value to return.
*
* @return The V8Array value associated with this key.
*/
public V8Array getArray(final String key) {
v8.checkThread();
checkReleased();
Object result = v8.get(v8.getV8RuntimePtr(), V8_ARRAY, objectHandle, key);
if ((result == null) || (result instanceof V8Array)) {
return (V8Array) result;
}
throw new V8ResultUndefined();
}
/**
* Returns the V8Object value associated with this key. If the value
* associated with this key does not exist then UNDEFINED is returned.
* If the value exists but is not an JS Object then
* V8ResultUndefined exception is thrown.
*
* @param key The key whose value to return.
*
* @return The V8Object value associated with this key.
*/
public V8Object getObject(final String key) {
v8.checkThread();
checkReleased();
Object result = v8.get(v8.getV8RuntimePtr(), V8_OBJECT, objectHandle, key);
if ((result == null) || (result instanceof V8Object)) {
return (V8Object) result;
}
throw new V8ResultUndefined();
}
/**
* Invoke a JavaScript function and return the result as a integer. If the
* result is not an integer, or does not exist, then V8ResultUndefined is thrown.
*
* @param name The name of the JS Function to call.
*
* @param parameters The parameters to pass to the function. Parameters must be released.
*
* @return An integer representing the result of the function call or V8ResultUndefined
* if the result is not an integer.
*/
public int executeIntegerFunction(final String name, final V8Array parameters) {
v8.checkThread();
checkReleased();
long parametersHandle = parameters == null ? 0 : parameters.getHandle();
return v8.executeIntegerFunction(v8.getV8RuntimePtr(), getHandle(), name, parametersHandle);
}
/**
* Invoke a JavaScript function and return the result as a double. If the
* result is not a double, or does not exist, then V8ResultUndefined is thrown.
*
* @param name The name of the JS Function to call.
*
* @param parameters The parameters to pass to the function. Parameters must be released.
*
* @return A double representing the result of the function call or V8ResultUndefined
* if the result is not a double.
*/
public double executeDoubleFunction(final String name, final V8Array parameters) {
v8.checkThread();
checkReleased();
long parametersHandle = parameters == null ? 0 : parameters.getHandle();
return v8.executeDoubleFunction(v8.getV8RuntimePtr(), getHandle(), name, parametersHandle);
}
/**
* Invoke a JavaScript function and return the result as a String. If the
* result is not a String, or does not exist, then V8ResultUndefined is thrown.
*
* @param name The name of the JS Function to call.
*
* @param parameters The parameters to pass to the function. Parameters must be released.
*
* @return A String representing the result of the function call or V8ResultUndefined
* if the result is not a String.
*/
public String executeStringFunction(final String name, final V8Array parameters) {
v8.checkThread();
checkReleased();
long parametersHandle = parameters == null ? 0 : parameters.getHandle();
return v8.executeStringFunction(v8.getV8RuntimePtr(), getHandle(), name, parametersHandle);
}
/**
* Invoke a JavaScript function and return the result as a boolean. If the
* result is not a boolean, or does not exist, then V8ResultUndefined is thrown.
*
* @param name The name of the JS Function to call.
*
* @param parameters The parameters to pass to the function. Parameters must be released.
*
* @return A boolean representing the result of the function call or V8ResultUndefined
* if the result is not a boolean.
*/
public boolean executeBooleanFunction(final String name, final V8Array parameters) {
v8.checkThread();
checkReleased();
long parametersHandle = parameters == null ? 0 : parameters.getHandle();
return v8.executeBooleanFunction(v8.getV8RuntimePtr(), getHandle(), name, parametersHandle);
}
/**
* Invoke a JavaScript function and return the result as a V8Array. If the
* result is not a V8Array then V8ResultUndefined is thrown.
*
* @param name The name of the JS Function to call.
*
* @param parameters The parameters to pass to the function. Parameters must be released.
*
* @return A V8Array representing the result of the function call or V8ResultUndefined
* if the result is not a V8Array. The result must be released.
*/
public V8Array executeArrayFunction(final String name, final V8Array parameters) {
v8.checkThread();
checkReleased();
long parametersHandle = parameters == null ? 0 : parameters.getHandle();
Object result = v8.executeFunction(v8.getV8RuntimePtr(), V8_ARRAY, objectHandle, name, parametersHandle);
if (result instanceof V8Array) {
return (V8Array) result;
}
throw new V8ResultUndefined();
}
/**
* Invoke a JavaScript function and return the result as a V8Object. If the
* result is not a V8Object then V8ResultUndefined is thrown.
*
* @param name The name of the JS Function to call.
*
* @param parameters The parameters to pass to the function. Parameters must be released.
*
* @return A V8Object representing the result of the function call or V8ResultUndefined
* if the result is not a V8Object. The result must be released.
*/
public V8Object executeObjectFunction(final String name, final V8Array parameters) {
v8.checkThread();
checkReleased();
long parametersHandle = parameters == null ? 0 : parameters.getHandle();
Object result = v8.executeFunction(v8.getV8RuntimePtr(), V8_OBJECT, objectHandle, name, parametersHandle);
if (result instanceof V8Object) {
return (V8Object) result;
}
throw new V8ResultUndefined();
}
/**
* Invoke a JavaScript function and return the result as a Java Object.
*
* @param name The name of the JS Function to call.
*
* @param parameters The parameters to pass to the function. Parameters must be released.
*
* @return A Java Object representing the result of the function call.
*/
public Object executeFunction(final String name, final V8Array parameters) {
v8.checkThread();
checkReleased();
long parametersHandle = parameters == null ? 0 : parameters.getHandle();
return v8.executeFunction(v8.getV8RuntimePtr(), UNKNOWN, objectHandle, name, parametersHandle);
}
/**
* Invoke a JavaScript function and return the result as a Java Object.
*
* @param name The name of the JS Function to call
* @return The result of this JS Function
*/
public Object executeJSFunction(final String name) {
return executeFunction(name, null);
}
/**
* Invoke a JavaScript function and return the result as a Java Object.
*
* @param name The name of the JS Function to call.
* @param parameters The parameters to pass to the function.
* @return A Java Object representing the result of the function call.
*/
public Object executeJSFunction(final String name, final Object... parameters) {
if (parameters == null) {
return executeFunction(name, null);
}
V8Array parameterArray = new V8Array(v8.getRuntime());
try {
for (Object object : parameters) {
if (object == null) {
parameterArray.pushNull();
} else if (object instanceof V8Value) {
parameterArray.push((V8Value) object);
} else if (object instanceof Integer) {
parameterArray.push((Integer) object);
} else if (object instanceof Double) {
parameterArray.push((Double) object);
} else if (object instanceof Long) {
parameterArray.push(((Long) object).doubleValue());
} else if (object instanceof Float) {
parameterArray.push(((Float) object).floatValue());
} else if (object instanceof Boolean) {
parameterArray.push((Boolean) object);
} else if (object instanceof String) {
parameterArray.push((String) object);
} else {
throw new IllegalArgumentException("Unsupported Object of type: " + object.getClass());
}
}
return executeFunction(name, parameterArray);
} finally {
parameterArray.release();
}
}
/**
* Invokes a JavaScript function which does not return a result.
*
* @param name The name of the JS Function to call.
*
* @param parameters The parameters to pass to the function. Parameters must be released.
*/
public void executeVoidFunction(final String name, final V8Array parameters) {
v8.checkThread();
checkReleased();
long parametersHandle = parameters == null ? 0 : parameters.getHandle();
v8.executeVoidFunction(v8.getV8RuntimePtr(), objectHandle, name, parametersHandle);
}
/**
* Adds a key value pair to the receiver where the value is an integer.
*
* @param key The key to associate the value with.
* @param value The value to add.
*
* @return The receiver.
*/
public V8Object add(final String key, final int value) {
v8.checkThread();
checkReleased();
v8.add(v8.getV8RuntimePtr(), objectHandle, key, value);
return this;
}
/**
* Adds a key value pair to the receiver where the value is a boolean.
*
* @param key The key to associate the value with.
* @param value The value to add.
*
* @return The receiver.
*/
public V8Object add(final String key, final boolean value) {
v8.checkThread();
checkReleased();
v8.add(v8.getV8RuntimePtr(), objectHandle, key, value);
return this;
}
/**
* Adds a key value pair to the receiver where the value is a double.
*
* @param key The key to associate the value with.
* @param value The value to add.
*
* @return The receiver.
*/
public V8Object add(final String key, final double value) {
v8.checkThread();
checkReleased();
v8.add(v8.getV8RuntimePtr(), objectHandle, key, value);
return this;
}
/**
* Adds a key value pair to the receiver where the value is a String.
*
* @param key The key to associate the value with.
* @param value The value to add.
*
* @return The receiver.
*/
public V8Object add(final String key, final String value) {
v8.checkThread();
checkReleased();
if (value == null) {
v8.addNull(v8.getV8RuntimePtr(), objectHandle, key);
} else if (value.equals(V8.getUndefined())) {
v8.addUndefined(v8.getV8RuntimePtr(), objectHandle, key);
} else {
v8.add(v8.getV8RuntimePtr(), objectHandle, key, value);
}
return this;
}
/**
* Adds a key value pair to the receiver where the value is a V8Value.
*
* @param key The key to associate the value with.
* @param value The value to add.
*
* @return The receiver.
*/
public V8Object add(final String key, final V8Value value) {
v8.checkThread();
checkReleased();
if (value == null) {
v8.addNull(v8.getV8RuntimePtr(), objectHandle, key);
} else if (value.equals(V8.getUndefined())) {
v8.addUndefined(v8.getV8RuntimePtr(), objectHandle, key);
} else {
v8.addObject(v8.getV8RuntimePtr(), objectHandle, key, value.getHandle());
}
return this;
}
/**
* Associate UNDEFINED with the given key.
*
* @param key The key to associate UNDEFINED with.
*
* @return The receiver.
*/
public V8Object addUndefined(final String key) {
v8.checkThread();
checkReleased();
v8.addUndefined(v8.getV8RuntimePtr(), objectHandle, key);
return this;
}
/**
* Associate NULL with the given key.
*
* @param key The key to associate NULL with.
*
* @return The receiver.
*/
public V8Object addNull(final String key) {
v8.checkThread();
checkReleased();
v8.addNull(v8.getV8RuntimePtr(), objectHandle, key);
return this;
}
/**
* Sets the prototype of the receiver.
*
* @param value The prototype to associate with this V8Object.
*
* @return The receiver.
*/
public V8Object setPrototype(final V8Object value) {
v8.checkThread();
checkReleased();
v8.setPrototype(v8.getV8RuntimePtr(), objectHandle, value.getHandle());
return this;
}
/**
* Register a Java method as a JavaScript function. When the JS Function is invoked
* the Java method will be called.
*
* @param callback The JavaCallback to call when the JSFunction is invoked.
* @param jsFunctionName The name of the JSFunction.
*
* @return The receiver.
*/
public V8Object registerJavaMethod(final JavaCallback callback, final String jsFunctionName) {
v8.checkThread();
checkReleased();
v8.registerCallback(callback, getHandle(), jsFunctionName);
return this;
}
/**
* Register a void Java method as a JavaScript function. When the JS Function is invoked
* the Java method will be called.
*
* @param callback The JavaVoidCallback to call when the JSFunction is invoked.
* @param jsFunctionName The name of the JSFunction.
*
* @return The receiver.
*/
public V8Object registerJavaMethod(final JavaVoidCallback callback, final String jsFunctionName) {
v8.checkThread();
checkReleased();
v8.registerVoidCallback(callback, getHandle(), jsFunctionName);
return this;
}
/**
* Register a Java method reflectively given it's name a signature.
*
* @param object The Java Object on which the method is defined.
* @param methodName The name of the method to register.
* @param jsFunctionName The name of the JavaScript function to register the
* method with.
* @param parameterTypes The parameter types of the method.
*
* @return The receiver.
*/
public V8Object registerJavaMethod(final Object object, final String methodName, final String jsFunctionName, final Class<?>[] parameterTypes) {
return registerJavaMethod(object, methodName, jsFunctionName, parameterTypes, false);
}
/**
* Register a Java method reflectively given it's name a signature. The option to include
* the JS Object in the callback can be specified by setting includeReceiver true.
*
* @param object The Java Object on which the method is defined.
* @param methodName The name of the method to register.
* @param jsFunctionName The name of the JavaScript function to register the
* method with.
* @param parameterTypes The parameter types of the method.
* @param includeReceiver True if the first parameter should include the JS Object,
* false otherwise.
*
* @return The receiver.
*/
public V8Object registerJavaMethod(final Object object, final String methodName, final String jsFunctionName, final Class<?>[] parameterTypes, final boolean includeReceiver) {
v8.checkThread();
checkReleased();
try {
Method method = object.getClass().getMethod(methodName, parameterTypes);
method.setAccessible(true);
v8.registerCallback(object, method, getHandle(), jsFunctionName, includeReceiver);
} catch (NoSuchMethodException e) {
throw new IllegalStateException(e);
} catch (SecurityException e) {
throw new IllegalStateException(e);
}
return this;
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
v8.checkThread();
checkReleased();
return v8.toString(v8.getV8RuntimePtr(), getHandle());
}
static class Undefined extends V8Object {
public Undefined() {
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Value#isUndefined()
*/
@Override
public boolean isUndefined() {
return true;
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Value#isReleased()
*/
@Override
public boolean isReleased() {
return false;
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Value#release()
*/
@Override
public void release() {
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#twin()
*/
@Override
public Undefined twin() {
return (Undefined) super.twin();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#toString()
*/
@Override
public String toString() {
return "undefined";
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Value#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object that) {
if ((that instanceof V8Object) && ((V8Object) that).isUndefined()) {
return true;
}
return false;
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Value#hashCode()
*/
@Override
public int hashCode() {
return 919;
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#add(java.lang.String, boolean)
*/
@Override
public V8Object add(final String key, final boolean value) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Value#getRuntime()
*/
@Override
public V8 getRuntime() {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#add(java.lang.String, double)
*/
@Override
public V8Object add(final String key, final double value) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#add(java.lang.String, int)
*/
@Override
public V8Object add(final String key, final int value) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#executeJSFunction(java.lang.String, java.lang.Object[])
*/
@Override
public Object executeJSFunction(final String name, final Object... parameters) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#executeFunction(java.lang.String, com.eclipsesource.v8.V8Array)
*/
@Override
public Object executeFunction(final String name, final V8Array parameters) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#add(java.lang.String, java.lang.String)
*/
@Override
public V8Object add(final String key, final String value) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#add(java.lang.String, com.eclipsesource.v8.V8Value)
*/
@Override
public V8Object add(final String key, final V8Value value) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#addUndefined(java.lang.String)
*/
@Override
public V8Object addUndefined(final String key) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#contains(java.lang.String)
*/
@Override
public boolean contains(final String key) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#executeArrayFunction(java.lang.String, com.eclipsesource.v8.V8Array)
*/
@Override
public V8Array executeArrayFunction(final String name, final V8Array parameters) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#executeBooleanFunction(java.lang.String, com.eclipsesource.v8.V8Array)
*/
@Override
public boolean executeBooleanFunction(final String name, final V8Array parameters) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#executeDoubleFunction(java.lang.String, com.eclipsesource.v8.V8Array)
*/
@Override
public double executeDoubleFunction(final String name, final V8Array parameters) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#executeIntegerFunction(java.lang.String, com.eclipsesource.v8.V8Array)
*/
@Override
public int executeIntegerFunction(final String name, final V8Array parameters) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#executeObjectFunction(java.lang.String, com.eclipsesource.v8.V8Array)
*/
@Override
public V8Object executeObjectFunction(final String name, final V8Array parameters) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#executeStringFunction(java.lang.String, com.eclipsesource.v8.V8Array)
*/
@Override
public String executeStringFunction(final String name, final V8Array parameters) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#executeVoidFunction(java.lang.String, com.eclipsesource.v8.V8Array)
*/
@Override
public void executeVoidFunction(final String name, final V8Array parameters) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#getArray(java.lang.String)
*/
@Override
public V8Array getArray(final String key) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#getBoolean(java.lang.String)
*/
@Override
public boolean getBoolean(final String key) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#getDouble(java.lang.String)
*/
@Override
public double getDouble(final String key) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#getInteger(java.lang.String)
*/
@Override
public int getInteger(final String key) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#getKeys()
*/
@Override
public String[] getKeys() {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#getObject(java.lang.String)
*/
@Override
public V8Object getObject(final String key) throws V8ResultUndefined {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#getString(java.lang.String)
*/
@Override
public String getString(final String key) throws V8ResultUndefined {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#getType(java.lang.String)
*/
@Override
public int getType(final String key) throws V8ResultUndefined {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#registerJavaMethod(com.eclipsesource.v8.JavaCallback, java.lang.String)
*/
@Override
public V8Object registerJavaMethod(final JavaCallback callback, final String jsFunctionName) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#registerJavaMethod(com.eclipsesource.v8.JavaVoidCallback, java.lang.String)
*/
@Override
public V8Object registerJavaMethod(final JavaVoidCallback callback, final String jsFunctionName) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#registerJavaMethod(java.lang.Object, java.lang.String, java.lang.String, java.lang.Class[], boolean)
*/
@Override
public V8Object registerJavaMethod(final Object object, final String methodName, final String jsFunctionName, final Class<?>[] parameterTypes, final boolean includeReceiver) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.V8Object#setPrototype(com.eclipsesource.v8.V8Object)
*/
@Override
public V8Object setPrototype(final V8Object value) {
throw new UnsupportedOperationException();
}
}
}

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

@ -0,0 +1,32 @@
/*******************************************************************************
* 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/com/eclipsesource/v8/V8RuntimeException.java

@ -0,0 +1,27 @@
/*******************************************************************************
* 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/com/eclipsesource/v8/V8ScriptCompilationException.java

@ -0,0 +1,24 @@
/*******************************************************************************
* 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/com/eclipsesource/v8/V8ScriptException.java

@ -0,0 +1,165 @@
/*******************************************************************************
* 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/com/eclipsesource/v8/V8ScriptExecutionException.java

@ -0,0 +1,40 @@
/*******************************************************************************
* 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);
}
}

169
fine-j2v8/src/com/eclipsesource/v8/V8TypedArray.java

@ -0,0 +1,169 @@
/*******************************************************************************
* 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;
/**
* 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);
}
/**
* 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");
}
/**
* Returns the underlying ByteBuffer used to back this TypedArray.
*
* @return The ByteBuffer used as the backing store for this TypedArray
*/
public ByteBuffer getByteBuffer() {
V8ArrayBuffer buffer = getBuffer();
try {
return buffer.getBackingStore();
} finally {
buffer.release();
}
}
@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.getStringRepresentaion(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.getStringRepresentaion(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.getBackingStore().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));
}
}
@Override
protected V8Value createTwin() {
return new V8TypedArray(v8);
}
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;
}
}
}

289
fine-j2v8/src/com/eclipsesource/v8/V8Value.java

@ -0,0 +1,289 @@
/*******************************************************************************
* 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 released. The rules for releasing resources is as
* follows:
*
* 1. If you created it, you must release 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 release 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.
*/
public static String getStringRepresentaion(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);
}
}
/**
* 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;
}
/**
* 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 released 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;
}
/**
* Releases the native resources associated with this V8Value.
*/
@Override
public void release() {
v8.checkThread();
if (!released) {
try {
v8.releaseObjRef(this);
} finally {
released = true;
v8.release(v8.getV8RuntimePtr(), objectHandle);
}
}
}
/**
* 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/com/eclipsesource/v8/debug/BreakEvent.java

@ -0,0 +1,55 @@
/*******************************************************************************
* 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/com/eclipsesource/v8/debug/BreakHandler.java

@ -0,0 +1,20 @@
/*******************************************************************************
* 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/com/eclipsesource/v8/debug/CompileEvent.java

@ -0,0 +1,24 @@
/*******************************************************************************
* 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);
}
}

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

@ -0,0 +1,352 @@
/*******************************************************************************
* 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.release();
}
}
/**
* 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.release();
}
}
/**
* 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.release();
}
}
/**
* 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.release();
}
}
/**
* 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.release();
}
}
/**
* 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.release();
}
}
/**
* 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.release();
}
}
return result;
} finally {
breakPoints.release();
}
}
/**
* 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.release();
if (scriptBreakPoint != null) {
scriptBreakPoint.release();
}
}
}
/**
* 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.release();
}
}
@Override
public void release() {
debugObject.release();
}
private void setupDebugObject(final V8 runtime) {
V8Object outerDebug = runtime.getObject(DEBUG_OBJECT_NAME);
try {
debugObject = outerDebug.getObject(V8_DEBUG_OBJECT);
} finally {
outerDebug.release();
}
}
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).push(debugHandler);
debugObject.executeFunction(SET_LISTENER, parameters);
} finally {
if ((debugHandler != null) && !debugHandler.isReleased()) {
debugHandler.release();
}
if ((parameters != null) && !parameters.isReleased()) {
parameters.release();
}
}
}
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();
}
}
}
}

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

@ -0,0 +1,34 @@
/*******************************************************************************
* 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 release() {
if (!v8Object.isReleased()) {
v8Object.release();
}
}
}

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

@ -0,0 +1,24 @@
/*******************************************************************************
* 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);
}
}

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

@ -0,0 +1,94 @@
/*******************************************************************************
* 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.release();
}
}
/**
* 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.release();
if (frame != null) {
frame.release();
}
}
}
@Override
public void release() {
if ((v8Object != null) && !v8Object.isReleased()) {
v8Object.release();
v8Object = null;
}
}
}

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

@ -0,0 +1,89 @@
/*******************************************************************************
* 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.release();
}
}
/**
* 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 release() {
if ((v8Object != null) && !v8Object.isReleased()) {
v8Object.release();
v8Object = null;
}
}
}

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

@ -0,0 +1,25 @@
/*******************************************************************************
* 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;
}
}

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

@ -0,0 +1,40 @@
/*******************************************************************************
* 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/com/eclipsesource/v8/debug/mirror/BooleanMirror.java

@ -0,0 +1,33 @@
/*******************************************************************************
* 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);
}
}

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

@ -0,0 +1,215 @@
/*******************************************************************************
* 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 END = "end";
private static final String START = "start";
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);
try {
V8Object scriptObject = (V8Object) sourceLocation.get(SCRIPT);
String scriptName = scriptObject.getString(NAME);
scriptObject.release();
return new SourceLocation(scriptName,
sourceLocation.getInteger(POSITION),
sourceLocation.getInteger(LINE),
sourceLocation.getInteger(COLUMN),
sourceLocation.getInteger(START),
sourceLocation.getInteger(END));
} finally {
sourceLocation.release();
}
}
/**
* 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.release();
}
}
/**
* 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.release();
if (result != null) {
result.release();
}
}
}
/**
* 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.release();
if (result != null) {
result.release();
}
}
}
/**
* 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.release();
}
}
/**
* 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.release();
if (scope != null) {
scope.release();
}
}
}
/**
* 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.release();
}
}
}
@Override
public boolean isFrame() {
return true;
}
}

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

@ -0,0 +1,38 @@
/*******************************************************************************
* 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 {
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);
}
@Override
public boolean isFunction() {
return true;
}
}

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

@ -0,0 +1,280 @@
/*******************************************************************************
* 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;
}
@Override
public void release() {
if ((v8Object != null) && !v8Object.isReleased()) {
v8Object.release();
v8Object = null;
}
}
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/com/eclipsesource/v8/debug/mirror/NullMirror.java

@ -0,0 +1,35 @@
/*******************************************************************************
* 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/com/eclipsesource/v8/debug/mirror/NumberMirror.java

@ -0,0 +1,34 @@
/*******************************************************************************
* 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/com/eclipsesource/v8/debug/mirror/ObjectMirror.java

@ -0,0 +1,98 @@
/*******************************************************************************
* 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.release();
if (propertyNames != null) {
propertyNames.release();
}
}
}
/**
* 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.release();
if ((result != null) && !result.isReleased()) {
result.release();
result = null;
}
}
}
}

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

@ -0,0 +1,59 @@
/*******************************************************************************
* 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.release();
}
}
@Override
public void release() {
if (!v8Array.isReleased()) {
v8Array.release();
}
}
/**
* 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/com/eclipsesource/v8/debug/mirror/PropertyMirror.java

@ -0,0 +1,52 @@
/*******************************************************************************
* 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.release();
}
}
@Override
public boolean isProperty() {
return true;
}
}

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

@ -0,0 +1,156 @@
/*******************************************************************************
* 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.release();
}
}
/**
* 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.release();
}
}
/**
* 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.release();
}
}
/**
* 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.release();
}
}
/**
* 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.release();
}
}
/**
* 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.release();
}
}
}
}

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

@ -0,0 +1,96 @@
/*******************************************************************************
* 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 final int start;
private final int end;
/**
* 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 start The start of this location
* @param end The end of this location
*/
public SourceLocation(final String scriptName, final int position, final int line, final int column, final int start, final int end) {
this.scriptName = scriptName;
this.position = position;
this.line = line;
this.column = column;
this.start = start;
this.end = end;
}
@Override
public String toString() {
return scriptName + " : " + position + " : " + line + " : " + column + " : " + start + " : " + end;
}
/**
* 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 start of this SourceLocation.
* @return The start of this SourceLocation.
*/
public int getStart() {
return start;
}
/**
* Returns the end of this SourceLocation.
* @return The end of this SourceLocation.
*/
public int getEnd() {
return end;
}
}

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

@ -0,0 +1,34 @@
/*******************************************************************************
* 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/com/eclipsesource/v8/debug/mirror/UndefinedMirror.java

@ -0,0 +1,35 @@
/*******************************************************************************
* 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/com/eclipsesource/v8/debug/mirror/ValueMirror.java

@ -0,0 +1,40 @@
/*******************************************************************************
* 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;
}
}

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

@ -0,0 +1,138 @@
/*******************************************************************************
* 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.release();
}
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;
}
}
}
}
}
}

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

@ -0,0 +1,256 @@
/*******************************************************************************
* 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();
}
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.release();
parameters.release();
}
}
}
} catch (Exception e) {
exception = e;
} finally {
synchronized (this) {
if (runtime.getLocker().hasLock()) {
runtime.release();
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");
}
}
}
}

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

@ -0,0 +1,175 @@
/*******************************************************************************
* 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>();
}
/**
* 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
public void release() {
this.clear();
}
/*
* (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.release();
}
return result;
}
/*
* (non-Javadoc)
* @see java.util.Map#putAll(java.util.Map)
*/
@Override
public void putAll(final Map<? extends V8Value, ? extends V> m) {
for (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.release();
}
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<Entry<V8Value, V>> entrySet() {
return map.entrySet();
}
}

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

@ -0,0 +1,649 @@
/*******************************************************************************
* 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.nio.ByteBuffer;
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.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;
import com.eclipsesource.v8.utils.typedarrays.ArrayBuffer;
import com.eclipsesource.v8.utils.typedarrays.Float32Array;
import com.eclipsesource.v8.utils.typedarrays.Float64Array;
import com.eclipsesource.v8.utils.typedarrays.Int16Array;
import com.eclipsesource.v8.utils.typedarrays.Int32Array;
import com.eclipsesource.v8.utils.typedarrays.Int8Array;
import com.eclipsesource.v8.utils.typedarrays.TypedArray;
import com.eclipsesource.v8.utils.typedarrays.UInt16Array;
import com.eclipsesource.v8.utils.typedarrays.UInt32Array;
import com.eclipsesource.v8.utils.typedarrays.UInt8Array;
import com.eclipsesource.v8.utils.typedarrays.UInt8ClampedArray;
/**
* 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();
/**
* 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) {
V8Map<Object> cache = new V8Map<Object>();
try {
return toMap(object, cache);
} finally {
cache.release();
}
}
/**
* 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) {
V8Map<Object> cache = new V8Map<Object>();
try {
return toList(array, cache);
} finally {
cache.release();
}
}
/**
* 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.release();
}
}
}
/**
* 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.release();
}
}
}
/**
* 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 V8Object) {
return ((V8Object) result).twin();
}
return result;
} finally {
for (V8Value v8Object : cache.values()) {
v8Object.release();
}
}
}
/**
* 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.release();
}
}
}
/**
* 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>();
try {
return getValue(array, index, cache);
} finally {
cache.release();
}
}
/**
* 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) {
V8Map<Object> cache = new V8Map<Object>();
try {
return getValue(object, key, cache);
} finally {
cache.release();
}
}
@SuppressWarnings("unchecked")
private static Map<String, ? super Object> toMap(final V8Object object, final V8Map<Object> cache) {
if (object == null) {
return Collections.emptyMap();
}
if (cache.containsKey(object)) {
return (Map<String, ? super Object>) cache.get(object);
}
Map<String, ? super Object> result = new V8PropertyMap<Object>();
cache.put(object, result);
String[] keys = object.getKeys();
for (String key : keys) {
Object value = getValue(object, key, cache);
if (value != IGNORE) {
result.put(key, value);
}
}
return result;
}
@SuppressWarnings("unchecked")
private static List<? super Object> toList(final V8Array array, final V8Map<Object> cache) {
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 value = getValue(array, i, cache);
if (value != IGNORE) {
result.add(getValue(array, i, cache));
}
}
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.release();
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.release();
throw e;
}
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 = new V8ArrayBuffer(v8, arrayBuffer.getByteBuffer());
cache.put(arrayBuffer, result);
return result;
}
private static V8TypedArray toV8TypedArray(final V8 v8, final TypedArray typedArray, final Map<Object, V8Value> cache) {
if (cache.containsKey(typedArray)) {
return (V8TypedArray) cache.get(typedArray);
}
V8ArrayBuffer arrayBuffer = new V8ArrayBuffer(v8, typedArray.getByteBuffer());
try {
V8TypedArray result = new V8TypedArray(v8, arrayBuffer, typedArray.getType(), 0, typedArray.length());
cache.put(typedArray, result);
return result;
} finally {
arrayBuffer.release();
}
}
@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" })
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((Integer) value);
} else if (value instanceof Long) {
result.push(new Double((Long) value));
} else if (value instanceof Double) {
result.push((Double) value);
} else if (value instanceof Float) {
result.push((Float) value);
} else if (value instanceof String) {
result.push((String) value);
} else if (value instanceof Boolean) {
result.push((Boolean) value);
} else if (value instanceof V8Object) {
result.push((V8Object) 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 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" })
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, (int) (long) (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 V8Object) {
result.add(key, (V8Object) value);
} else if (value instanceof TypedArray) {
V8TypedArray typedArray = toV8TypedArray(v8, (TypedArray) value, cache);
result.add(key, typedArray);
} else if (value instanceof ArrayBuffer) {
V8ArrayBuffer v8ArrayBuffer = toV8ArrayBuffer(v8, (ArrayBuffer) value, cache);
result.add(key, v8ArrayBuffer);
} 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 V8Array array, final int index, final V8Map<Object> cache) {
int valueType = array.getType(index);
switch (valueType) {
case V8Value.INTEGER:
return array.getInteger(index);
case V8Value.DOUBLE:
return array.getDouble(index);
case V8Value.BOOLEAN:
return array.getBoolean(index);
case V8Value.STRING:
return array.getString(index);
case V8Value.V8_FUNCTION:
return IGNORE;
case V8Value.V8_ARRAY_BUFFER:
V8ArrayBuffer buffer = (V8ArrayBuffer) array.get(index);
try {
return new ArrayBuffer(buffer.getBackingStore());
} finally {
buffer.release();
}
case V8Value.V8_TYPED_ARRAY:
V8Array typedArray = array.getArray(index);
try {
return toTypedArray(typedArray);
} finally {
if (typedArray instanceof V8Array) {
typedArray.release();
}
}
case V8Value.V8_ARRAY:
V8Array arrayValue = array.getArray(index);
try {
return toList(arrayValue, cache);
} finally {
if (arrayValue instanceof V8Array) {
arrayValue.release();
}
}
case V8Value.V8_OBJECT:
V8Object objectValue = array.getObject(index);
try {
return toMap(objectValue, cache);
} finally {
if (objectValue instanceof V8Object) {
objectValue.release();
}
}
case V8Value.NULL:
return null;
case V8Value.UNDEFINED:
return V8.getUndefined();
default:
throw new IllegalStateException("Cannot find type for index: " + index);
}
}
private static Object toTypedArray(final V8Array typedArray) {
int arrayType = typedArray.getType();
ByteBuffer buffer = ((V8TypedArray) typedArray).getByteBuffer();
switch (arrayType) {
case V8Value.INT_8_ARRAY:
return new Int8Array(buffer);
case V8Value.UNSIGNED_INT_8_ARRAY:
return new UInt8Array(buffer);
case V8Value.UNSIGNED_INT_8_CLAMPED_ARRAY:
return new UInt8ClampedArray(buffer);
case V8Value.INT_16_ARRAY:
return new Int16Array(buffer);
case V8Value.UNSIGNED_INT_16_ARRAY:
return new UInt16Array(buffer);
case V8Value.INT_32_ARRAY:
return new Int32Array(buffer);
case V8Value.UNSIGNED_INT_32_ARRAY:
return new UInt32Array(buffer);
case V8Value.FLOAT_32_ARRAY:
return new Float32Array(buffer);
case V8Value.FLOAT_64_ARRAY:
return new Float64Array(buffer);
default:
throw new IllegalStateException("Known Typed Array type: " + V8Value.getStringRepresentaion(arrayType));
}
}
private static Object getValue(final V8Object object, final String key, final V8Map<Object> cache) {
int valueType = object.getType(key);
switch (valueType) {
case V8Value.INTEGER:
return object.getInteger(key);
case V8Value.DOUBLE:
return object.getDouble(key);
case V8Value.BOOLEAN:
return object.getBoolean(key);
case V8Value.STRING:
return object.getString(key);
case V8Value.V8_FUNCTION:
return IGNORE;
case V8Value.V8_ARRAY_BUFFER:
V8ArrayBuffer buffer = (V8ArrayBuffer) object.get(key);
try {
return new ArrayBuffer(buffer.getBackingStore());
} finally {
buffer.release();
}
case V8Value.V8_TYPED_ARRAY:
V8Array typedArray = object.getArray(key);
try {
return toTypedArray(typedArray);
} finally {
if (typedArray instanceof V8Array) {
typedArray.release();
}
}
case V8Value.V8_ARRAY:
V8Array array = object.getArray(key);
try {
return toList(array, cache);
} finally {
if (array instanceof V8Array) {
array.release();
}
}
case V8Value.V8_OBJECT:
V8Object child = object.getObject(key);
try {
return toMap(child, cache);
} finally {
if (child instanceof V8Object) {
child.release();
}
}
case V8Value.NULL:
return null;
case V8Value.UNDEFINED:
return V8.getUndefined();
default:
throw new IllegalStateException("Cannot find type for key: " + key);
}
}
private V8ObjectUtils() {
}
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/com/eclipsesource/v8/utils/V8PropertyMap.java

@ -0,0 +1,176 @@
/*******************************************************************************
* 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 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<Entry<String, V>>(map.entrySet());
for (String nullKey : nulls) {
result.add(new SimpleEntry<String, V>(nullKey, null));
}
return result;
}
}

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

@ -0,0 +1,29 @@
/*******************************************************************************
* 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/com/eclipsesource/v8/utils/V8Thread.java

@ -0,0 +1,57 @@
/*******************************************************************************
* 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.release();
runtime = null;
}
}
}
}
}

109
fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/ArrayBuffer.java

@ -0,0 +1,109 @@
/*******************************************************************************
* 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.typedarrays;
import java.nio.ByteBuffer;
/**
* A wrapper class for java.nio.ByteBuffer. This class provides some convenience methods
* for working with the ByteBuffer. Furthermore, this class can be converted to a
* V8ByteBuffer using V8ObjectUtils.
*/
public class ArrayBuffer {
private ByteBuffer byteBuffer;
/**
* Create a new ArrayBuffer with an initial capacity.
*
* @param capacity The capacity of this ByteBuffer.
*/
public ArrayBuffer(final int capacity) {
byteBuffer = ByteBuffer.allocateDirect(capacity);
}
/**
* Create a new ArrayBuffer from a byte array. The array buffer will be allocated with the same
* size as the byte array, and the contents of the byte array will be copied to the ArrayBuffer.
*
* @param src The byte array from which the ArrayBuffer will be initialized.
*/
public ArrayBuffer(final byte[] src) {
byteBuffer = ByteBuffer.allocateDirect(src.length);
byteBuffer.put(src, 0, src.length);
}
/**
* Create a new ArrayBuffer with the given ByteBuffer as the backing store. The ByteBuffer must
* be created as a DirectBuffer.
*
* @param byteBuffer The ByteBuffer to back this ArrayBuffer.
*/
public ArrayBuffer(final ByteBuffer byteBuffer) {
this.byteBuffer = validateByteBuffer(byteBuffer);
}
private ByteBuffer validateByteBuffer(final ByteBuffer byteBuffer) {
if (!byteBuffer.isDirect()) {
throw new IllegalArgumentException("ByteBuffer must be a allocated as a direct ByteBuffer");
}
return byteBuffer;
}
/**
* Returns the ByteBuffer backing this ArrayBuffer.
*
* @return The ByteBuffer backing this ArrayBuffer.
*/
public ByteBuffer getByteBuffer() {
return byteBuffer;
}
/**
* Returns the byte at a given index.
*
* @param index The index at which to return the byte.
* @return The byte at the given index.
*/
public byte getByte(final int index) {
return byteBuffer.get(index);
}
/**
* Returns the byte at a given index as an unsigned integer.
*
* @param index The index at which to return the byte.
* @return The unsigned byte at the given index.
*/
public short getUnsignedByte(final int index) {
return (short) (0xFF & byteBuffer.get(index));
}
/**
* Puts a byte into the ByteBuffer at the given index.
*
* @param index The index at which to put the byte.
* @param value The value to put at the index.
*/
public void put(final int index, final byte value) {
byteBuffer.put(index, value);
}
/**
* Returns this ArrayBuffers limit.
*
* @return This ArrayBuffers limit.
*/
public int limit() {
return byteBuffer.limit();
}
}

79
fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/Float32Array.java

@ -0,0 +1,79 @@
/*******************************************************************************
* 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.typedarrays;
import java.nio.ByteBuffer;
import com.eclipsesource.v8.V8Value;
/**
* The Float32Array typed array represents an array of 32-bit floating
* point numbers.
*/
public class Float32Array extends TypedArray {
/**
* Creates a Float32Array projected onto the given ByteBuffer.
*
* @param buffer The ByteBuffer on which the array is projected on.
*/
public Float32Array(final ByteBuffer buffer) {
super(buffer);
}
/**
* Creates a Float32Array projected onto the given ArrayBuffer.
*
* @param arrayBuffer The ArrayBuffer on which the array is projected on.
*/
public Float32Array(final ArrayBuffer arrayBuffer) {
this(arrayBuffer.getByteBuffer());
}
/**
* Returns the floating point (Float32) value at a given index.
*
* @param index The index at which to return the value.
* @return The Float32 value at the given index.
*/
public float get(final int index) {
return buffer.asFloatBuffer().get(index);
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#length()
*/
@Override
public int length() {
return buffer.asFloatBuffer().limit();
}
/**
* Puts a Float32 value at a particular index.
*
* @param index The index at which to place the value.
* @param value The Float32 value to place into buffer.
*/
public void put(final int index, final float value) {
buffer.asFloatBuffer().put(index, value);
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#getType()
*/
@Override
public int getType() {
return V8Value.FLOAT_32_ARRAY;
}
}

79
fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/Float64Array.java

@ -0,0 +1,79 @@
/*******************************************************************************
* 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.typedarrays;
import java.nio.ByteBuffer;
import com.eclipsesource.v8.V8Value;
/**
* The Float64Array typed array represents an array of 64-bit floating
* point numbers.
*/
public class Float64Array extends TypedArray {
/**
* Creates a Float64Array projected onto the given ByteBuffer.
*
* @param buffer The ByteBuffer on which the array is projected on.
*/
public Float64Array(final ByteBuffer buffer) {
super(buffer);
}
/**
* Creates a Float64Array projected onto the given ArrayBuffer.
*
* @param arrayBuffer The ArrayBuffer on which the array is projected on.
*/
public Float64Array(final ArrayBuffer arrayBuffer) {
this(arrayBuffer.getByteBuffer());
}
/**
* Returns the floating point (Float64) value at a given index.
*
* @param index The index at which to return the value.
* @return The Double (Float64) value at the given index.
*/
public double get(final int index) {
return buffer.asDoubleBuffer().get(index);
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#length()
*/
@Override
public int length() {
return buffer.asDoubleBuffer().limit();
}
/**
* Puts a Double (Float64) value at a particular index.
*
* @param index The index at which to place the value.
* @param value The Double to put into the buffer.
*/
public void put(final int index, final double value) {
buffer.asDoubleBuffer().put(index, value);
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#getType()
*/
@Override
public int getType() {
return V8Value.FLOAT_64_ARRAY;
}
}

79
fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/Int16Array.java

@ -0,0 +1,79 @@
/*******************************************************************************
* 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.typedarrays;
import java.nio.ByteBuffer;
import com.eclipsesource.v8.V8Value;
/**
* The Int16Array typed array represents an array of twos-complement
* 16-bit signed integers in the platform byte order.
*/
public class Int16Array extends TypedArray {
/**
* Creates an Int16Array projected onto the given ByteBuffer.
*
* @param buffer The ByteBuffer on which the array is projected on.
*/
public Int16Array(final ByteBuffer buffer) {
super(buffer);
}
/**
* Creates a Int16Array projected onto the given ArrayBuffer.
*
* @param arrayBuffer The ArrayBuffer on which the array is projected on.
*/
public Int16Array(final ArrayBuffer arrayBuffer) {
this(arrayBuffer.getByteBuffer());
}
/**
* Returns the 16-bit signed integer at the given index
*
* @param index The index at which to return the value.
* @return The 16-bit integer at the index.
*/
public short get(final int index) {
return buffer.asShortBuffer().get(index);
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#length()
*/
@Override
public int length() {
return buffer.asShortBuffer().limit();
}
/**
* Puts a 16-bit integer at a particular index.
*
* @param index The index at which to place the value.
* @param value The 16-bit integer to put into buffer.
*/
public void put(final int index, final short value) {
buffer.asShortBuffer().put(index, value);
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#getType()
*/
@Override
public int getType() {
return V8Value.INT_16_ARRAY;
}
}

75
fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/Int32Array.java

@ -0,0 +1,75 @@
/*******************************************************************************
* 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.typedarrays;
import java.nio.ByteBuffer;
import com.eclipsesource.v8.V8Value;
/**
* The Int32Array typed array represents an array of twos-complement 32-bit signed
* integers in the platform byte order.
*/
public class Int32Array extends TypedArray {
/**
* Creates an Int32Array projected onto the given ByteBuffer.
*
* @param buffer The ByteBuffer on which the array is projected on.
*/
public Int32Array(final ByteBuffer buffer) {
super(buffer);
}
/**
* Creates a Int32Array projected onto the given ArrayBuffer.
*
* @param arrayBuffer The ArrayBuffer on which the array is projected on.
*/
public Int32Array(final ArrayBuffer arrayBuffer) {
this(arrayBuffer.getByteBuffer());
}
/**
* Returns the 32-bit signed integer at the given index.
*
* @param index The index at which to return the value.
* @return The 32-bit integer at the index.
*/
public int get(final int index) {
return buffer.asIntBuffer().get(index);
}
@Override
public int length() {
return buffer.asIntBuffer().limit();
}
/**
* Puts a 32-bit integer at a particular index.
*
* @param index The index at which to place the value.
* @param value The 32-bit integer to put into buffer.
*/
public void put(final int index, final int value) {
buffer.asIntBuffer().put(index, value);
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#getType()
*/
@Override
public int getType() {
return V8Value.INT_32_ARRAY;
}
}

78
fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/Int8Array.java

@ -0,0 +1,78 @@
/*******************************************************************************
* 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.typedarrays;
import java.nio.ByteBuffer;
import com.eclipsesource.v8.V8Value;
/**
* The Int8Array typed array represents an array of twos-complement
* 8-bit signed integers.
*/
public class Int8Array extends TypedArray {
/**
* Creates an Int8Array projected onto the given ByteBuffer.
*
* @param buffer The ByteBuffer on which the array is projected on.
*/
public Int8Array(final ByteBuffer buffer) {
super(buffer);
}
/**
* Creates a Int8Array projected onto the given ArrayBuffer.
*
* @param arrayBuffer The ArrayBuffer on which the array is projected on.
*/
public Int8Array(final ArrayBuffer arrayBuffer) {
this(arrayBuffer.getByteBuffer());
}
/**
* Returns the 8-bit signed integer at the given index.
*
* @param index The index at which to return the value.
* @return The 8-bit integer at the index.
*/
public byte get(final int index) {
return buffer.get(index);
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#length()
*/
@Override
public int length() {
return buffer.limit();
}
/**
* Puts an 8-bit integer at a particular index.
*
* @param index The index at which to place the value.
* @param value The 8-bit integer to put into buffer.
*/
public void put(final int index, final byte value) {
buffer.put(index, value);
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#getType()
*/
@Override
public int getType() {
return V8Value.INT_8_ARRAY;
}
}

58
fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/TypedArray.java

@ -0,0 +1,58 @@
/*******************************************************************************
* 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.typedarrays;
import java.nio.ByteBuffer;
import com.eclipsesource.v8.V8TypedArray;
/**
* An abstract class that represents TypedArrays
*/
public abstract class TypedArray {
protected ByteBuffer buffer;
protected TypedArray(final ByteBuffer buffer) {
if (!buffer.isDirect()) {
throw new IllegalArgumentException("ByteBuffer must be a allocated as a direct ByteBuffer");
}
if ((buffer.limit() % V8TypedArray.getStructureSize(getType())) != 0) {
throw new IllegalArgumentException("ByteBuffer must be a allocated as a direct ByteBuffer");
}
this.buffer = buffer;
}
/**
* Return the underlying ByteBuffer.
*
* @return The underlying ByteBuffer behind this view
*/
public ByteBuffer getByteBuffer() {
return buffer;
}
/**
* Return the size of this view. The size of the view is determined by the size
* of the buffer, and the size of the data projected onto it. For example, for a
* buffer size of 8, and a view representing 16bit integers, the size would be 4.
*
* @return The size of this view
*/
public abstract int length();
/**
* Returns the 'Type' of this TypedArray using one of the constants defined in V8Value.
*
* @return The 'Type' of this typed array.
*/
public abstract int getType();
}

79
fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/UInt16Array.java

@ -0,0 +1,79 @@
/*******************************************************************************
* 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.typedarrays;
import java.nio.ByteBuffer;
import com.eclipsesource.v8.V8Value;
/**
* The Uint16Array typed array represents an array of 16-bit unsigned
* integers in the platform byte order.
*/
public class UInt16Array extends TypedArray {
/**
* Creates an UInt16Array projected onto the given ByteBuffer.
*
* @param buffer The ByteBuffer on which the array is projected on.
*/
public UInt16Array(final ByteBuffer buffer) {
super(buffer);
}
/**
* Creates a UInt16Array projected onto the given ArrayBuffer.
*
* @param arrayBuffer The ArrayBuffer on which the array is projected on.
*/
public UInt16Array(final ArrayBuffer arrayBuffer) {
this(arrayBuffer.getByteBuffer());
}
/**
* Returns the 16-bit unsigned integer at the given index.
*
* @param index The index at which to return the value.
* @return The 16-bit unsigned integer at the index.
*/
public int get(final int index) {
return 0xFFFF & buffer.asShortBuffer().get(index);
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#length()
*/
@Override
public int length() {
return buffer.asShortBuffer().limit();
}
/**
* Puts a 16-bit unsigned integer at a particular index.
*
* @param index The index at which to place the value.
* @param value The 16-bit unsigned integer to put into buffer.
*/
public void put(final int index, final int value) {
buffer.asShortBuffer().put(index, (short) (0x0000FFFF & value));
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#getType()
*/
@Override
public int getType() {
return V8Value.UNSIGNED_INT_16_ARRAY;
}
}

79
fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/UInt32Array.java

@ -0,0 +1,79 @@
/*******************************************************************************
* 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.typedarrays;
import java.nio.ByteBuffer;
import com.eclipsesource.v8.V8Value;
/**
* The Uint32Array typed array represents an array of 32-bit unsigned
* integers in the platform byte order.
*/
public class UInt32Array extends TypedArray {
/**
* Creates an UInt32Array projected onto the given ByteBuffer.
*
* @param buffer The ByteBuffer on which the array is projected on.
*/
public UInt32Array(final ByteBuffer buffer) {
super(buffer);
}
/**
* Creates a UInt32Array projected onto the given ArrayBuffer.
*
* @param arrayBuffer The ArrayBuffer on which the array is projected on.
*/
public UInt32Array(final ArrayBuffer arrayBuffer) {
this(arrayBuffer.getByteBuffer());
}
/**
* Returns the 32-bit unsigned integer at the given index.
*
* @param index The index at which to return the value.
* @return The 32-bit unsigned integer at the index.
*/
public long get(final int index) {
return 0x00000000FFFFFFFF & buffer.asIntBuffer().get(index);
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#length()
*/
@Override
public int length() {
return buffer.asIntBuffer().limit();
}
/**
* Puts a 32-bit unsigned integer at a particular index.
*
* @param index The index at which to place the value.
* @param value The 32-bit unsigned integer to put into buffer.
*/
public void put(final int index, final long value) {
buffer.asIntBuffer().put(index, (int) (0x00000000FFFFFFFF & value));
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#getType()
*/
@Override
public int getType() {
return V8Value.UNSIGNED_INT_32_ARRAY;
}
}

78
fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/UInt8Array.java

@ -0,0 +1,78 @@
/*******************************************************************************
* 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.typedarrays;
import java.nio.ByteBuffer;
import com.eclipsesource.v8.V8Value;
/**
* The Uint8Array typed array represents an array of 8-bit unsigned integers
*/
public class UInt8Array extends TypedArray {
/**
* Creates an UInt8Array projected onto the given ByteBuffer.
*
* @param buffer The ByteBuffer on which the array is projected on.
*/
public UInt8Array(final ByteBuffer buffer) {
super(buffer);
}
/**
* Creates a UInt8Array projected onto the given ArrayBuffer.
*
* @param arrayBuffer The ArrayBuffer on which the array is projected on.
*/
public UInt8Array(final ArrayBuffer arrayBuffer) {
this(arrayBuffer.getByteBuffer());
}
/**
* Returns the 8-bit unsigned integer at the given index.
*
* @param index The index at which to return the value.
* @return The 8-bit unsigned integer at the index.
*/
public short get(final int index) {
return (short) (0xFF & buffer.get(index));
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#length()
*/
@Override
public int length() {
return buffer.limit();
}
/**
* Puts a 8-bit unsigned integer at a particular index.
*
* @param index The index at which to place the value.
* @param value The 8-bit unsigned integer to put into buffer.
*/
public void put(final int index, final short value) {
buffer.put(index, (byte) (0x00FF & value));
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#getType()
*/
@Override
public int getType() {
return V8Value.UNSIGNED_INT_8_ARRAY;
}
}

87
fine-j2v8/src/com/eclipsesource/v8/utils/typedarrays/UInt8ClampedArray.java

@ -0,0 +1,87 @@
/*******************************************************************************
* 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.typedarrays;
import java.nio.ByteBuffer;
import com.eclipsesource.v8.V8Value;
/**
* The Uint8ClampedArray typed array represents an array of 8-bit unsigned
* integers clamped to 0-255; if you specified a value that is out of the
* range of [0,255], 0 or 255 will be set instead.
*/
public class UInt8ClampedArray extends TypedArray {
/**
* Creates an UInt8ClampedArray projected onto the given ByteBuffer.
*
* @param buffer The ByteBuffer on which the array is projected on.
*/
public UInt8ClampedArray(final ByteBuffer buffer) {
super(buffer);
}
/**
* Creates a UInt8ClampedArray projected onto the given ArrayBuffer.
*
* @param arrayBuffer The ArrayBuffer on which the array is projected on.
*/
public UInt8ClampedArray(final ArrayBuffer arrayBuffer) {
this(arrayBuffer.getByteBuffer());
}
/**
* Returns the 8-bit unsigned integer at the given index.
*
* @param index The index at which to return the value.
* @return The 8-bit unsigned integer at the index.
*/
public short get(final int index) {
return (short) (0xFF & buffer.get(index));
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#length()
*/
@Override
public int length() {
return buffer.limit();
}
/**
* Puts a 8-bit unsigned integer at a particular index. If the unsigned
* integer is outside the range [0,255], 0 or 255 will be used instead.
*
* @param index The index at which to place the value.
* @param value The 8-bit unsigned integer to put into buffer.
*/
public void put(final int index, final short value) {
if (value > 255) {
buffer.put(index, (byte) (255));
} else if (value < 0) {
buffer.put(index, (byte) (0));
} else {
buffer.put(index, (byte) (value));
}
}
/*
* (non-Javadoc)
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#getType()
*/
@Override
public int getType() {
return V8Value.UNSIGNED_INT_8_CLAMPED_ARRAY;
}
}

BIN
fine-j2v8/src/libj2v8_linux_x86_64.so

Binary file not shown.

BIN
fine-j2v8/src/libj2v8_macosx_x86_64.dylib

Binary file not shown.

BIN
fine-j2v8/src/libj2v8_win32_x86.dll

Binary file not shown.

BIN
fine-j2v8/src/libj2v8_win32_x86_64.dll

Binary file not shown.
Loading…
Cancel
Save