From 9bc41a8a00818e8c9b36cffc7decb1f313f79892 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Tue, 3 Sep 2024 20:32:17 +0200 Subject: [PATCH] Add Float16Array (#491) --- cutils.h | 76 +++++++++++++++++++++++++++++++++ gen/function_source.c | Bin 3177 -> 3177 bytes gen/hello.c | Bin 1329 -> 1329 bytes gen/hello_module.c | Bin 3965 -> 3965 bytes gen/repl.c | Bin 139388 -> 139388 bytes gen/test_fib.c | Bin 1954 -> 1954 bytes quickjs-atom.h | 1 + quickjs.c | 95 ++++++++++++++++++++++++++++++++++++++++-- test262.conf | 2 +- test262_errors.txt | 8 ++-- tests/test_bjson.js | 2 + tests/test_builtin.js | 3 ++ 12 files changed, 178 insertions(+), 9 deletions(-) diff --git a/cutils.h b/cutils.h index aefb4dd..125f5f6 100644 --- a/cutils.h +++ b/cutils.h @@ -28,6 +28,7 @@ #include #include #include +#include #if defined(_WIN32) #include @@ -356,6 +357,81 @@ static inline void inplace_bswap32(uint8_t *tab) { put_u32(tab, bswap32(get_u32(tab))); } +static inline double fromfp16(uint16_t v) { + double d, s; + int e; + if ((v & 0x7C00) == 0x7C00) { + d = (v & 0x3FF) ? NAN : INFINITY; + } else { + d = (v & 0x3FF) / 1024.; + e = (v & 0x7C00) >> 10; + if (e == 0) { + e = -14; + } else { + d += 1; + e -= 15; + } + d = scalbn(d, e); + } + s = (v & 0x8000) ? -1.0 : 1.0; + return d * s; +} + +static inline uint16_t tofp16(double d) { + uint16_t f, s; + double t; + int e; + s = 0; + if (copysign(1, d) < 0) { // preserve sign when |d| is negative zero + d = -d; + s = 0x8000; + } + if (isinf(d)) + return s | 0x7C00; + if (isnan(d)) + return s | 0x7C01; + if (d == 0) + return s | 0; + d = 2 * frexp(d, &e); + e--; + if (e > 15) + return s | 0x7C00; // out of range, return +/-infinity + if (e < -25) { + d = 0; + e = 0; + } else if (e < -14) { + d = scalbn(d, e + 14); + e = 0; + } else { + d -= 1; + e += 15; + } + d *= 1024.; + f = (uint16_t)d; + t = d - f; + if (t < 0.5) + goto done; + if (t == 0.5) + if ((f & 1) == 0) + goto done; + // adjust for rounding + if (++f == 1024) { + f = 0; + if (++e == 31) + return s | 0x7C00; // out of range, return +/-infinity + } +done: + return s | (e << 10) | f; +} + +static inline int isfp16nan(uint16_t v) { + return (v & 0x7FFF) > 0x7C00; +} + +static inline int isfp16zero(uint16_t v) { + return (v & 0x7FFF) == 0; +} + /* XXX: should take an extra argument to pass slack information to the caller */ typedef void *DynBufReallocFunc(void *opaque, void *ptr, size_t size); diff --git a/gen/function_source.c b/gen/function_source.c index 85705da32fc0c55c935d8d69fcdeebe9a03cc823..494f560e4e1e9e7e330044bdf44338e095a41099 100644 GIT binary patch delta 201 zcmaDU@ls-g8Z)EGWOZgac{3dag9-y zi_J=vIWBAlr)f14&y|SP)f?= z4XommHQ6MAIzX%_wpg%V3h;Po(Ia#XP*U^Z2~&rGRHJ#0Bj95 AXaE2J delta 186 zcmaDU@ls-g8Z)EOWOZgac@rH4g9-yGRbIi3UeMiRLx`qR64GBPFu1ymRl!NS?Byg+^>s{xR|3MiT~`8<$J1<7$3CxT2&NuIocReZ80na3pPS*asUVC*aC diff --git a/gen/hello.c b/gen/hello.c index e131cfa55cab91a6f76c984926ff5f5bd99f5eb5..3225da4d46fb45f1d8f53104605ae16229e4a003 100644 GIT binary patch delta 43 xcmdnUwUKLs9us5YWC12I4ih6C1%rx|q{+Taa*W9!p~+253XF-H7c=!S0RZ**3p@Y- delta 43 xcmdnUwUKLs9uuSGWC12I4ih6C1%rx|#L2!)a*RnJp~+253XB$;7c=!S0RZo03h4j< diff --git a/gen/hello_module.c b/gen/hello_module.c index 98a6765fa6d1033d92745fcdf16cd7f7d52cf711..7005c6f6d305bec79748aa49c881298af32c671e 100644 GIT binary patch delta 174 zcmew>_g8L18RKMrCW*;?j695HlV>xQOkT<*G`XLNZL&I(Bv8bW$%fHlvH+7fvw;rR zX*hWSm*nIrT!KKIjaUffM)Aq>xfK{wfMT+Ysgv(<%QB@J QfE5Vycmr*V=aFLu0R6u)8vp_g8L186%_7WC14e$$gAGj3$$3GnN2J0VV?=>BwX=nV(65(O_}`qr~KOOiLM! zHis~`vH&&2^N4T$$X?4NY^0-LP+?#UCJjMklF8&oE|tj*Tq2Wqaz!zkO%~xcV@#fW zk6WDC#7JlIZf@zx4czREsgoBnicg-;tpJoez%9#|0#qT(l#&MIh)ove@djEI&m+eS E0D$~0N&o-= diff --git a/gen/repl.c b/gen/repl.c index 9bdd1f831dd1654736e7618b45def57da0cf6dc9..df1a3cd7fc9355fe250b73601cd9ae6271e402bc 100644 GIT binary patch delta 19794 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 diff --git a/gen/test_fib.c b/gen/test_fib.c index 53c431bf1e8b2ce99bd10bbcf13ba61471ebd6f9..f3b0352c3371cadb678c84cdc3149652e4a8cb63 100644 GIT binary patch delta 96 zcmZ3)zleWB6qAUFj)Fmjfw2x3h%y9mlFTOOF)1@!=x|NWXA+ydiYbiIVlpGM8Dq+1 t3uam7RG|17X1U2_%%(t*H9%Ggv&iIo%$!WA29sYhCo-CB_GSrZ1^}j#8C(DW delta 97 zcmZ3)zleWB6qAUNj)Fmjfw2x3h%y9ml1wJ&F)1^f>2OWXXA+ydiYbiIY%(LW8DsKf t3uam76rlJSW@)CB)XAk_!8Ocsj46{(Gs`fgq)mRwoXBXj*_$Pt834E>8Iu42 diff --git a/quickjs-atom.h b/quickjs-atom.h index 01d1910..2174f1e 100644 --- a/quickjs-atom.h +++ b/quickjs-atom.h @@ -202,6 +202,7 @@ DEF(Int32Array, "Int32Array") DEF(Uint32Array, "Uint32Array") DEF(BigInt64Array, "BigInt64Array") DEF(BigUint64Array, "BigUint64Array") +DEF(Float16Array, "Float16Array") DEF(Float32Array, "Float32Array") DEF(Float64Array, "Float64Array") DEF(DataView, "DataView") diff --git a/quickjs.c b/quickjs.c index 9132031..7883095 100644 --- a/quickjs.c +++ b/quickjs.c @@ -141,6 +141,7 @@ enum { JS_CLASS_UINT32_ARRAY, /* u.array (typed_array) */ JS_CLASS_BIG_INT64_ARRAY, /* u.array (typed_array) */ JS_CLASS_BIG_UINT64_ARRAY, /* u.array (typed_array) */ + JS_CLASS_FLOAT16_ARRAY, /* u.array (typed_array) */ JS_CLASS_FLOAT32_ARRAY, /* u.array (typed_array) */ JS_CLASS_FLOAT64_ARRAY, /* u.array (typed_array) */ JS_CLASS_DATAVIEW, /* u.typed_array */ @@ -944,6 +945,7 @@ struct JSObject { uint32_t *uint32_ptr; /* JS_CLASS_UINT32_ARRAY */ int64_t *int64_ptr; /* JS_CLASS_INT64_ARRAY */ uint64_t *uint64_ptr; /* JS_CLASS_UINT64_ARRAY */ + uint16_t *fp16_ptr; /* JS_CLASS_FLOAT16_ARRAY */ float *float_ptr; /* JS_CLASS_FLOAT32_ARRAY */ double *double_ptr; /* JS_CLASS_FLOAT64_ARRAY */ } u; @@ -1568,6 +1570,7 @@ static JSClassShortDef const js_std_class_def[] = { { JS_ATOM_Uint32Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_UINT32_ARRAY */ { JS_ATOM_BigInt64Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_BIG_INT64_ARRAY */ { JS_ATOM_BigUint64Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_BIG_UINT64_ARRAY */ + { JS_ATOM_Float16Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_FLOAT16_ARRAY */ { JS_ATOM_Float32Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_FLOAT32_ARRAY */ { JS_ATOM_Float64Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_FLOAT64_ARRAY */ { JS_ATOM_DataView, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_DATAVIEW */ @@ -4773,6 +4776,7 @@ static JSValue JS_NewObjectFromShape(JSContext *ctx, JSShape *sh, JSClassID clas case JS_CLASS_UINT32_ARRAY: case JS_CLASS_BIG_INT64_ARRAY: case JS_CLASS_BIG_UINT64_ARRAY: + case JS_CLASS_FLOAT16_ARRAY: case JS_CLASS_FLOAT32_ARRAY: case JS_CLASS_FLOAT64_ARRAY: p->is_exotic = 1; @@ -6085,6 +6089,7 @@ void JS_ComputeMemoryUsage(JSRuntime *rt, JSMemoryUsage *s) case JS_CLASS_UINT32_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_BIG_INT64_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_BIG_UINT64_ARRAY: /* u.typed_array / u.array */ + case JS_CLASS_FLOAT16_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_FLOAT32_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_FLOAT64_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_DATAVIEW: /* u.typed_array */ @@ -8004,6 +8009,10 @@ static BOOL js_get_fast_array_element(JSContext *ctx, JSObject *p, if (unlikely(idx >= p->u.array.count)) return FALSE; *pval = JS_NewBigUint64(ctx, p->u.array.u.uint64_ptr[idx]); return TRUE; + case JS_CLASS_FLOAT16_ARRAY: + if (unlikely(idx >= p->u.array.count)) return FALSE; + *pval = js_float64(fromfp16(p->u.array.u.fp16_ptr[idx])); + return TRUE; case JS_CLASS_FLOAT32_ARRAY: if (unlikely(idx >= p->u.array.count)) return FALSE; *pval = js_float64(p->u.array.u.float_ptr[idx]); @@ -8837,6 +8846,13 @@ static int JS_SetPropertyValue(JSContext *ctx, JSValue this_obj, p->u.array.u.uint64_ptr[idx] = v; } break; + case JS_CLASS_FLOAT16_ARRAY: + if (JS_ToFloat64Free(ctx, &d, val)) + goto ta_cvt_fail; + if (unlikely(idx >= (uint32_t)p->u.array.count)) + goto ta_out_of_bound; + p->u.array.u.fp16_ptr[idx] = tofp16(d); + break; case JS_CLASS_FLOAT32_ARRAY: if (JS_ToFloat64Free(ctx, &d, val)) goto ta_cvt_fail; @@ -11633,6 +11649,7 @@ static __maybe_unused void JS_DumpObject(JSRuntime *rt, JSObject *p) case JS_CLASS_UINT32_ARRAY: case JS_CLASS_BIG_INT64_ARRAY: case JS_CLASS_BIG_UINT64_ARRAY: + case JS_CLASS_FLOAT16_ARRAY: case JS_CLASS_FLOAT32_ARRAY: case JS_CLASS_FLOAT64_ARRAY: { @@ -41662,6 +41679,11 @@ static JSValue js_math_hypot(JSContext *ctx, JSValue this_val, return js_float64(r); } +static double js_math_f16round(double a) +{ + return fromfp16(tofp16(a)); +} + static double js_math_fround(double a) { return (float)a; @@ -41793,6 +41815,7 @@ static const JSCFunctionListEntry js_math_funcs[] = { JS_CFUNC_SPECIAL_DEF("cbrt", 1, f_f, js_math_cbrt ), JS_CFUNC_DEF("hypot", 2, js_math_hypot ), JS_CFUNC_DEF("random", 0, js_math_random ), + JS_CFUNC_SPECIAL_DEF("f16round", 1, f_f, js_math_f16round ), JS_CFUNC_SPECIAL_DEF("fround", 1, f_f, js_math_fround ), JS_CFUNC_DEF("imul", 2, js_math_imul ), JS_CFUNC_DEF("clz32", 1, js_math_clz32 ), @@ -49485,8 +49508,8 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx) static uint8_t const typed_array_size_log2[JS_TYPED_ARRAY_COUNT] = { 0, 0, 0, 1, 1, 2, 2, - 3, 3, /* BigInt64Array, BigUint64Array */ - 2, 3 + 3, 3, // BigInt64Array, BigUint64Array + 1, 2, 3 // Float16Array, Float32Array, Float64Array }; static JSValue js_array_buffer_constructor3(JSContext *ctx, @@ -50199,6 +50222,8 @@ static JSValue js_typed_array_at(JSContext *ctx, JSValue this_val, return js_int32(p->u.array.u.int32_ptr[idx]); case JS_CLASS_UINT32_ARRAY: return js_uint32(p->u.array.u.uint32_ptr[idx]); + case JS_CLASS_FLOAT16_ARRAY: + return js_float64(fromfp16(p->u.array.u.fp16_ptr[idx])); case JS_CLASS_FLOAT32_ARRAY: return js_float64(p->u.array.u.float_ptr[idx]); case JS_CLASS_FLOAT64_ARRAY: @@ -50518,7 +50543,9 @@ static JSValue js_typed_array_fill(JSContext *ctx, JSValue this_val, double d; if (JS_ToFloat64(ctx, &d, argv[0])) return JS_EXCEPTION; - if (p->class_id == JS_CLASS_FLOAT32_ARRAY) { + if (p->class_id == JS_CLASS_FLOAT16_ARRAY) { + v64 = tofp16(d); + } else if (p->class_id == JS_CLASS_FLOAT32_ARRAY) { union { float f; uint32_t u32; @@ -50649,6 +50676,7 @@ static JSValue js_typed_array_indexOf(JSContext *ctx, JSValue this_val, int64_t v64; double d; float f; + uint16_t hf; len = js_typed_array_get_length_internal(ctx, this_val); if (len < 0) @@ -50797,6 +50825,39 @@ static JSValue js_typed_array_indexOf(JSContext *ctx, JSValue this_val, } } break; + case JS_CLASS_FLOAT16_ARRAY: + if (is_bigint) + break; + if (isnan(d)) { + const uint16_t *pv = p->u.array.u.fp16_ptr; + /* special case: indexOf returns -1, includes finds NaN */ + if (special != special_includes) + goto done; + for (; k != stop; k += inc) { + if (isfp16nan(pv[k])) { + res = k; + break; + } + } + } else if (d == 0) { + // special case: includes also finds negative zero + const uint16_t *pv = p->u.array.u.fp16_ptr; + for (; k != stop; k += inc) { + if (isfp16zero(pv[k])) { + res = k; + break; + } + } + } else if (hf = tofp16(d), d == fromfp16(hf)) { + const uint16_t *pv = p->u.array.u.fp16_ptr; + for (; k != stop; k += inc) { + if (pv[k] == hf) { + res = k; + break; + } + } + } + break; case JS_CLASS_FLOAT32_ARRAY: if (is_bigint) break; @@ -51175,6 +51236,11 @@ static int js_TA_cmp_uint64(const void *a, const void *b, void *opaque) { return (y < x) - (y > x); } +static int js_TA_cmp_float16(const void *a, const void *b, void *opaque) { + return js_cmp_doubles(fromfp16(*(const uint16_t *)a), + fromfp16(*(const uint16_t *)b)); +} + static int js_TA_cmp_float32(const void *a, const void *b, void *opaque) { return js_cmp_doubles(*(const float *)a, *(const float *)b); } @@ -51215,6 +51281,10 @@ static JSValue js_TA_get_uint64(JSContext *ctx, const void *a) { return JS_NewBigUint64(ctx, *(uint64_t *)a); } +static JSValue js_TA_get_float16(JSContext *ctx, const void *a) { + return js_float64(fromfp16(*(const uint16_t *)a)); +} + static JSValue js_TA_get_float32(JSContext *ctx, const void *a) { return js_float64(*(const float *)a); } @@ -51339,6 +51409,10 @@ static JSValue js_typed_array_sort(JSContext *ctx, JSValue this_val, tsc.getfun = js_TA_get_uint64; cmpfun = js_TA_cmp_uint64; break; + case JS_CLASS_FLOAT16_ARRAY: + tsc.getfun = js_TA_get_float16; + cmpfun = js_TA_cmp_float16; + break; case JS_CLASS_FLOAT32_ARRAY: tsc.getfun = js_TA_get_float32; cmpfun = js_TA_cmp_float32; @@ -51893,6 +51967,14 @@ static JSValue js_dataview_getValue(JSContext *ctx, return JS_NewBigUint64(ctx, v); } break; + case JS_CLASS_FLOAT16_ARRAY: + { + uint16_t v; + v = get_u16(ptr); + if (is_swap) + v = bswap16(v); + return js_float64(fromfp16(v)); + } case JS_CLASS_FLOAT32_ARRAY: { union { @@ -51956,7 +52038,9 @@ static JSValue js_dataview_setValue(JSContext *ctx, double d; if (JS_ToFloat64(ctx, &d, val)) return JS_EXCEPTION; - if (class_id == JS_CLASS_FLOAT32_ARRAY) { + if (class_id == JS_CLASS_FLOAT16_ARRAY) { + v = tofp16(d); + } else if (class_id == JS_CLASS_FLOAT32_ARRAY) { union { float f; uint32_t i; @@ -51985,6 +52069,7 @@ static JSValue js_dataview_setValue(JSContext *ctx, break; case JS_CLASS_INT16_ARRAY: case JS_CLASS_UINT16_ARRAY: + case JS_CLASS_FLOAT16_ARRAY: if (is_swap) v = bswap16(v); put_u16(ptr, v); @@ -52021,6 +52106,7 @@ static const JSCFunctionListEntry js_dataview_proto_funcs[] = { JS_CFUNC_MAGIC_DEF("getUint32", 1, js_dataview_getValue, JS_CLASS_UINT32_ARRAY ), JS_CFUNC_MAGIC_DEF("getBigInt64", 1, js_dataview_getValue, JS_CLASS_BIG_INT64_ARRAY ), JS_CFUNC_MAGIC_DEF("getBigUint64", 1, js_dataview_getValue, JS_CLASS_BIG_UINT64_ARRAY ), + JS_CFUNC_MAGIC_DEF("getFloat16", 1, js_dataview_getValue, JS_CLASS_FLOAT16_ARRAY ), JS_CFUNC_MAGIC_DEF("getFloat32", 1, js_dataview_getValue, JS_CLASS_FLOAT32_ARRAY ), JS_CFUNC_MAGIC_DEF("getFloat64", 1, js_dataview_getValue, JS_CLASS_FLOAT64_ARRAY ), JS_CFUNC_MAGIC_DEF("setInt8", 2, js_dataview_setValue, JS_CLASS_INT8_ARRAY ), @@ -52031,6 +52117,7 @@ static const JSCFunctionListEntry js_dataview_proto_funcs[] = { JS_CFUNC_MAGIC_DEF("setUint32", 2, js_dataview_setValue, JS_CLASS_UINT32_ARRAY ), JS_CFUNC_MAGIC_DEF("setBigInt64", 2, js_dataview_setValue, JS_CLASS_BIG_INT64_ARRAY ), JS_CFUNC_MAGIC_DEF("setBigUint64", 2, js_dataview_setValue, JS_CLASS_BIG_UINT64_ARRAY ), + JS_CFUNC_MAGIC_DEF("setFloat16", 2, js_dataview_setValue, JS_CLASS_FLOAT16_ARRAY ), JS_CFUNC_MAGIC_DEF("setFloat32", 2, js_dataview_setValue, JS_CLASS_FLOAT32_ARRAY ), JS_CFUNC_MAGIC_DEF("setFloat64", 2, js_dataview_setValue, JS_CLASS_FLOAT64_ARRAY ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "DataView", JS_PROP_CONFIGURABLE ), diff --git a/test262.conf b/test262.conf index 19690e6..8da70c7 100644 --- a/test262.conf +++ b/test262.conf @@ -107,7 +107,7 @@ exponentiation export-star-as-namespace-from-module FinalizationRegistry FinalizationRegistry.prototype.cleanupSome=skip -Float16Array=skip +Float16Array Float32Array Float64Array for-in-order diff --git a/test262_errors.txt b/test262_errors.txt index 000cdfd..8dceec4 100644 --- a/test262_errors.txt +++ b/test262_errors.txt @@ -76,10 +76,10 @@ test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canoni test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-prototype-chain-set.js:35: strict mode: Test262Error: value should not be coerced Expected SameValue(«22», «0») to be true test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-reflect-set.js:35: Test262Error: value should not be coerced Expected SameValue(«32», «0») to be true test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-reflect-set.js:35: strict mode: Test262Error: value should not be coerced Expected SameValue(«32», «0») to be true -test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-prototype-chain-set.js:35: Test262Error: value should not be coerced Expected SameValue(«99», «0») to be true -test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-prototype-chain-set.js:35: strict mode: Test262Error: value should not be coerced Expected SameValue(«99», «0») to be true -test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-reflect-set.js:35: Test262Error: value should not be coerced Expected SameValue(«144», «0») to be true -test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-reflect-set.js:35: strict mode: Test262Error: value should not be coerced Expected SameValue(«144», «0») to be true +test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-prototype-chain-set.js:35: Test262Error: value should not be coerced Expected SameValue(«110», «0») to be true +test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-prototype-chain-set.js:35: strict mode: Test262Error: value should not be coerced Expected SameValue(«110», «0») to be true +test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-reflect-set.js:35: Test262Error: value should not be coerced Expected SameValue(«160», «0») to be true +test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-reflect-set.js:35: strict mode: Test262Error: value should not be coerced Expected SameValue(«160», «0») to be true test262/test/language/expressions/arrow-function/static-init-await-reference.js:12: unexpected error type: Test262: This statement should not be evaluated. test262/test/language/expressions/arrow-function/static-init-await-reference.js:12: strict mode: unexpected error type: Test262: This statement should not be evaluated. test262/test/language/expressions/assignment/destructuring/iterator-destructuring-property-reference-target-evaluation-order.js:42: Test262Error: Expected [source, iterator, target, target-key, target-key-tostring, iterator-step, iterator-done, set] and [source, iterator, target, target-key, iterator-step, iterator-done, target-key-tostring, set] to have the same contents. diff --git a/tests/test_bjson.js b/tests/test_bjson.js index e12919b..4139711 100644 --- a/tests/test_bjson.js +++ b/tests/test_bjson.js @@ -42,6 +42,7 @@ function isArrayLike(a) (a instanceof Int8Array) || (a instanceof Int16Array) || (a instanceof Int32Array) || + (a instanceof Float16Array) || (a instanceof Float32Array) || (a instanceof Float64Array); } @@ -192,6 +193,7 @@ function bjson_test_all() bjson_test([new Date(1234), new String("abc"), new Number(-12.1), new Boolean(true)]); bjson_test(new Int32Array([123123, 222111, -32222])); + bjson_test(new Float16Array([1024, 1024.5])); bjson_test(new Float64Array([123123, 222111.5])); /* tested with a circular reference */ diff --git a/tests/test_builtin.js b/tests/test_builtin.js index 41a4482..1e54587 100644 --- a/tests/test_builtin.js +++ b/tests/test_builtin.js @@ -551,6 +551,9 @@ function test_typed_array() a = new Uint16Array(buffer, 2); a[0] = -1; + a = new Float16Array(buffer, 8, 1); + a[0] = 1; + a = new Float32Array(buffer, 8, 1); a[0] = 1;