Skip to content

Commit

Permalink
✨ feat: #256 Support Float16Array
Browse files Browse the repository at this point in the history
  • Loading branch information
caoccao committed Oct 17, 2024
1 parent 7f78491 commit b6c1d2e
Show file tree
Hide file tree
Showing 21 changed files with 1,042 additions and 146 deletions.
3 changes: 3 additions & 0 deletions cpp/jni/javet_converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,9 @@ namespace Javet {
else if (v8Value->IsBigUint64Array()) {
type = V8ValueReferenceType::BigUint64Array;
}
else if (v8Value->IsFloat16Array()) {
type = V8ValueReferenceType::Float16Array;
}
else if (v8Value->IsFloat32Array()) {
type = V8ValueReferenceType::Float32Array;
}
Expand Down
28 changes: 15 additions & 13 deletions cpp/jni/javet_enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,16 @@ namespace Javet {
Int16Array = 42,
Uint32Array = 43,
Int32Array = 44,
Float32Array = 45,
Float64Array = 46,
BigInt64Array = 47,
BigUint64Array = 48,
DataView = 49,
SharedArrayBuffer = 50,
Proxy = 51,
WasmModuleObject = 52,
ModuleNamespaceObject = 53,
Float16Array = 45,
Float32Array = 46,
Float64Array = 47,
BigInt64Array = 48,
BigUint64Array = 49,
DataView = 50,
SharedArrayBuffer = 51,
Proxy = 52,
WasmModuleObject = 53,
ModuleNamespaceObject = 54,
};
};

Expand Down Expand Up @@ -165,10 +166,11 @@ namespace Javet {
Uint16Array = 37, // 0 to 65535 2 16-bit unsigned integer unsigned short uint16_t
Int32Array = 38, // -2147483648 to 2147483647 4 32-bit two's complement signed integer long int32_t
Uint32Array = 39, // 0 to 4294967295 4 32-bit unsigned integer unsigned long uint32_t
Float32Array = 40, // 1.2��10^-38 to 3.4��10^38 4 32-bit IEEE floating point number (7 significant digits e.g., 1.234567) unrestricted float float
Float64Array = 41, // 5.0��10^-324 to 1.8��10^308 8 64-bit IEEE floating point number (16 significant digits e.g., 1.23456789012345) unrestricted double double
BigInt64Array = 42, // -2^63 to 2^63-1 8 64-bit two's complement signed integer bigint int64_t (signed long long)
BigUint64Array = 43, // 0 to 2^64-1 8 64-bit unsigned integer bigint uint64_t (unsigned long long)
Float16Array = 40, // -65504 to 65504 2 N/A
Float32Array = 41, // -3.4e38 to 3.4e38 4 32-bit IEEE floating point number (7 significant digits e.g., 1.234567) unrestricted float float
Float64Array = 42, // -1.8e308 to 1.8e308 8 64-bit IEEE floating point number (16 significant digits e.g., 1.23456789012345) unrestricted double double
BigInt64Array = 43, // -2^63 to 2^63-1 8 64-bit two's complement signed integer bigint int64_t (signed long long)
BigUint64Array = 44, // 0 to 2^64-1 8 64-bit unsigned integer bigint uint64_t (unsigned long long)
};
};

Expand Down
19 changes: 10 additions & 9 deletions cpp/jni/javet_jni_core_v8.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,15 +217,16 @@ JNIEXPORT jboolean JNICALL Java_com_caoccao_javet_interop_V8Native_hasInternalTy
case Int16Array: return v8LocalValue->IsInt16Array(); // 42
case Uint32Array: return v8LocalValue->IsUint32Array(); // 43
case Int32Array: return v8LocalValue->IsInt32Array(); // 44
case Float32Array: return v8LocalValue->IsFloat32Array(); // 45
case Float64Array: return v8LocalValue->IsFloat64Array(); // 46
case BigInt64Array: return v8LocalValue->IsBigInt64Array(); // 47
case BigUint64Array: return v8LocalValue->IsBigUint64Array(); // 48
case DataView: return v8LocalValue->IsDataView(); // 49
case SharedArrayBuffer: return v8LocalValue->IsSharedArrayBuffer(); // 50
case Proxy: return v8LocalValue->IsProxy(); // 51
case WasmModuleObject: return v8LocalValue->IsWasmModuleObject(); // 52
case ModuleNamespaceObject: return v8LocalValue->IsModuleNamespaceObject(); // 53
case Float16Array: return v8LocalValue->IsFloat16Array(); // 45
case Float32Array: return v8LocalValue->IsFloat32Array(); // 46
case Float64Array: return v8LocalValue->IsFloat64Array(); // 47
case BigInt64Array: return v8LocalValue->IsBigInt64Array(); // 48
case BigUint64Array: return v8LocalValue->IsBigUint64Array(); // 49
case DataView: return v8LocalValue->IsDataView(); // 50
case SharedArrayBuffer: return v8LocalValue->IsSharedArrayBuffer(); // 51
case Proxy: return v8LocalValue->IsProxy(); // 52
case WasmModuleObject: return v8LocalValue->IsWasmModuleObject(); // 53
case ModuleNamespaceObject: return v8LocalValue->IsModuleNamespaceObject(); // 54
default:
break;
}
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/troubleshooting/termination.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ With Engine Pool
Please refer to the :extsource3:`source code <../../../src/test/java/com/caoccao/javet/interop/engine/TestJavetEnginePool.java>` for more detail.

Without Engine Pool
----------------
-------------------

.. code-block:: java
Expand Down
60 changes: 60 additions & 0 deletions docs/reference/v8_values/v8_typed_array.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
==============
V8 Typed Array
==============

There are 12 typed array supported. They are as follows.

=================== =========================== =============== =========== =======================
Type Value Range Size in bytes Java Type Web IDL type
=================== =========================== =============== =========== =======================
Int8Array -128 to 127 1 byte byte
Uint8Array 0 to 255 1 byte octet
Uint8ClampedArray 0 to 255 1 byte octet
Int16Array -32768 to 32767 2 short short
Uint16Array 0 to 65535 2 short unsigned short
Int32Array -2147483648 to 2147483647 4 int long
Uint32Array 0 to 4294967295 4 int unsigned long
Float16Array -65504 to 65504 2 short N/A
Float32Array -3.4e38 to 3.4e38 4 int unrestricted float
Float64Array -1.8e308 to 1.8e308 8 double unrestricted double
BigInt64Array -2^63 to 2^63 - 1 8 long bigint
BigUint64Array 0 to 2^64 - 1 8 long bigint
=================== =========================== =============== =========== =======================

Play with V8ValueTypedArray
===========================

All typed array share the same V8 value type ``V8ValueTypedArray``. They can be differentiated by their ``getType()`` which is an enum indicating their actual types. There is a buffer associated with the ``V8ValueTypedArray``. That buffer is the actual shared memory between JVM and V8. In other words, there is zero memory copy between JVM and V8 if ``V8ValueTypedArray`` is used. Many performance sensitive applications usually exchange data via ``V8ValueTypedArray``. There are a set of ``from****`` and ``to****`` API for the data exchange.

.. code-block:: java
try (V8ValueTypedArray v8ValueTypedArray = v8Runtime.createV8ValueTypedArray(
V8ValueReferenceType.Int8Array, 4)) {
assertEquals(4, v8ValueTypedArray.getLength());
assertEquals(1, v8ValueTypedArray.getSizeInBytes());
assertEquals(4, v8ValueTypedArray.getByteLength());
assertEquals(0, v8ValueTypedArray.getByteOffset());
assertEquals(V8ValueReferenceType.Int8Array, v8ValueTypedArray.getType());
try (V8ValueArrayBuffer v8ValueArrayBuffer = v8ValueTypedArray.getBuffer()) {
v8ValueArrayBuffer.fromBytes(new byte[]{ (byte) 1, (byte) 2, (byte) 3, (byte) 4,});
}
}
Play with Float16Array
======================

``Float16Array`` was `introduced to V8 in Mar, 2024 <https://blog.seokho.dev/development/2024/03/03/V8-Float16Array.html>`_ as an implementation of TC39 `proposal-float16array <https://github.com/tc39/proposal-float16array>`_. It's quite special because there is no float 16 in Java, so has to be mapped to ``short``.

Javet borrows ``Float16`` from the `Android FP16 implementation <https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/libcore/util/FP16.java>`_ (copyright preserved) to allow easy translation between ``short`` and ``float``. Just call ``short toHalf(float f)`` or ``float toFloat(short h)`` to complete the translation.

``Float16Array`` is not enabled by default. Please make sure the following code is executed before the first ``NodeRuntime`` or ``V8Runtime`` is created.

.. code-block:: java
// Node.js mode
NodeRuntimeOptions.NODE_FLAGS.setJsFloat16Array(true);
// V8 mode
V8RuntimeOptions.V8_FLAGS.setJsFloat16Array(true);
Please review the :extsource3:`test cases <../../../src/test/java/com/caoccao/javet/values/reference/TestV8ValueTypedArray.java>` for more detail.
2 changes: 2 additions & 0 deletions docs/release_notes/release_notes_4_0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Release Notes 4.0.x - 4.1.x
-----

* Switched to core dependency + individual native dependency
* Supported ``Float16Array``
* Added ``Float16``

4.0.0
-----
Expand Down
19 changes: 10 additions & 9 deletions src/main/java/com/caoccao/javet/enums/V8ValueInternalType.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,16 @@ public enum V8ValueInternalType {
Int16Array(42, "Int16Array"),
Uint32Array(43, "Uint32Array"),
Int32Array(44, "Int32Array"),
Float32Array(45, "Float32Array"),
Float64Array(46, "Float64Array"),
BigInt64Array(47, "BigInt64Array"),
BigUint64Array(48, "BigUint64Array"),
DataView(49, "DataView"),
SharedArrayBuffer(50, "SharedArrayBuffer"),
Proxy(51, "Proxy"),
WasmModuleObject(52, "WasmModuleObject"),
ModuleNamespaceObject(53, "ModuleNamespaceObject");
Float16Array(45, "Float16Array"),
Float32Array(46, "Float32Array"),
Float64Array(47, "Float64Array"),
BigInt64Array(48, "BigInt64Array"),
BigUint64Array(49, "BigUint64Array"),
DataView(50, "DataView"),
SharedArrayBuffer(51, "SharedArrayBuffer"),
Proxy(52, "Proxy"),
WasmModuleObject(53, "WasmModuleObject"),
ModuleNamespaceObject(54, "ModuleNamespaceObject");

private static final int LENGTH = values().length;
private static final V8ValueInternalType[] TYPES = new V8ValueInternalType[LENGTH];
Expand Down
11 changes: 6 additions & 5 deletions src/main/java/com/caoccao/javet/enums/V8ValueReferenceType.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ public enum V8ValueReferenceType {
Uint16Array(37, "Uint16Array"), // 0 to 65535 2 16-bit unsigned integer unsigned short uint16_t
Int32Array(38, "Int32Array"), // -2147483648 to 2147483647 4 32-bit two's complement signed integer long int32_t
Uint32Array(39, "Uint32Array"), // 0 to 4294967295 4 32-bit unsigned integer unsigned long uint32_t
Float32Array(40, "Float32Array"), // 1.2×10^-38 to 3.4×10^38 4 32-bit IEEE floating point number (7 significant digits e.g., 1.234567) unrestricted float float
Float64Array(41, "Float64Array"), // 5.0×10^-324 to 1.8×10^308 8 64-bit IEEE floating point number (16 significant digits e.g., 1.23456789012345) unrestricted double double
BigInt64Array(42, "BigInt64Array"), // -2^63 to 2^63-1 8 64-bit two's complement signed integer bigint int64_t (signed long long)
BigUint64Array(43, "BigUint64Array"); // 0 to 2^64-1 8 64-bit unsigned integer bigint uint64_t (unsigned long long)
Float16Array(40, "Float16Array"), // -65504 to 65504 2 N/A
Float32Array(41, "Float32Array"), // -3.4e38 to 3.4e38 4 32-bit IEEE floating point number (7 significant digits e.g., 1.234567) unrestricted float float
Float64Array(42, "Float64Array"), // -1.8e308 to 1.8e308 8 64-bit IEEE floating point number (16 significant digits e.g., 1.23456789012345) unrestricted double double
BigInt64Array(43, "BigInt64Array"), // -2^63 to 2^63-1 8 64-bit two's complement signed integer bigint int64_t (signed long long)
BigUint64Array(44, "BigUint64Array"); // 0 to 2^64-1 8 64-bit unsigned integer bigint uint64_t (unsigned long long)

private static final int LENGTH = 44;
private static final int LENGTH = 45;
private static final V8ValueReferenceType[] TYPES = new V8ValueReferenceType[LENGTH];

static {
Expand Down
27 changes: 22 additions & 5 deletions src/main/java/com/caoccao/javet/interop/V8Runtime.java
Original file line number Diff line number Diff line change
Expand Up @@ -996,11 +996,28 @@ public V8ValueSymbol createV8ValueSymbol(String description, boolean global) thr
@Override
@CheckReturnValue
public V8ValueTypedArray createV8ValueTypedArray(V8ValueReferenceType type, int length) throws JavetException {
try (V8Value v8Value = getGlobalObject().get(type.getName())) {
if (v8Value instanceof V8ValueFunction) {
V8ValueFunction v8ValueFunction = (V8ValueFunction) v8Value;
return v8ValueFunction.callAsConstructor(createV8ValueInteger(length));
}
switch (type) {
case Int8Array:
case Uint8Array:
case Uint8ClampedArray:
case Int16Array:
case Uint16Array:
case Int32Array:
case Uint32Array:
case Float16Array:
case Float32Array:
case Float64Array:
case BigInt64Array:
case BigUint64Array:
try (V8Value v8Value = getGlobalObject().get(type.getName())) {
if (v8Value instanceof V8ValueFunction) {
V8ValueFunction v8ValueFunction = (V8ValueFunction) v8Value;
return v8ValueFunction.callAsConstructor(createV8ValueInteger(length));
}
}
break;
default:
break;
}
throw new JavetException(JavetError.NotSupported, SimpleMap.of(PARAMETER_FEATURE, type.getName()));
}
Expand Down
38 changes: 36 additions & 2 deletions src/main/java/com/caoccao/javet/interop/options/NodeFlags.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,18 @@ public final class NodeFlags {
* @since 4.0.0
*/
public static final String EXPERIMENTAL_SQLITE = "--experimental-sqlite";

/**
* The constant ICU_DATA_DIR.
*
* @since 4.0.0
*/
public static final String ICU_DATA_DIR = "--icu-data-dir";
/**
* The constant JS_FLOAT_16_ARRAY.
*
* @since 4.1.0
*/
public static final String JS_FLOAT_16_ARRAY = "--js-float16array";
/**
* The constant NO_WARNINGS.
*
Expand All @@ -83,6 +88,7 @@ public final class NodeFlags {
private boolean experimentalRequireModule;
private boolean experimentalSqlite;
private String icuDataDir;
private boolean jsFloat16Array;
private boolean noWarnings;
private boolean sealed;

Expand All @@ -98,6 +104,7 @@ public final class NodeFlags {
experimentalPermission = false;
experimentalRequireModule = false;
experimentalSqlite = false;
jsFloat16Array = false;
noWarnings = false;
sealed = false;
}
Expand Down Expand Up @@ -189,6 +196,16 @@ public boolean isExperimentalSqlite() {
return experimentalSqlite;
}

/**
* Is js float 16 array enabled.
*
* @return true : yes, false: no
* @since 4.1.0
*/
public boolean isJsFloat16Array() {
return jsFloat16Array;
}

/**
* Silence all process warnings (including deprecations).
*
Expand Down Expand Up @@ -330,7 +347,7 @@ public NodeFlags setExperimentalSqlite(boolean experimentalSqlite) {
* Sets icu data dir.
*
* @param icuDataDir the icu data dir
* @return the icu data dir
* @return the self
* @since 4.0.0
*/
public NodeFlags setIcuDataDir(String icuDataDir) {
Expand All @@ -340,6 +357,20 @@ public NodeFlags setIcuDataDir(String icuDataDir) {
return this;
}

/**
* Sets js float 16 array.
*
* @param jsFloat16Array the js float 16 array
* @return the self
* @since 4.1.0
*/
public NodeFlags setJsFloat16Array(boolean jsFloat16Array) {
if (!sealed) {
this.jsFloat16Array = jsFloat16Array;
}
return this;
}

/**
* Sets no warnings.
*
Expand Down Expand Up @@ -385,6 +416,9 @@ public String[] toArray() {
if (StringUtils.isNotBlank(icuDataDir)) {
tokens.add(ICU_DATA_DIR + EQUAL + icuDataDir.trim());
}
if (jsFloat16Array) {
tokens.add(JS_FLOAT_16_ARRAY);
}
if (noWarnings) {
tokens.add(NO_WARNINGS);
}
Expand Down
Loading

0 comments on commit b6c1d2e

Please sign in to comment.