Skip to content

Commit

Permalink
Adds a twin() method to V8Value
Browse files Browse the repository at this point in the history
The twin() method will return a new Java object pointing at the same
V8Value. Care is taken to ensure the same type is returned (V8Object,
V8Function, V8Array).

The twin will mimic any changes made to the original (since they are 
the same V8Objects), but can be released independently.
  • Loading branch information
irbull committed May 15, 2015
1 parent d588d5e commit b5b3226
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 8 deletions.
8 changes: 8 additions & 0 deletions jni/com_eclipsesource_v8_V8Impl.cpp
Expand Up @@ -262,6 +262,14 @@ JNIEXPORT void JNICALL Java_com_eclipsesource_v8_V8__1initNewV8Object
reinterpret_cast<V8Runtime*>(v8RuntimePtr)->objects[objectHandle]->Reset(reinterpret_cast<V8Runtime*>(v8RuntimePtr)->isolate, obj);
}

JNIEXPORT void JNICALL Java_com_eclipsesource_v8_V8__1createTwin
(JNIEnv *env, jobject, jlong v8RuntimePtr, jint objectHandle, jint twinObjectHandle) {
Isolate* isolate = SETUP(env, v8RuntimePtr, );
Handle<Object> obj = Local<Object>::New(isolate, *reinterpret_cast<V8Runtime*>(v8RuntimePtr)->objects[objectHandle]);
createPersistentContainer(reinterpret_cast<V8Runtime*>(v8RuntimePtr), twinObjectHandle);
reinterpret_cast<V8Runtime*>(v8RuntimePtr)->objects[twinObjectHandle]->Reset(reinterpret_cast<V8Runtime*>(v8RuntimePtr)->isolate, obj);
}

JNIEXPORT void JNICALL Java_com_eclipsesource_v8_V8__1initNewV8Array
(JNIEnv *env, jobject, jlong v8RuntimePtr, jint arrayHandle) {
Isolate* isolate = SETUP(env, v8RuntimePtr, );
Expand Down
8 changes: 8 additions & 0 deletions jni/com_eclipsesource_v8_V8Impl.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions src/main/java/com/eclipsesource/v8/V8.java
Expand Up @@ -183,6 +183,11 @@ public int executeIntegerScript(final String script, final String scriptName, fi
return executeIntegerScript(v8RuntimePtr, script, scriptName, lineNumber);
}

void createTwin(final V8Value value, final int twinObjectHandle) {
checkThread();
createTwin(v8RuntimePtr, value.getHandle(), twinObjectHandle);
}

public double executeDoubleScript(final String script) {
return executeDoubleScript(script, null, 0);
}
Expand Down Expand Up @@ -483,6 +488,10 @@ protected void initNewV8Object(final long v8RuntimePtr, final int objectHandle)
_initNewV8Object(v8RuntimePtr, objectHandle);
}

protected void createTwin(final long v8RuntimePtr, final int objectHandle, final int twinObjectHandle) {
_createTwin(v8RuntimePtr, objectHandle, twinObjectHandle);
}

protected int executeIntegerScript(final long v8RuntimePtr, final String script, final String scriptName, final int lineNumber) {
return _executeIntegerScript(v8RuntimePtr, script, scriptName, lineNumber);
}
Expand Down Expand Up @@ -741,6 +750,8 @@ protected void terminateExecution(final long v8RuntimePtr) {

private native void _initNewV8Object(long v8RuntimePtr, int objectHandle);

private native void _createTwin(long v8RuntimePtr, int objectHandle, int twinObjectHandle);

private native void _releaseRuntime(long v8RuntimePtr);

private native long _createIsolate(String globalAlias);
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/com/eclipsesource/v8/V8Array.java
Expand Up @@ -21,6 +21,15 @@ public V8Array(final V8 v8) {
v8.checkThread();
}

@Override
protected V8Value createTwin(final int newHandle) {
return new V8Array(v8, newHandle);
}

protected V8Array(final V8 v8, final int objectHandle) {
super(v8, objectHandle);
}

@Override
protected void initialize(final long runtimePtr, final int objectHandle) {
v8.initNewV8Array(runtimePtr, objectHandle);
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/com/eclipsesource/v8/V8Function.java
Expand Up @@ -16,6 +16,15 @@ protected V8Function(final V8 v8) {
super(v8);
}

protected V8Function(final V8 v8, final int objectHandle) {
super(v8, objectHandle);
}

@Override
protected V8Value createTwin(final int newHandle) {
return new V8Function(v8, newHandle);
}

public Object call(final V8Object receiver, final V8Array parameters) {
v8.checkThread();
checkReleaesd();
Expand Down
14 changes: 7 additions & 7 deletions src/main/java/com/eclipsesource/v8/V8Object.java
Expand Up @@ -18,18 +18,18 @@ protected V8Object() {

}

@Override
protected V8Value createTwin(final int newHandle) {
return new V8Object(v8, newHandle);
}

protected V8Object(final V8 v8, final int objectHandle) {
if (v8 == null) {
this.v8 = (V8) this;
}
this.objectHandle = objectHandle;
released = false;
super(v8, objectHandle);
}

public V8Object(final V8 v8) {
this.v8 = v8;
super(v8);
v8.checkThread();
objectHandle = v8ObjectInstanceCounter++;
initialize(v8.getV8RuntimePtr(), objectHandle);
}

Expand Down
31 changes: 30 additions & 1 deletion src/main/java/com/eclipsesource/v8/V8Value.java
Expand Up @@ -28,10 +28,26 @@ abstract public class V8Value {
protected int objectHandle;
protected boolean released = true;

public V8Value() {
protected V8Value() {
super();
}

public V8Value(final V8 v8) {
this.v8 = v8;
objectHandle = v8ObjectInstanceCounter++;
}

protected V8Value(final V8 v8, final int objectHandle) {
if (v8 == null) {
this.v8 = (V8) this;
} else {
this.v8 = v8;
v8.addObjRef();
}
this.objectHandle = objectHandle;
released = false;
}

protected void initialize(final long runtimePtr, final int objectHandle) {
v8.initNewV8Object(runtimePtr, objectHandle);
v8.addObjRef();
Expand All @@ -51,6 +67,19 @@ public V8 getRutime() {
return v8;
}

public V8Value twin() {
if (isUndefined()) {
return this;
}
v8.checkThread();
v8.checkReleaesd();
int twinHandle = v8ObjectInstanceCounter++;
v8.createTwin(this, twinHandle);
return createTwin(twinHandle);
}

protected abstract V8Value createTwin(int twinObjectHandle);

public void release() {
v8.checkThread();
if ( !released ) {
Expand Down
129 changes: 129 additions & 0 deletions src/test/java/com/eclipsesource/v8/V8ObjectTest.java
Expand Up @@ -1041,4 +1041,133 @@ public void testToStringInCallback() {
a.release();
}

@Test
public void testV8ObjectTwinEqual() {
V8Object v8Object = new V8Object(v8);

V8Value twin = v8Object.twin();

assertNotSame(v8Object, twin);
assertTrue(v8Object.equals(twin));
assertTrue(twin.equals(v8Object));
v8Object.release();
twin.release();
}

@Test
public void testV8ObjectTwinSameValue() {
V8Object v8Object = new V8Object(v8);

V8Value twin = v8Object.twin();

assertNotSame(v8Object, twin);
assertTrue(v8Object.sameValue(twin));
assertTrue(twin.sameValue(v8Object));
v8Object.release();
twin.release();
}

@Test
public void testV8ObjectTwinStrictEquals() {
V8Object v8Object = new V8Object(v8);

V8Value twin = v8Object.twin();

assertNotSame(v8Object, twin);
assertTrue(v8Object.strictEquals(twin));
assertTrue(twin.strictEquals(v8Object));
v8Object.release();
twin.release();
}

@Test
public void testV8ObjectTwinSameHashCode() {
V8Object v8Object = new V8Object(v8);

V8Value twin = v8Object.twin();

assertEquals(v8Object.hashCode(), twin.hashCode());
v8Object.release();
twin.release();
}

@Test
public void testTwinIsObject() {
V8Object v8Object = new V8Object(v8);

V8Value twin = v8Object.twin();

assertTrue(twin instanceof V8Object);
v8Object.release();
twin.release();
}

@Test
public void testTwinIsArray() {
V8Object v8Object = new V8Array(v8);

V8Value twin = v8Object.twin();

assertTrue(twin instanceof V8Array);
v8Object.release();
twin.release();
}

@Test
public void testTwinIsFunction() {
v8.executeVoidScript("function add(x, y) {return x+y;}");
V8Object v8Object = v8.getObject("add");

V8Value twin = v8Object.twin();

assertTrue(twin instanceof V8Function);
v8Object.release();
twin.release();
}

@Test
public void testTwinIsUndefined() {
V8Object v8Object = (V8Object) V8.getUndefined();

V8Value twin = v8Object.twin();

assertTrue(twin.isUndefined());
v8Object.release();
twin.release();
}

@Test
public void testReleaseTwinDoesNotReleaseOriginal() {
V8Object v8Object = new V8Object(v8);
V8Value twin = v8Object.twin();

twin.release();

assertFalse(v8Object.isReleased());
v8Object.release();
}

@Test
public void testReleaseObjectDoesNotReleaseTwin() {
V8Object v8Object = new V8Object(v8);
V8Value twin = v8Object.twin();

v8Object.release();

assertFalse(twin.isReleased());
twin.release();
}

@Test
public void testTwinMimicsObject() {
V8Object v8Object = new V8Object(v8);
V8Value twin = v8Object.twin();

v8Object.add("foo", "bar");

assertEquals("bar", ((V8Object) twin).getString("foo"));
v8Object.release();
twin.release();
}

}

0 comments on commit b5b3226

Please sign in to comment.