private void releaseNow(Object value) { if (value instanceof V8Value) { V8Value ref = (V8Value) value; if (!ref.isReleased()) { ref.release(); } } } }
/** * 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 void initialize(final long runtimePtr, final Object data) { long objectHandle = v8.initNewV8Object(runtimePtr); released = false; addObjectReference(objectHandle); }
void checkRuntime(final V8Value value) { if ((value == null) || value.isUndefined()) { return; } V8 runtime = value.getRuntime(); if ((runtime == null) || runtime.isReleased() || (runtime != this)) { throw new Error("Invalid target runtime"); } }
/** * 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(); v8.checkRuntime(value); 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; }
/** * Creates a new Java object pointing at the same V8 Value * as this. If the value is mutated (by adding new members or * changing existing ones) then both the original and twin * will be updated. Twins are .equal and .strict equals, but * not == in Java. * * Twins must be closed separately since they have their own * native resources. * * @return A new Java object pointing at the same V8 Value * as this. */ public V8Value twin() { if (isUndefined()) { return this; } v8.checkThread(); v8.checkReleased(); V8Value twin = createTwin(); v8.createTwin(this, twin); return twin; }
@Override public V8Object twin() { return (V8Object) super.twin(); }
@Override public int hashCode() { v8.checkThread(); checkReleased(); return v8.identityHash(v8.getV8RuntimePtr(), getHandle()); }
private Object checkResult(final Object result) { if (result == null) { return result; } if (result instanceof Float) { return ((Float) result).doubleValue(); } if ((result instanceof Integer) || (result instanceof Double) || (result instanceof Boolean) || (result instanceof String)) { return result; } if (result instanceof V8Value) { if (((V8Value) result).isReleased()) { throw new V8RuntimeException("V8Value already released"); } return result; } throw new V8RuntimeException("Unknown return type: " + result.getClass()); }
/** * Returns the 'type' of this V8Value. The available types are defined * as constants in {@link V8Value}. Only types that inherit from * {@link V8Value} can be returned here. * * @return The 'type of this V8Value. */ public int getV8Type() { if (isUndefined()) { return UNDEFINED; } v8.checkThread(); v8.checkReleased(); return v8.getType(v8.getV8RuntimePtr(), objectHandle); }
@Test public void testReleaseObjectDoesNotReleaseTwin() { V8Object v8Object = new V8Object(v8); V8Value twin = v8Object.twin(); v8Object.close(); assertFalse(twin.isReleased()); twin.close(); }
@Test public void testTwinIsUndefined() { V8Object v8Object = (V8Object) V8.getUndefined(); V8Value twin = v8Object.twin(); assertTrue(twin.isUndefined()); v8Object.close(); twin.close(); }
protected long getHandle() { checkReleased(); return objectHandle; }
@Override public boolean equals(final Object that) { return strictEquals(that); }
/** * Pushes a V8Value to the next available spot in the Array. In * particular, this[length] = value; * * @param value The value to push to the array. * * @return The receiver. */ public V8Array push(final V8Value value) { v8.checkThread(); checkReleased(); v8.checkRuntime(value); if (value == null) { v8.addArrayNullItem(v8.getV8RuntimePtr(), getHandle()); } else if (value.equals(V8.getUndefined())) { v8.addArrayUndefinedItem(v8.getV8RuntimePtr(), getHandle()); } else { v8.addArrayObjectItem(v8.getV8RuntimePtr(), getHandle(), value.getHandle()); } return this; }
/** * Creates a new Java object pointing at the same V8 Value * as this. If the value is mutated (by adding new members or * changing existing ones) then both the original and twin * will be updated. Twins are .equal and .strict equals, but * not == in Java. * * Twins must be closed separately since they have their own * native resources. * * @return A new Java object pointing at the same V8 Value * as this. */ public V8Value twin() { if (isUndefined()) { return this; } v8.checkThread(); v8.checkReleased(); V8Value twin = createTwin(); v8.createTwin(this, twin); return twin; }