diff --git a/TODO b/TODO index a0cb604..4e87a71 100644 --- a/TODO +++ b/TODO @@ -63,4 +63,4 @@ Test262o: 0/11262 errors, 463 excluded Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch) Test262: -Result: 66/83341 errors, 2567 excluded, 5767 skipped +Result: 64/83341 errors, 2567 excluded, 5767 skipped diff --git a/quickjs.c b/quickjs.c index 8a11cf3..727cf8d 100644 --- a/quickjs.c +++ b/quickjs.c @@ -57676,7 +57676,7 @@ static JSValue js_TA_get_float64(JSContext *ctx, const void *a) { struct TA_sort_context { JSContext *ctx; int exception; /* 1 = exception, 2 = detached typed array */ - JSValueConst arr; + uint8_t *array; JSValueConst cmp; JSValue (*getfun)(JSContext *ctx, const void *a); int elt_size; @@ -57689,7 +57689,6 @@ static int js_TA_cmp_generic(const void *a, const void *b, void *opaque) { JSValueConst argv[2]; JSValue res; int cmp; - JSObject *p; cmp = 0; if (!psc->exception) { @@ -57697,15 +57696,9 @@ static int js_TA_cmp_generic(const void *a, const void *b, void *opaque) { error */ a_idx = *(uint32_t *)a; b_idx = *(uint32_t *)b; - p = JS_VALUE_GET_PTR(psc->arr); - if (a_idx >= p->u.array.count || b_idx >= p->u.array.count) { - /* OOB case */ - psc->exception = 2; - return 0; - } - argv[0] = psc->getfun(ctx, p->u.array.u.uint8_ptr + + argv[0] = psc->getfun(ctx, psc->array + a_idx * (size_t)psc->elt_size); - argv[1] = psc->getfun(ctx, p->u.array.u.uint8_ptr + + argv[1] = psc->getfun(ctx, psc->array + b_idx * (size_t)(psc->elt_size)); res = JS_Call(ctx, psc->cmp, JS_UNDEFINED, 2, argv); if (JS_IsException(res)) { @@ -57746,7 +57739,6 @@ static JSValue js_typed_array_sort(JSContext *ctx, JSValueConst this_val, tsc.ctx = ctx; tsc.exception = 0; - tsc.arr = this_val; tsc.cmp = argv[0]; if (!JS_IsUndefined(tsc.cmp) && check_function(ctx, tsc.cmp)) @@ -57809,65 +57801,69 @@ static JSValue js_typed_array_sort(JSContext *ctx, JSValueConst this_val, elt_size = 1 << typed_array_size_log2(p->class_id); if (!JS_IsUndefined(tsc.cmp)) { uint32_t *array_idx; - void *array_tmp; + void *array; size_t i, j; - /* XXX: a stable sort would use less memory */ - array_idx = js_malloc(ctx, len * sizeof(array_idx[0])); - if (!array_idx) + /* the array must be copied because the comparison + function may modify it */ + array = js_malloc(ctx, len * elt_size); + if (!array) return JS_EXCEPTION; + memcpy(array, p->u.array.u.ptr, len * elt_size); + + /* array_idx is needed to have a stable sort */ + array_idx = js_malloc(ctx, len * sizeof(array_idx[0])); + if (!array_idx) { + js_free(ctx, array); + return JS_EXCEPTION; + } for(i = 0; i < len; i++) array_idx[i] = i; tsc.elt_size = elt_size; + tsc.array = array; rqsort(array_idx, len, sizeof(array_idx[0]), js_TA_cmp_generic, &tsc); if (tsc.exception) { - if (tsc.exception == 1) - goto fail; + if (tsc.exception == 1) { + js_free(ctx, array_idx); + js_free(ctx, array); + return JS_EXCEPTION; + } /* detached typed array during the sort: no error */ } else { void *array_ptr = p->u.array.u.ptr; len = min_int(len, p->u.array.count); - if (len != 0) { - array_tmp = js_malloc(ctx, len * elt_size); - if (!array_tmp) { - fail: - js_free(ctx, array_idx); - return JS_EXCEPTION; + switch(elt_size) { + case 1: + for(i = 0; i < len; i++) { + j = array_idx[i]; + ((uint8_t *)array_ptr)[i] = ((uint8_t *)array)[j]; } - memcpy(array_tmp, array_ptr, len * elt_size); - switch(elt_size) { - case 1: - for(i = 0; i < len; i++) { - j = array_idx[i]; - ((uint8_t *)array_ptr)[i] = ((uint8_t *)array_tmp)[j]; - } - break; - case 2: - for(i = 0; i < len; i++) { - j = array_idx[i]; - ((uint16_t *)array_ptr)[i] = ((uint16_t *)array_tmp)[j]; - } - break; - case 4: - for(i = 0; i < len; i++) { - j = array_idx[i]; - ((uint32_t *)array_ptr)[i] = ((uint32_t *)array_tmp)[j]; - } - break; - case 8: - for(i = 0; i < len; i++) { - j = array_idx[i]; - ((uint64_t *)array_ptr)[i] = ((uint64_t *)array_tmp)[j]; - } - break; - default: - abort(); + break; + case 2: + for(i = 0; i < len; i++) { + j = array_idx[i]; + ((uint16_t *)array_ptr)[i] = ((uint16_t *)array)[j]; } - js_free(ctx, array_tmp); + break; + case 4: + for(i = 0; i < len; i++) { + j = array_idx[i]; + ((uint32_t *)array_ptr)[i] = ((uint32_t *)array)[j]; + } + break; + case 8: + for(i = 0; i < len; i++) { + j = array_idx[i]; + ((uint64_t *)array_ptr)[i] = ((uint64_t *)array)[j]; + } + break; + default: + abort(); } } js_free(ctx, array_idx); + js_free(ctx, array); } else { rqsort(p->u.array.u.ptr, len, elt_size, cmpfun, &tsc); if (tsc.exception) diff --git a/test262_errors.txt b/test262_errors.txt index faeb589..6974d27 100644 --- a/test262_errors.txt +++ b/test262_errors.txt @@ -37,8 +37,6 @@ test262/test/staging/sm/TypedArray/constructor-buffer-sequence.js:29: Test262Err test262/test/staging/sm/TypedArray/constructor-buffer-sequence.js:29: strict mode: Test262Error: Expected a ExpectedError but got a Error test262/test/staging/sm/TypedArray/prototype-constructor-identity.js:17: Test262Error: Expected SameValue(«2», «6») to be true test262/test/staging/sm/TypedArray/prototype-constructor-identity.js:17: strict mode: Test262Error: Expected SameValue(«2», «6») to be true -test262/test/staging/sm/TypedArray/sort_modifications.js:9: Test262Error: Int8Array at index 0 for size 4 Expected SameValue(«0», «1») to be true -test262/test/staging/sm/TypedArray/sort_modifications.js:9: strict mode: Test262Error: Int8Array at index 0 for size 4 Expected SameValue(«0», «1») to be true test262/test/staging/sm/async-functions/async-contains-unicode-escape.js:11: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all test262/test/staging/sm/async-functions/async-contains-unicode-escape.js:11: strict mode: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all test262/test/staging/sm/async-functions/await-in-arrow-parameters.js:10: Test262Error: AsyncFunction:(a = (b = await/r/g) => {}) => {} Expected a SyntaxError to be thrown but no exception was thrown at all