richie
6 years ago
66 changed files with 9415 additions and 1 deletions
@ -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); |
||||
|
||||
} |
@ -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); |
||||
|
||||
} |
@ -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()); |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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); |
||||
|
||||
} |
@ -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(); |
||||
|
||||
} |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -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; |
||||
} |
||||
|
||||
} |
@ -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); |
||||
} |
||||
|
||||
} |
@ -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(); |
||||
} |
||||
|
||||
} |
@ -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(); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -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(); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
|
||||
} |
@ -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); |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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); |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
} |
||||
|
||||
} |
@ -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 don’t 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"); |
||||
} |
||||
} |
||||
|
||||
} |
@ -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); |
||||
} |
||||
|
||||
} |
@ -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); |
||||
|
||||
} |
@ -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); |
||||
} |
||||
|
||||
} |
@ -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(); |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -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(); |
||||
} |
||||
} |
||||
|
||||
} |
@ -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); |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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); |
||||
} |
||||
|
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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(); |
||||
} |
||||
} |
@ -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"; |
||||
} |
||||
|
||||
} |
@ -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); |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
@ -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(); |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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(); |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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); |
||||
} |
||||
|
||||
} |
@ -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"; |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
@ -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"); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -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(); |
||||
} |
||||
|
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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); |
||||
|
||||
} |
@ -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; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
@ -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(); |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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(); |
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue