Skip to content

Commit b6c1d2e

Browse files
committed
✨ feat: #256 Support Float16Array
1 parent 7f78491 commit b6c1d2e

21 files changed

+1042
-146
lines changed

cpp/jni/javet_converter.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,9 @@ namespace Javet {
672672
else if (v8Value->IsBigUint64Array()) {
673673
type = V8ValueReferenceType::BigUint64Array;
674674
}
675+
else if (v8Value->IsFloat16Array()) {
676+
type = V8ValueReferenceType::Float16Array;
677+
}
675678
else if (v8Value->IsFloat32Array()) {
676679
type = V8ValueReferenceType::Float32Array;
677680
}

cpp/jni/javet_enums.h

+15-13
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,16 @@ namespace Javet {
117117
Int16Array = 42,
118118
Uint32Array = 43,
119119
Int32Array = 44,
120-
Float32Array = 45,
121-
Float64Array = 46,
122-
BigInt64Array = 47,
123-
BigUint64Array = 48,
124-
DataView = 49,
125-
SharedArrayBuffer = 50,
126-
Proxy = 51,
127-
WasmModuleObject = 52,
128-
ModuleNamespaceObject = 53,
120+
Float16Array = 45,
121+
Float32Array = 46,
122+
Float64Array = 47,
123+
BigInt64Array = 48,
124+
BigUint64Array = 49,
125+
DataView = 50,
126+
SharedArrayBuffer = 51,
127+
Proxy = 52,
128+
WasmModuleObject = 53,
129+
ModuleNamespaceObject = 54,
129130
};
130131
};
131132

@@ -165,10 +166,11 @@ namespace Javet {
165166
Uint16Array = 37, // 0 to 65535 2 16-bit unsigned integer unsigned short uint16_t
166167
Int32Array = 38, // -2147483648 to 2147483647 4 32-bit two's complement signed integer long int32_t
167168
Uint32Array = 39, // 0 to 4294967295 4 32-bit unsigned integer unsigned long uint32_t
168-
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
169-
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
170-
BigInt64Array = 42, // -2^63 to 2^63-1 8 64-bit two's complement signed integer bigint int64_t (signed long long)
171-
BigUint64Array = 43, // 0 to 2^64-1 8 64-bit unsigned integer bigint uint64_t (unsigned long long)
169+
Float16Array = 40, // -65504 to 65504 2 N/A
170+
Float32Array = 41, // -3.4e38 to 3.4e38 4 32-bit IEEE floating point number (7 significant digits e.g., 1.234567) unrestricted float float
171+
Float64Array = 42, // -1.8e308 to 1.8e308 8 64-bit IEEE floating point number (16 significant digits e.g., 1.23456789012345) unrestricted double double
172+
BigInt64Array = 43, // -2^63 to 2^63-1 8 64-bit two's complement signed integer bigint int64_t (signed long long)
173+
BigUint64Array = 44, // 0 to 2^64-1 8 64-bit unsigned integer bigint uint64_t (unsigned long long)
172174
};
173175
};
174176

cpp/jni/javet_jni_core_v8.cpp

+10-9
Original file line numberDiff line numberDiff line change
@@ -217,15 +217,16 @@ JNIEXPORT jboolean JNICALL Java_com_caoccao_javet_interop_V8Native_hasInternalTy
217217
case Int16Array: return v8LocalValue->IsInt16Array(); // 42
218218
case Uint32Array: return v8LocalValue->IsUint32Array(); // 43
219219
case Int32Array: return v8LocalValue->IsInt32Array(); // 44
220-
case Float32Array: return v8LocalValue->IsFloat32Array(); // 45
221-
case Float64Array: return v8LocalValue->IsFloat64Array(); // 46
222-
case BigInt64Array: return v8LocalValue->IsBigInt64Array(); // 47
223-
case BigUint64Array: return v8LocalValue->IsBigUint64Array(); // 48
224-
case DataView: return v8LocalValue->IsDataView(); // 49
225-
case SharedArrayBuffer: return v8LocalValue->IsSharedArrayBuffer(); // 50
226-
case Proxy: return v8LocalValue->IsProxy(); // 51
227-
case WasmModuleObject: return v8LocalValue->IsWasmModuleObject(); // 52
228-
case ModuleNamespaceObject: return v8LocalValue->IsModuleNamespaceObject(); // 53
220+
case Float16Array: return v8LocalValue->IsFloat16Array(); // 45
221+
case Float32Array: return v8LocalValue->IsFloat32Array(); // 46
222+
case Float64Array: return v8LocalValue->IsFloat64Array(); // 47
223+
case BigInt64Array: return v8LocalValue->IsBigInt64Array(); // 48
224+
case BigUint64Array: return v8LocalValue->IsBigUint64Array(); // 49
225+
case DataView: return v8LocalValue->IsDataView(); // 50
226+
case SharedArrayBuffer: return v8LocalValue->IsSharedArrayBuffer(); // 51
227+
case Proxy: return v8LocalValue->IsProxy(); // 52
228+
case WasmModuleObject: return v8LocalValue->IsWasmModuleObject(); // 53
229+
case ModuleNamespaceObject: return v8LocalValue->IsModuleNamespaceObject(); // 54
229230
default:
230231
break;
231232
}

docs/reference/troubleshooting/termination.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ With Engine Pool
3333
Please refer to the :extsource3:`source code <../../../src/test/java/com/caoccao/javet/interop/engine/TestJavetEnginePool.java>` for more detail.
3434

3535
Without Engine Pool
36-
----------------
36+
-------------------
3737

3838
.. code-block:: java
3939
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
==============
2+
V8 Typed Array
3+
==============
4+
5+
There are 12 typed array supported. They are as follows.
6+
7+
=================== =========================== =============== =========== =======================
8+
Type Value Range Size in bytes Java Type Web IDL type
9+
=================== =========================== =============== =========== =======================
10+
Int8Array -128 to 127 1 byte byte
11+
Uint8Array 0 to 255 1 byte octet
12+
Uint8ClampedArray 0 to 255 1 byte octet
13+
Int16Array -32768 to 32767 2 short short
14+
Uint16Array 0 to 65535 2 short unsigned short
15+
Int32Array -2147483648 to 2147483647 4 int long
16+
Uint32Array 0 to 4294967295 4 int unsigned long
17+
Float16Array -65504 to 65504 2 short N/A
18+
Float32Array -3.4e38 to 3.4e38 4 int unrestricted float
19+
Float64Array -1.8e308 to 1.8e308 8 double unrestricted double
20+
BigInt64Array -2^63 to 2^63 - 1 8 long bigint
21+
BigUint64Array 0 to 2^64 - 1 8 long bigint
22+
=================== =========================== =============== =========== =======================
23+
24+
Play with V8ValueTypedArray
25+
===========================
26+
27+
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.
28+
29+
.. code-block:: java
30+
31+
try (V8ValueTypedArray v8ValueTypedArray = v8Runtime.createV8ValueTypedArray(
32+
V8ValueReferenceType.Int8Array, 4)) {
33+
assertEquals(4, v8ValueTypedArray.getLength());
34+
assertEquals(1, v8ValueTypedArray.getSizeInBytes());
35+
assertEquals(4, v8ValueTypedArray.getByteLength());
36+
assertEquals(0, v8ValueTypedArray.getByteOffset());
37+
assertEquals(V8ValueReferenceType.Int8Array, v8ValueTypedArray.getType());
38+
try (V8ValueArrayBuffer v8ValueArrayBuffer = v8ValueTypedArray.getBuffer()) {
39+
v8ValueArrayBuffer.fromBytes(new byte[]{ (byte) 1, (byte) 2, (byte) 3, (byte) 4,});
40+
}
41+
}
42+
43+
Play with Float16Array
44+
======================
45+
46+
``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``.
47+
48+
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.
49+
50+
``Float16Array`` is not enabled by default. Please make sure the following code is executed before the first ``NodeRuntime`` or ``V8Runtime`` is created.
51+
52+
.. code-block:: java
53+
54+
// Node.js mode
55+
NodeRuntimeOptions.NODE_FLAGS.setJsFloat16Array(true);
56+
57+
// V8 mode
58+
V8RuntimeOptions.V8_FLAGS.setJsFloat16Array(true);
59+
60+
Please review the :extsource3:`test cases <../../../src/test/java/com/caoccao/javet/values/reference/TestV8ValueTypedArray.java>` for more detail.

docs/release_notes/release_notes_4_0.rst

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ Release Notes 4.0.x - 4.1.x
66
-----
77

88
* Switched to core dependency + individual native dependency
9+
* Supported ``Float16Array``
10+
* Added ``Float16``
911

1012
4.0.0
1113
-----

src/main/java/com/caoccao/javet/enums/V8ValueInternalType.java

+10-9
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,16 @@ public enum V8ValueInternalType {
6969
Int16Array(42, "Int16Array"),
7070
Uint32Array(43, "Uint32Array"),
7171
Int32Array(44, "Int32Array"),
72-
Float32Array(45, "Float32Array"),
73-
Float64Array(46, "Float64Array"),
74-
BigInt64Array(47, "BigInt64Array"),
75-
BigUint64Array(48, "BigUint64Array"),
76-
DataView(49, "DataView"),
77-
SharedArrayBuffer(50, "SharedArrayBuffer"),
78-
Proxy(51, "Proxy"),
79-
WasmModuleObject(52, "WasmModuleObject"),
80-
ModuleNamespaceObject(53, "ModuleNamespaceObject");
72+
Float16Array(45, "Float16Array"),
73+
Float32Array(46, "Float32Array"),
74+
Float64Array(47, "Float64Array"),
75+
BigInt64Array(48, "BigInt64Array"),
76+
BigUint64Array(49, "BigUint64Array"),
77+
DataView(50, "DataView"),
78+
SharedArrayBuffer(51, "SharedArrayBuffer"),
79+
Proxy(52, "Proxy"),
80+
WasmModuleObject(53, "WasmModuleObject"),
81+
ModuleNamespaceObject(54, "ModuleNamespaceObject");
8182

8283
private static final int LENGTH = values().length;
8384
private static final V8ValueInternalType[] TYPES = new V8ValueInternalType[LENGTH];

src/main/java/com/caoccao/javet/enums/V8ValueReferenceType.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,13 @@ public enum V8ValueReferenceType {
5353
Uint16Array(37, "Uint16Array"), // 0 to 65535 2 16-bit unsigned integer unsigned short uint16_t
5454
Int32Array(38, "Int32Array"), // -2147483648 to 2147483647 4 32-bit two's complement signed integer long int32_t
5555
Uint32Array(39, "Uint32Array"), // 0 to 4294967295 4 32-bit unsigned integer unsigned long uint32_t
56-
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
57-
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
58-
BigInt64Array(42, "BigInt64Array"), // -2^63 to 2^63-1 8 64-bit two's complement signed integer bigint int64_t (signed long long)
59-
BigUint64Array(43, "BigUint64Array"); // 0 to 2^64-1 8 64-bit unsigned integer bigint uint64_t (unsigned long long)
56+
Float16Array(40, "Float16Array"), // -65504 to 65504 2 N/A
57+
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
58+
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
59+
BigInt64Array(43, "BigInt64Array"), // -2^63 to 2^63-1 8 64-bit two's complement signed integer bigint int64_t (signed long long)
60+
BigUint64Array(44, "BigUint64Array"); // 0 to 2^64-1 8 64-bit unsigned integer bigint uint64_t (unsigned long long)
6061

61-
private static final int LENGTH = 44;
62+
private static final int LENGTH = 45;
6263
private static final V8ValueReferenceType[] TYPES = new V8ValueReferenceType[LENGTH];
6364

6465
static {

src/main/java/com/caoccao/javet/interop/V8Runtime.java

+22-5
Original file line numberDiff line numberDiff line change
@@ -996,11 +996,28 @@ public V8ValueSymbol createV8ValueSymbol(String description, boolean global) thr
996996
@Override
997997
@CheckReturnValue
998998
public V8ValueTypedArray createV8ValueTypedArray(V8ValueReferenceType type, int length) throws JavetException {
999-
try (V8Value v8Value = getGlobalObject().get(type.getName())) {
1000-
if (v8Value instanceof V8ValueFunction) {
1001-
V8ValueFunction v8ValueFunction = (V8ValueFunction) v8Value;
1002-
return v8ValueFunction.callAsConstructor(createV8ValueInteger(length));
1003-
}
999+
switch (type) {
1000+
case Int8Array:
1001+
case Uint8Array:
1002+
case Uint8ClampedArray:
1003+
case Int16Array:
1004+
case Uint16Array:
1005+
case Int32Array:
1006+
case Uint32Array:
1007+
case Float16Array:
1008+
case Float32Array:
1009+
case Float64Array:
1010+
case BigInt64Array:
1011+
case BigUint64Array:
1012+
try (V8Value v8Value = getGlobalObject().get(type.getName())) {
1013+
if (v8Value instanceof V8ValueFunction) {
1014+
V8ValueFunction v8ValueFunction = (V8ValueFunction) v8Value;
1015+
return v8ValueFunction.callAsConstructor(createV8ValueInteger(length));
1016+
}
1017+
}
1018+
break;
1019+
default:
1020+
break;
10041021
}
10051022
throw new JavetException(JavetError.NotSupported, SimpleMap.of(PARAMETER_FEATURE, type.getName()));
10061023
}

src/main/java/com/caoccao/javet/interop/options/NodeFlags.java

+36-2
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,18 @@ public final class NodeFlags {
6161
* @since 4.0.0
6262
*/
6363
public static final String EXPERIMENTAL_SQLITE = "--experimental-sqlite";
64-
6564
/**
6665
* The constant ICU_DATA_DIR.
6766
*
6867
* @since 4.0.0
6968
*/
7069
public static final String ICU_DATA_DIR = "--icu-data-dir";
70+
/**
71+
* The constant JS_FLOAT_16_ARRAY.
72+
*
73+
* @since 4.1.0
74+
*/
75+
public static final String JS_FLOAT_16_ARRAY = "--js-float16array";
7176
/**
7277
* The constant NO_WARNINGS.
7378
*
@@ -83,6 +88,7 @@ public final class NodeFlags {
8388
private boolean experimentalRequireModule;
8489
private boolean experimentalSqlite;
8590
private String icuDataDir;
91+
private boolean jsFloat16Array;
8692
private boolean noWarnings;
8793
private boolean sealed;
8894

@@ -98,6 +104,7 @@ public final class NodeFlags {
98104
experimentalPermission = false;
99105
experimentalRequireModule = false;
100106
experimentalSqlite = false;
107+
jsFloat16Array = false;
101108
noWarnings = false;
102109
sealed = false;
103110
}
@@ -189,6 +196,16 @@ public boolean isExperimentalSqlite() {
189196
return experimentalSqlite;
190197
}
191198

199+
/**
200+
* Is js float 16 array enabled.
201+
*
202+
* @return true : yes, false: no
203+
* @since 4.1.0
204+
*/
205+
public boolean isJsFloat16Array() {
206+
return jsFloat16Array;
207+
}
208+
192209
/**
193210
* Silence all process warnings (including deprecations).
194211
*
@@ -330,7 +347,7 @@ public NodeFlags setExperimentalSqlite(boolean experimentalSqlite) {
330347
* Sets icu data dir.
331348
*
332349
* @param icuDataDir the icu data dir
333-
* @return the icu data dir
350+
* @return the self
334351
* @since 4.0.0
335352
*/
336353
public NodeFlags setIcuDataDir(String icuDataDir) {
@@ -340,6 +357,20 @@ public NodeFlags setIcuDataDir(String icuDataDir) {
340357
return this;
341358
}
342359

360+
/**
361+
* Sets js float 16 array.
362+
*
363+
* @param jsFloat16Array the js float 16 array
364+
* @return the self
365+
* @since 4.1.0
366+
*/
367+
public NodeFlags setJsFloat16Array(boolean jsFloat16Array) {
368+
if (!sealed) {
369+
this.jsFloat16Array = jsFloat16Array;
370+
}
371+
return this;
372+
}
373+
343374
/**
344375
* Sets no warnings.
345376
*
@@ -385,6 +416,9 @@ public String[] toArray() {
385416
if (StringUtils.isNotBlank(icuDataDir)) {
386417
tokens.add(ICU_DATA_DIR + EQUAL + icuDataDir.trim());
387418
}
419+
if (jsFloat16Array) {
420+
tokens.add(JS_FLOAT_16_ARRAY);
421+
}
388422
if (noWarnings) {
389423
tokens.add(NO_WARNINGS);
390424
}

0 commit comments

Comments
 (0)