use internal calls for internals

This commit is contained in:
2026-01-26 11:44:21 -06:00
parent 086508bacd
commit 06f7791159
2 changed files with 355 additions and 341 deletions

View File

@@ -27633,42 +27633,47 @@ static JSValue js_cell_array(JSContext *ctx, JSValueConst this_val,
/* array(number) - create array of size */
/* array(number, initial_value) - create array with initial values */
if (tag == JS_TAG_INT || tag == JS_TAG_FLOAT64) {
double d;
if (JS_ToFloat64(ctx, &d, arg))
return JS_NULL;
if (d < 0) return JS_NULL;
int64_t len = (int64_t)floor(d);
if (JS_IsNumber(arg)) {
if (!JS_IsInteger(arg))
return JS_ThrowTypeError(ctx, "Array expected an integer.");
int len = JS_VALUE_GET_INT(arg);
if (len < 0) return JS_NULL;
JSValue result = JS_NewArrayLen(ctx, len);
if (JS_IsException(result)) return result;
JSArray *out = JS_VALUE_GET_ARRAY(result);
if (JS_IsFunction(argv[1])) {
if (argc > 1 && JS_IsFunction(argv[1])) {
/* Fill with function results */
JSValueConst func = argv[1];
int arity = 0;
JSValue len_val = JS_GetPropertyStr(ctx, func, "length");
if (!JS_IsException(len_val)) {
JS_ToInt32(ctx, &arity, len_val);
JS_FreeValue(ctx, len_val);
}
int arity = ((JSFunction*)JS_VALUE_GET_FUNCTION(func))->length;
for (int64_t i = 0; i < len; i++) {
JSValue args[1] = { JS_NewInt64(ctx, i) };
JSValue val = arity >= 1 ? JS_Call(ctx, func, JS_NULL, 1, args)
: JS_Call(ctx, func, JS_NULL, 0, NULL);
JS_FreeValue(ctx, args[0]);
if (arity >= 1) {
for (int i = 0; i < len; i++) {
JSValue idx_arg = JS_NewInt32(ctx, i);
JSValue val = JS_CallInternal(ctx, func, JS_NULL, 1, &idx_arg, 0);
JS_FreeValue(ctx, idx_arg);
if (JS_IsException(val)) {
JS_FreeValue(ctx, result);
return JS_EXCEPTION;
}
JS_SetPropertyInt64(ctx, result, i, val);
out->values[i] = val;
}
} else {
/* Fill with value */
for (int64_t i = 0; i < len; i++) {
JS_SetPropertyInt64(ctx, result, i, JS_DupValue(ctx, argv[1]));
for (int i = 0; i < len; i++) {
JSValue val = JS_CallInternal(ctx, func, JS_NULL, 0, NULL, 0);
if (JS_IsException(val)) {
JS_FreeValue(ctx, result);
return JS_EXCEPTION;
}
out->values[i] = val;
}
}
} else if (argc > 1) {
/* Fill with value */
for (int i = 0; i < len; i++)
out->values[i] = JS_DupValue(ctx, argv[1]);
}
return result;
}
@@ -27678,51 +27683,72 @@ static JSValue js_cell_array(JSContext *ctx, JSValueConst this_val,
/* array(array, another_array) - concat */
/* array(array, from, to) - slice */
if (JS_IsArray(ctx, arg)) {
int64_t len;
if (js_get_length64(ctx, &len, arg))
return JS_EXCEPTION;
JSArray *arr = JS_VALUE_GET_ARRAY(arg);
int len = arr->len;
if (argc < 2 || JS_IsNull(argv[1])) {
/* Copy */
JSValue result = JS_NewArrayLen(ctx, len);
if (JS_IsException(result)) return result;
for (int64_t i = 0; i < len; i++) {
JSValue val = JS_GetPropertyInt64(ctx, arg, i);
if (JS_IsException(val)) {
JS_FreeValue(ctx, result);
return JS_EXCEPTION;
}
JS_SetPropertyInt64(ctx, result, i, val);
JSArray *out = JS_VALUE_GET_ARRAY(result);
for (int i = 0; i < len; i++) {
out->values[i] = JS_DupValue(ctx, arr->values[i]);
}
out->len = len;
return result;
}
if (JS_IsFunction(argv[1])) {
/* Map */
JSValueConst func = argv[1];
int arity = (JSFunction*)JS_VALUE_GET_FUNCTION(argv[1])->length;
int arity = ((JSFunction*)JS_VALUE_GET_FUNCTION(argv[1]))->length;
int reverse = argc > 2 && JS_ToBool(ctx, argv[2]);
JSValue exit_val = argc > 3 ? argv[3] : JS_NULL;
JSValue result = JS_NewArrayLen(ctx, len);
JSValue result = JS_NewArray(ctx);
if (JS_IsException(result)) return result;
JSArray *out = JS_VALUE_GET_ARRAY(result);
if (arity >= 2) {
if (reverse) {
int64_t out_idx = 0;
for (int64_t i = len - 1; i >= 0; i--) {
JSValue item = JS_GetPropertyInt64(ctx, arg, i);
if (JS_IsException(item)) {
for (int i = len - 1; i >= 0; i--) {
JSValue args[2] = { JS_DupValue(ctx, arr->values[i]), JS_NewInt32(ctx, i) };
JSValue val = JS_CallInternal(ctx, func, JS_NULL, 2, args, 0);
JS_FreeValue(ctx, args[0]);
JS_FreeValue(ctx, args[1]);
if (JS_IsException(val)) {
JS_FreeValue(ctx, result);
return JS_EXCEPTION;
}
JSValue val;
if (arity >= 2) {
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
val = JS_Call(ctx, func, JS_NULL, 2, args);
JS_FreeValue(ctx, args[1]);
} else {
val = JS_Call(ctx, func, JS_NULL, 1, &item);
if (!JS_IsNull(exit_val) && js_strict_eq(ctx, val, exit_val)) {
JS_FreeValue(ctx, val);
break;
}
js_intrinsic_array_push(ctx, out, val);
}
} else {
for (int i = 0; i < len; i++) {
JSValue args[2] = { JS_DupValue(ctx, arr->values[i]), JS_NewInt32(ctx, i) };
JSValue val = JS_CallInternal(ctx, func, JS_NULL, 2, args, 0);
JS_FreeValue(ctx, args[0]);
JS_FreeValue(ctx, args[1]);
if (JS_IsException(val)) {
JS_FreeValue(ctx, result);
return JS_EXCEPTION;
}
if (!JS_IsNull(exit_val) && js_strict_eq(ctx, val, exit_val)) {
JS_FreeValue(ctx, val);
break;
}
js_intrinsic_array_push(ctx, out, val);
}
}
} else {
if (reverse) {
for (int i = len - 1; i >= 0; i--) {
JSValue item = JS_DupValue(ctx, arr->values[i]);
JSValue val = JS_CallInternal(ctx, func, JS_NULL, 1, &item, 0);
JS_FreeValue(ctx, item);
if (JS_IsException(val)) {
JS_FreeValue(ctx, result);
@@ -27732,24 +27758,12 @@ static JSValue js_cell_array(JSContext *ctx, JSValueConst this_val,
JS_FreeValue(ctx, val);
break;
}
JS_SetPropertyInt64(ctx, result, out_idx++, val);
js_intrinsic_array_push(ctx, out, val);
}
} else {
int64_t out_idx = 0;
for (int64_t i = 0; i < len; i++) {
JSValue item = JS_GetPropertyInt64(ctx, arg, i);
if (JS_IsException(item)) {
JS_FreeValue(ctx, result);
return JS_EXCEPTION;
}
JSValue val;
if (arity >= 2) {
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
val = JS_Call(ctx, func, JS_NULL, 2, args);
JS_FreeValue(ctx, args[1]);
} else {
val = JS_Call(ctx, func, JS_NULL, 1, &item);
}
for (int i = 0; i < len; i++) {
JSValue item = JS_DupValue(ctx, arr->values[i]);
JSValue val = JS_CallInternal(ctx, func, JS_NULL, 1, &item, 0);
JS_FreeValue(ctx, item);
if (JS_IsException(val)) {
JS_FreeValue(ctx, result);
@@ -27759,7 +27773,8 @@ static JSValue js_cell_array(JSContext *ctx, JSValueConst this_val,
JS_FreeValue(ctx, val);
break;
}
JS_SetPropertyInt64(ctx, result, out_idx++, val);
js_intrinsic_array_push(ctx, out, val);
}
}
}
return result;
@@ -27767,64 +27782,51 @@ static JSValue js_cell_array(JSContext *ctx, JSValueConst this_val,
if (JS_IsArray(ctx, argv[1])) {
/* Concat */
int64_t len2;
if (js_get_length64(ctx, &len2, argv[1]))
return JS_EXCEPTION;
JSArray *arr2 = JS_VALUE_GET_ARRAY(argv[1]);
int len2 = arr2->len;
JSValue result = JS_NewArrayLen(ctx, len + len2);
if (JS_IsException(result)) return result;
JSArray *out = JS_VALUE_GET_ARRAY(result);
int64_t idx = 0;
for (int64_t i = 0; i < len; i++) {
JSValue val = JS_GetPropertyInt64(ctx, arg, i);
if (JS_IsException(val)) {
JS_FreeValue(ctx, result);
return JS_EXCEPTION;
for (int i = 0; i < len; i++) {
out->values[i] = JS_DupValue(ctx, arr->values[i]);
}
JS_SetPropertyInt64(ctx, result, idx++, val);
}
for (int64_t i = 0; i < len2; i++) {
JSValue val = JS_GetPropertyInt64(ctx, argv[1], i);
if (JS_IsException(val)) {
JS_FreeValue(ctx, result);
return JS_EXCEPTION;
}
JS_SetPropertyInt64(ctx, result, idx++, val);
for (int i = 0; i < len2; i++) {
out->values[len + i] = JS_DupValue(ctx, arr2->values[i]);
}
out->len = len + len2;
return result;
}
if (tag == JS_TAG_INT || tag == JS_TAG_FLOAT64 ||
JS_VALUE_GET_TAG(argv[1]) == JS_TAG_INT ||
JS_VALUE_GET_TAG(argv[1]) == JS_TAG_FLOAT64) {
if (JS_IsNumber(argv[1])) {
/* Slice */
int from, to;
if (JS_ToInt32(ctx, &from, argv[1]))
if (!JS_IsInteger(argv[1]))
return JS_NULL;
int from = JS_VALUE_GET_INT(argv[1]);
int to;
if (argc > 2 && !JS_IsNull(argv[2])) {
if (JS_ToInt32(ctx, &to, argv[2]))
if (!JS_IsNumber(argv[2]) || !JS_IsInteger(argv[2]))
return JS_NULL;
to = JS_VALUE_GET_INT(argv[2]);
} else {
to = len;
}
if (from < 0) from += len;
if (to < 0) to += len;
if (from < 0 || from > to || to > len)
if (from < 0 || from > len || to < 0 || to > len || from > to)
return JS_NULL;
JSValue result = JS_NewArrayLen(ctx, to - from);
int slice_len = to - from;
JSValue result = JS_NewArrayLen(ctx, slice_len);
if (JS_IsException(result)) return result;
JSArray *out = JS_VALUE_GET_ARRAY(result);
int64_t idx = 0;
for (int i = from; i < to; i++) {
JSValue val = JS_GetPropertyInt64(ctx, arg, i);
if (JS_IsException(val)) {
JS_FreeValue(ctx, result);
return JS_EXCEPTION;
}
JS_SetPropertyInt64(ctx, result, idx++, val);
for (int i = 0; i < slice_len; i++) {
out->values[i] = JS_DupValue(ctx, arr->values[from + i]);
}
out->len = slice_len;
return result;
}
@@ -27851,14 +27853,16 @@ static JSValue js_cell_array(JSContext *ctx, JSValueConst this_val,
if (JS_IsException(result)) {
return result;
}
JSArray *out = JS_VALUE_GET_ARRAY(result);
for (int i = 0; i < len; i++) {
JSValue ch = js_sub_string(ctx, p, i, i + 1);
if (JS_IsException(ch)) {
JS_FreeValue(ctx, result);
return JS_EXCEPTION;
}
JS_SetPropertyInt64(ctx, result, i, ch);
out->values[i] = ch;
}
out->len = len;
return result;
}
@@ -28099,46 +28103,34 @@ static JSValue js_cell_array_reduce(JSContext *ctx, JSValueConst this_val,
if (!JS_IsArray(ctx, argv[0])) return JS_NULL;
if (!JS_IsFunction(argv[1])) return JS_NULL;
JSValueConst arr = argv[0];
JSArray *arr = JS_VALUE_GET_ARRAY(argv[0]);
JSValueConst func = argv[1];
int64_t len;
if (js_get_length64(ctx, &len, arr))
return JS_EXCEPTION;
int len = arr->len;
int reverse = argc > 3 && JS_ToBool(ctx, argv[3]);
JSValue acc;
if (argc < 3 || JS_IsNull(argv[2])) {
if (len == 0) return JS_NULL;
if (len == 1) return JS_GetPropertyInt64(ctx, arr, 0);
if (len == 1) return JS_DupValue(ctx, arr->values[0]);
if (reverse) {
acc = JS_GetPropertyInt64(ctx, arr, len - 1);
for (int64_t i = len - 2; i >= 0; i--) {
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
if (JS_IsException(item)) {
JS_FreeValue(ctx, acc);
return JS_EXCEPTION;
}
JSValue args[2] = { acc, item };
JSValue new_acc = JS_Call(ctx, func, JS_NULL, 2, args);
JS_FreeValue(ctx, acc);
JS_FreeValue(ctx, item);
acc = JS_DupValue(ctx, arr->values[len - 1]);
for (int i = len - 2; i >= 0; i--) {
JSValue args[2] = { acc, JS_DupValue(ctx, arr->values[i]) };
JSValue new_acc = JS_CallInternal(ctx, func, JS_NULL, 2, args, 0);
JS_FreeValue(ctx, args[0]);
JS_FreeValue(ctx, args[1]);
if (JS_IsException(new_acc)) return JS_EXCEPTION;
acc = new_acc;
}
} else {
acc = JS_GetPropertyInt64(ctx, arr, 0);
for (int64_t i = 1; i < len; i++) {
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
if (JS_IsException(item)) {
JS_FreeValue(ctx, acc);
return JS_EXCEPTION;
}
JSValue args[2] = { acc, item };
JSValue new_acc = JS_Call(ctx, func, JS_NULL, 2, args);
JS_FreeValue(ctx, acc);
JS_FreeValue(ctx, item);
acc = JS_DupValue(ctx, arr->values[0]);
for (int i = 1; i < len; i++) {
JSValue args[2] = { acc, JS_DupValue(ctx, arr->values[i]) };
JSValue new_acc = JS_CallInternal(ctx, func, JS_NULL, 2, args, 0);
JS_FreeValue(ctx, args[0]);
JS_FreeValue(ctx, args[1]);
if (JS_IsException(new_acc)) return JS_EXCEPTION;
acc = new_acc;
}
@@ -28148,30 +28140,20 @@ static JSValue js_cell_array_reduce(JSContext *ctx, JSValueConst this_val,
acc = JS_DupValue(ctx, argv[2]);
if (reverse) {
for (int64_t i = len - 1; i >= 0; i--) {
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
if (JS_IsException(item)) {
JS_FreeValue(ctx, acc);
return JS_EXCEPTION;
}
JSValue args[2] = { acc, item };
JSValue new_acc = JS_Call(ctx, func, JS_NULL, 2, args);
JS_FreeValue(ctx, acc);
JS_FreeValue(ctx, item);
for (int i = len - 1; i >= 0; i--) {
JSValue args[2] = { acc, JS_DupValue(ctx, arr->values[i]) };
JSValue new_acc = JS_CallInternal(ctx, func, JS_NULL, 2, args, 0);
JS_FreeValue(ctx, args[0]);
JS_FreeValue(ctx, args[1]);
if (JS_IsException(new_acc)) return JS_EXCEPTION;
acc = new_acc;
}
} else {
for (int64_t i = 0; i < len; i++) {
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
if (JS_IsException(item)) {
JS_FreeValue(ctx, acc);
return JS_EXCEPTION;
}
JSValue args[2] = { acc, item };
JSValue new_acc = JS_Call(ctx, func, JS_NULL, 2, args);
JS_FreeValue(ctx, acc);
JS_FreeValue(ctx, item);
for (int i = 0; i < len; i++) {
JSValue args[2] = { acc, JS_DupValue(ctx, arr->values[i]) };
JSValue new_acc = JS_CallInternal(ctx, func, JS_NULL, 2, args, 0);
JS_FreeValue(ctx, args[0]);
JS_FreeValue(ctx, args[1]);
if (JS_IsException(new_acc)) return JS_EXCEPTION;
acc = new_acc;
}
@@ -28199,7 +28181,7 @@ static JSValue js_cell_array_for(JSContext *ctx, JSValueConst this_val,
JSValue exit_val = argc > 3 ? argv[3] : JS_NULL;
/* Determine function arity */
int arity = (JSFunction*)JS_VALUE_GET_FUNCTION(argv[1])->length;
int arity = ((JSFunction*)JS_VALUE_GET_FUNCTION(argv[1]))->length;
if (reverse) {
for (int i = len - 1; i >= 0; i--) {
@@ -28257,15 +28239,13 @@ static JSValue js_cell_array_find(JSContext *ctx, JSValueConst this_val,
if (argc < 2) return JS_NULL;
if (!JS_IsArray(ctx, argv[0])) return JS_NULL;
JSValueConst arr = argv[0];
int64_t len;
if (js_get_length64(ctx, &len, arr))
return JS_EXCEPTION;
JSArray *arr = JS_VALUE_GET_ARRAY(argv[0]);
int len = arr->len;
int reverse = argc > 2 && JS_ToBool(ctx, argv[2]);
int64_t from;
int from;
if (argc > 3 && !JS_IsNull(argv[3])) {
if (JS_ToInt64(ctx, &from, argv[3]))
if (JS_ToInt32(ctx, &from, argv[3]))
return JS_NULL;
} else {
from = reverse ? len - 1 : 0;
@@ -28275,24 +28255,14 @@ static JSValue js_cell_array_find(JSContext *ctx, JSValueConst this_val,
/* Compare exactly */
JSValue target = argv[1];
if (reverse) {
for (int64_t i = from; i >= 0; i--) {
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
if (JS_IsException(item)) return JS_EXCEPTION;
if (js_strict_eq(ctx, item, target)) {
JS_FreeValue(ctx, item);
return JS_NewInt64(ctx, i);
}
JS_FreeValue(ctx, item);
for (int i = from; i >= 0; i--) {
if (js_strict_eq(ctx, arr->values[i], target))
return JS_NewInt32(ctx, i);
}
} else {
for (int64_t i = from; i < len; i++) {
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
if (JS_IsException(item)) return JS_EXCEPTION;
if (js_strict_eq(ctx, item, target)) {
JS_FreeValue(ctx, item);
return JS_NewInt64(ctx, i);
}
JS_FreeValue(ctx, item);
for (int i = from; i < len; i++) {
if (js_strict_eq(ctx, arr->values[i], target))
return JS_NewInt32(ctx, i);
}
}
return JS_NULL;
@@ -28300,50 +28270,63 @@ static JSValue js_cell_array_find(JSContext *ctx, JSValueConst this_val,
/* Use function predicate */
JSValueConst func = argv[1];
int arity = (JSFunction*)JS_VALUE_GET_FUNCTION(argv[1])->length;
int arity = ((JSFunction*)JS_VALUE_GET_FUNCTION(argv[1]))->length;
if (arity == 2) {
if (reverse) {
for (int64_t i = from; i >= 0; i--) {
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
if (JS_IsException(item)) return JS_EXCEPTION;
JSValue result;
if (arity == 2) {
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
result = JS_Call(ctx, func, JS_NULL, 2, args);
for (int i = from; i >= 0; i--) {
JSValue args[2] = { JS_DupValue(ctx, arr->values[i]), JS_NewInt32(ctx, i) };
JSValue result = JS_CallInternal(ctx, func, JS_NULL, 2, args, 0);
JS_FreeValue(ctx, args[0]);
JS_FreeValue(ctx, args[1]);
} else {
result = JS_Call(ctx, func, JS_NULL, 1, &item);
}
JS_FreeValue(ctx, item);
if (JS_IsException(result)) return JS_EXCEPTION;
if (JS_ToBool(ctx, result)) {
JS_FreeValue(ctx, result);
return JS_NewInt64(ctx, i);
return JS_NewInt32(ctx, i);
}
JS_FreeValue(ctx, result);
}
} else {
for (int64_t i = from; i < len; i++) {
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
if (JS_IsException(item)) return JS_EXCEPTION;
JSValue result;
if (arity == 2) {
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
result = JS_Call(ctx, func, JS_NULL, 2, args);
for (int i = from; i < len; i++) {
JSValue args[2] = { JS_DupValue(ctx, arr->values[i]), JS_NewInt32(ctx, i) };
JSValue result = JS_CallInternal(ctx, func, JS_NULL, 2, args, 0);
JS_FreeValue(ctx, args[0]);
JS_FreeValue(ctx, args[1]);
} else {
result = JS_Call(ctx, func, JS_NULL, 1, &item);
}
JS_FreeValue(ctx, item);
if (JS_IsException(result)) return JS_EXCEPTION;
if (JS_ToBool(ctx, result)) {
JS_FreeValue(ctx, result);
return JS_NewInt64(ctx, i);
return JS_NewInt32(ctx, i);
}
JS_FreeValue(ctx, result);
}
}
} else {
if (reverse) {
for (int i = from; i >= 0; i--) {
JSValue item = JS_DupValue(ctx, arr->values[i]);
JSValue result = JS_CallInternal(ctx, func, JS_NULL, 1, &item, 0);
JS_FreeValue(ctx, item);
if (JS_IsException(result)) return JS_EXCEPTION;
if (JS_ToBool(ctx, result)) {
JS_FreeValue(ctx, result);
return JS_NewInt32(ctx, i);
}
JS_FreeValue(ctx, result);
}
} else {
for (int i = from; i < len; i++) {
JSValue item = JS_DupValue(ctx, arr->values[i]);
JSValue result = JS_CallInternal(ctx, func, JS_NULL, 1, &item, 0);
JS_FreeValue(ctx, item);
if (JS_IsException(result)) return JS_EXCEPTION;
if (JS_ToBool(ctx, result)) {
JS_FreeValue(ctx, result);
return JS_NewInt32(ctx, i);
}
JS_FreeValue(ctx, result);
}
}
}
return JS_NULL;
}
@@ -28356,34 +28339,44 @@ static JSValue js_cell_array_filter(JSContext *ctx, JSValueConst this_val,
if (!JS_IsArray(ctx, argv[0])) return JS_NULL;
if (!JS_IsFunction(argv[1])) return JS_NULL;
JSValueConst arr = argv[0];
JSArray *arr = JS_VALUE_GET_ARRAY(argv[0]);
JSValueConst func = argv[1];
int64_t len;
if (js_get_length64(ctx, &len, arr))
return JS_EXCEPTION;
int len = arr->len;
JSValue result = JS_NewArray(ctx);
if (JS_IsException(result)) return result;
JSArray *out = JS_VALUE_GET_ARRAY(result);
int arity = ((JSFunction*)JS_VALUE_GET_FUNCTION(func))->length;
int64_t out_idx = 0;
for (int64_t i = 0; i < len; i++) {
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
if (JS_IsException(item)) {
if (arity >= 2) {
for (int i = 0; i < len; i++) {
JSValue args[2] = { JS_DupValue(ctx, arr->values[i]), JS_NewInt32(ctx, i) };
JSValue val = JS_CallInternal(ctx, func, JS_NULL, 2, args, 0);
JS_FreeValue(ctx, args[1]);
if (JS_IsException(val)) {
JS_FreeValue(ctx, args[0]);
JS_FreeValue(ctx, result);
return JS_EXCEPTION;
}
JSValue val;
if (arity == 0) {
val = JS_Call(ctx, func, JS_NULL, 0, NULL);
} else if (arity == 1) {
val = JS_Call(ctx, func, JS_NULL, 1, &item);
if (JS_VALUE_GET_TAG(val) == JS_TAG_BOOL) {
if (JS_VALUE_GET_BOOL(val)) {
js_intrinsic_array_push(ctx, out, args[0]);
} else {
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
val = JS_Call(ctx, func, JS_NULL, 2, args);
JS_FreeValue(ctx, args[1]);
JS_FreeValue(ctx, args[0]);
}
} else {
JS_FreeValue(ctx, args[0]);
JS_FreeValue(ctx, val);
JS_FreeValue(ctx, result);
return JS_NULL;
}
JS_FreeValue(ctx, val);
}
} else if (arity == 1) {
for (int i = 0; i < len; i++) {
JSValue item = JS_DupValue(ctx, arr->values[i]);
JSValue val = JS_CallInternal(ctx, func, JS_NULL, 1, &item, 0);
if (JS_IsException(val)) {
JS_FreeValue(ctx, item);
JS_FreeValue(ctx, result);
@@ -28391,7 +28384,7 @@ static JSValue js_cell_array_filter(JSContext *ctx, JSValueConst this_val,
}
if (JS_VALUE_GET_TAG(val) == JS_TAG_BOOL) {
if (JS_VALUE_GET_BOOL(val)) {
JS_SetPropertyInt64(ctx, result, out_idx++, item);
js_intrinsic_array_push(ctx, out, item);
} else {
JS_FreeValue(ctx, item);
}
@@ -28403,6 +28396,25 @@ static JSValue js_cell_array_filter(JSContext *ctx, JSValueConst this_val,
}
JS_FreeValue(ctx, val);
}
} else {
for (int i = 0; i < len; i++) {
JSValue val = JS_CallInternal(ctx, func, JS_NULL, 0, NULL, 0);
if (JS_IsException(val)) {
JS_FreeValue(ctx, result);
return JS_EXCEPTION;
}
if (JS_VALUE_GET_TAG(val) == JS_TAG_BOOL) {
if (JS_VALUE_GET_BOOL(val)) {
js_intrinsic_array_push(ctx, out, JS_DupValue(ctx, arr->values[i]));
}
} else {
JS_FreeValue(ctx, val);
JS_FreeValue(ctx, result);
return JS_NULL;
}
JS_FreeValue(ctx, val);
}
}
return result;
}
@@ -28414,10 +28426,8 @@ static JSValue js_cell_array_sort(JSContext *ctx, JSValueConst this_val,
if (argc < 1) return JS_NULL;
if (!JS_IsArray(ctx, argv[0])) return JS_NULL;
JSValueConst arr = argv[0];
int64_t len;
if (js_get_length64(ctx, &len, arr))
return JS_EXCEPTION;
JSArray *arr = JS_VALUE_GET_ARRAY(argv[0]);
int len = arr->len;
/* Copy array */
JSValue result = JS_NewArrayLen(ctx, len);
@@ -28425,6 +28435,7 @@ static JSValue js_cell_array_sort(JSContext *ctx, JSValueConst this_val,
if (len == 0) return result;
JSArray *out = JS_VALUE_GET_ARRAY(result);
JSValue *items = js_malloc(ctx, sizeof(JSValue) * len);
double *keys = js_malloc(ctx, sizeof(double) * len);
char **str_keys = NULL;
@@ -28437,16 +28448,14 @@ static JSValue js_cell_array_sort(JSContext *ctx, JSValueConst this_val,
return JS_EXCEPTION;
}
/* Check if we have a key selector array */
JSArray *key_arr = NULL;
if (argc >= 2 && JS_IsArray(ctx, argv[1]))
key_arr = JS_VALUE_GET_ARRAY(argv[1]);
/* Extract keys */
for (int64_t i = 0; i < len; i++) {
items[i] = JS_GetPropertyInt64(ctx, arr, i);
if (JS_IsException(items[i])) {
for (int64_t j = 0; j < i; j++) JS_FreeValue(ctx, items[j]);
js_free(ctx, items);
js_free(ctx, keys);
JS_FreeValue(ctx, result);
return JS_EXCEPTION;
}
for (int i = 0; i < len; i++) {
items[i] = JS_DupValue(ctx, arr->values[i]);
JSValue key;
if (argc < 2 || JS_IsNull(argv[1])) {
@@ -28455,17 +28464,28 @@ static JSValue js_cell_array_sort(JSContext *ctx, JSValueConst this_val,
/* Numeric index - use for nested arrays */
int32_t idx;
JS_ToInt32(ctx, &idx, argv[1]);
if (JS_IsArray(ctx, items[i])) {
JSArray *nested = JS_VALUE_GET_ARRAY(items[i]);
if (idx >= 0 && idx < (int)nested->len)
key = JS_DupValue(ctx, nested->values[idx]);
else
key = JS_NULL;
} else {
key = JS_GetPropertyInt64(ctx, items[i], idx);
}
} else if (JS_VALUE_GET_TAG(argv[1]) == JS_TAG_STRING) {
key = JS_GetProperty(ctx, items[i], JS_ValueToAtom(ctx, argv[1]));
} else if (JS_IsArray(ctx, argv[1])) {
key = JS_GetPropertyInt64(ctx, argv[1], i);
} else if (key_arr) {
if (i < (int)key_arr->len)
key = JS_DupValue(ctx, key_arr->values[i]);
else
key = JS_NULL;
} else {
key = JS_DupValue(ctx, items[i]);
}
if (JS_IsException(key)) {
for (int64_t j = 0; j <= i; j++) JS_FreeValue(ctx, items[j]);
for (int j = 0; j <= i; j++) JS_FreeValue(ctx, items[j]);
js_free(ctx, items);
js_free(ctx, keys);
JS_FreeValue(ctx, result);
@@ -28482,7 +28502,7 @@ static JSValue js_cell_array_sort(JSContext *ctx, JSValueConst this_val,
str_keys = js_malloc(ctx, sizeof(char*) * len);
if (!str_keys) {
JS_FreeValue(ctx, key);
for (int64_t j = 0; j <= i; j++) JS_FreeValue(ctx, items[j]);
for (int j = 0; j <= i; j++) JS_FreeValue(ctx, items[j]);
js_free(ctx, items);
js_free(ctx, keys);
JS_FreeValue(ctx, result);
@@ -28494,11 +28514,11 @@ static JSValue js_cell_array_sort(JSContext *ctx, JSValueConst this_val,
}
} else {
JS_FreeValue(ctx, key);
for (int64_t j = 0; j <= i; j++) JS_FreeValue(ctx, items[j]);
for (int j = 0; j <= i; j++) JS_FreeValue(ctx, items[j]);
js_free(ctx, items);
js_free(ctx, keys);
if (str_keys) {
for (int64_t j = 0; j < i; j++) JS_FreeCString(ctx, str_keys[j]);
for (int j = 0; j < i; j++) JS_FreeCString(ctx, str_keys[j]);
js_free(ctx, str_keys);
}
JS_FreeValue(ctx, result);
@@ -28508,24 +28528,24 @@ static JSValue js_cell_array_sort(JSContext *ctx, JSValueConst this_val,
}
/* Create index array */
int64_t *indices = js_malloc(ctx, sizeof(int64_t) * len);
int *indices = js_malloc(ctx, sizeof(int) * len);
if (!indices) {
for (int64_t j = 0; j < len; j++) JS_FreeValue(ctx, items[j]);
for (int j = 0; j < len; j++) JS_FreeValue(ctx, items[j]);
js_free(ctx, items);
js_free(ctx, keys);
if (str_keys) {
for (int64_t j = 0; j < len; j++) JS_FreeCString(ctx, str_keys[j]);
for (int j = 0; j < len; j++) JS_FreeCString(ctx, str_keys[j]);
js_free(ctx, str_keys);
}
JS_FreeValue(ctx, result);
return JS_EXCEPTION;
}
for (int64_t i = 0; i < len; i++) indices[i] = i;
for (int i = 0; i < len; i++) indices[i] = i;
/* Simple insertion sort (stable) */
for (int64_t i = 1; i < len; i++) {
int64_t temp = indices[i];
int64_t j = i - 1;
for (int i = 1; i < len; i++) {
int temp = indices[i];
int j = i - 1;
while (j >= 0) {
int cmp;
if (is_string) {
@@ -28541,18 +28561,19 @@ static JSValue js_cell_array_sort(JSContext *ctx, JSValueConst this_val,
indices[j + 1] = temp;
}
/* Build sorted array */
for (int64_t i = 0; i < len; i++) {
JS_SetPropertyInt64(ctx, result, i, JS_DupValue(ctx, items[indices[i]]));
/* Build sorted array directly into output */
for (int i = 0; i < len; i++) {
out->values[i] = JS_DupValue(ctx, items[indices[i]]);
}
out->len = len;
/* Cleanup */
for (int64_t i = 0; i < len; i++) JS_FreeValue(ctx, items[i]);
for (int i = 0; i < len; i++) JS_FreeValue(ctx, items[i]);
js_free(ctx, items);
js_free(ctx, keys);
js_free(ctx, indices);
if (str_keys) {
for (int64_t i = 0; i < len; i++) JS_FreeCString(ctx, str_keys[i]);
for (int i = 0; i < len; i++) JS_FreeCString(ctx, str_keys[i]);
js_free(ctx, str_keys);
}
@@ -28648,18 +28669,11 @@ static JSValue js_cell_object(JSContext *ctx, JSValueConst this_val,
JSValue result = JS_NewObject(ctx);
if (JS_IsException(result)) return result;
int64_t len;
if (js_get_length64(ctx, &len, argv[1])) {
JS_FreeValue(ctx, result);
return JS_EXCEPTION;
}
JSArray *keys = JS_VALUE_GET_ARRAY(argv[1]);
int len = keys->len;
for (int64_t i = 0; i < len; i++) {
JSValue key = JS_GetPropertyInt64(ctx, argv[1], i);
if (JS_IsException(key)) {
JS_FreeValue(ctx, result);
return JS_EXCEPTION;
}
for (int i = 0; i < len; i++) {
JSValue key = keys->values[i];
int key_tag = JS_VALUE_GET_TAG(key);
if (key_tag == JS_TAG_STRING || key_tag == JS_TAG_STRING_ROPE) {
JSAtom atom = JS_ValueToAtom(ctx, key);
@@ -28672,7 +28686,6 @@ static JSValue js_cell_object(JSContext *ctx, JSValueConst this_val,
}
JS_FreeAtom(ctx, atom);
}
JS_FreeValue(ctx, key);
}
return result;
}
@@ -28682,30 +28695,28 @@ static JSValue js_cell_object(JSContext *ctx, JSValueConst this_val,
/* object(array_of_keys, value) - value set */
/* object(array_of_keys, function) - functional value set */
if (JS_IsArray(ctx, arg)) {
int64_t len;
if (js_get_length64(ctx, &len, arg))
return JS_EXCEPTION;
JSArray *keys = JS_VALUE_GET_ARRAY(arg);
int len = keys->len;
JSValue result = JS_NewObject(ctx);
if (JS_IsException(result)) return result;
for (int64_t i = 0; i < len; i++) {
JSValue key = JS_GetPropertyInt64(ctx, arg, i);
if (JS_IsException(key)) {
JS_FreeValue(ctx, result);
return JS_EXCEPTION;
}
int is_func = argc >= 2 && JS_IsFunction(argv[1]);
for (int i = 0; i < len; i++) {
JSValue key = keys->values[i];
int key_tag = JS_VALUE_GET_TAG(key);
if (key_tag == JS_TAG_STRING || key_tag == JS_TAG_STRING_ROPE) {
JSAtom atom = JS_ValueToAtom(ctx, key);
JSValue val;
if (argc < 2 || JS_IsNull(argv[1])) {
val = JS_TRUE;
} else if (JS_IsFunction(argv[1])) {
val = JS_Call(ctx, argv[1], JS_NULL, 1, &key);
} else if (is_func) {
JSValue arg_key = JS_DupValue(ctx, key);
val = JS_CallInternal(ctx, argv[1], JS_NULL, 1, &arg_key, 0);
JS_FreeValue(ctx, arg_key);
if (JS_IsException(val)) {
JS_FreeAtom(ctx, atom);
JS_FreeValue(ctx, key);
JS_FreeValue(ctx, result);
return JS_EXCEPTION;
}
@@ -28715,7 +28726,6 @@ static JSValue js_cell_object(JSContext *ctx, JSValueConst this_val,
JS_SetProperty(ctx, result, atom, val);
JS_FreeAtom(ctx, atom);
}
JS_FreeValue(ctx, key);
}
return result;
}
@@ -28737,34 +28747,35 @@ static JSValue js_cell_fn_apply(JSContext *ctx, JSValueConst this_val,
JSValueConst func = argv[0];
if (argc < 2) {
return JS_Call(ctx, func, JS_NULL, 0, NULL);
return JS_CallInternal(ctx, func, JS_NULL, 0, NULL, 0);
}
JSValue args_val = argv[1];
if (!JS_IsArray(ctx, args_val)) {
/* Wrap single value in array */
return JS_Call(ctx, func, JS_NULL, 1, &args_val);
JSValue arg = JS_DupValue(ctx, args_val);
JSValue result = JS_CallInternal(ctx, func, JS_NULL, 1, &arg, 0);
JS_FreeValue(ctx, arg);
return result;
}
int64_t len;
if (js_get_length64(ctx, &len, args_val))
return JS_EXCEPTION;
JSArray *arr = JS_VALUE_GET_ARRAY(args_val);
int len = arr->len;
JSValue *args = js_malloc(ctx, sizeof(JSValue) * (len > 0 ? len : 1));
if (len == 0) {
return JS_CallInternal(ctx, func, JS_NULL, 0, NULL, 0);
}
JSValue *args = js_malloc(ctx, sizeof(JSValue) * len);
if (!args) return JS_EXCEPTION;
for (int64_t i = 0; i < len; i++) {
args[i] = JS_GetPropertyInt64(ctx, args_val, i);
if (JS_IsException(args[i])) {
for (int64_t j = 0; j < i; j++) JS_FreeValue(ctx, args[j]);
js_free(ctx, args);
return JS_EXCEPTION;
}
for (int i = 0; i < len; i++) {
args[i] = JS_DupValue(ctx, arr->values[i]);
}
JSValue result = JS_Call(ctx, func, JS_NULL, len, args);
JSValue result = JS_CallInternal(ctx, func, JS_NULL, len, args, 0);
for (int64_t i = 0; i < len; i++) JS_FreeValue(ctx, args[i]);
for (int i = 0; i < len; i++) JS_FreeValue(ctx, args[i]);
js_free(ctx, args);
return result;
@@ -29419,16 +29430,16 @@ static JSValue js_cell_reverse(JSContext *ctx, JSValueConst this_val,
/* Handle arrays */
if (JS_IsArray(ctx, value)) {
int64_t len;
if (js_get_length64(ctx, &len, value))
return JS_NULL;
JSArray *arr = JS_VALUE_GET_ARRAY(value);
int len = arr->len;
JSValue result = JS_NewArrayLen(ctx, len);
if (JS_IsException(result)) return result;
for (int64_t i = len - 1, j = 0; i >= 0; i--, j++) {
JSValue elem = JS_GetPropertyInt64(ctx, value, i);
JS_SetPropertyInt64(ctx, result, j, elem);
JSArray *out = JS_VALUE_GET_ARRAY(result);
for (int i = len - 1, j = 0; i >= 0; i--, j++) {
out->values[j] = JS_DupValue(ctx, arr->values[i]);
}
out->len = len;
return result;
}
@@ -29758,10 +29769,8 @@ static JSValue js_cell_length(JSContext *ctx, JSValueConst this_val,
/* Arrays return element count */
if (JS_IsArray(ctx, val)) {
int64_t len;
if (js_get_length64(ctx, &len, val) < 0)
return JS_EXCEPTION;
return JS_NewInt64(ctx, len);
JSArray *arr = JS_VALUE_GET_ARRAY(val);
return JS_NewInt32(ctx, arr->len);
}
/* Objects with length property */
@@ -29804,7 +29813,7 @@ static JSValue js_cell_call(JSContext *ctx, JSValueConst this_val,
this_arg = argv[1];
if (argc < 3 || JS_IsNull(argv[2]))
return JS_Call(ctx, func, this_arg, 0, NULL);
return JS_CallInternal(ctx, func, this_arg, 0, NULL, 0);
if (!JS_IsArray(ctx, argv[2]))
return JS_ThrowTypeError(ctx, "third argument must be an array");
@@ -29814,7 +29823,7 @@ static JSValue js_cell_call(JSContext *ctx, JSValueConst this_val,
if (!tab)
return JS_EXCEPTION;
JSValue ret = JS_Call(ctx, func, this_arg, len, (JSValueConst *)tab);
JSValue ret = JS_CallInternal(ctx, func, this_arg, len, tab, 0);
free_arg_list(ctx, tab, len);
return ret;
}

View File

@@ -545,6 +545,11 @@ static inline JS_BOOL JS_IsFunction(JSValueConst v)
return JS_VALUE_GET_TAG(v) == JS_TAG_FUNCTION;
}
static inline JS_BOOL JS_IsInteger(JSValueConst v)
{
return JS_VALUE_GET_TAG(v) == JS_TAG_INT;
}
static inline JS_BOOL JS_IsObject(JSValueConst v)
{
return JS_VALUE_GET_TAG(v) == JS_TAG_OBJECT;