MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

array methods!

+1445 -11
+1 -1
meson.build
··· 74 74 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 75 75 76 76 version_conf = configuration_data() 77 - version_conf.set('ANT_VERSION', '0.1.0.19') 77 + version_conf.set('ANT_VERSION', '0.1.0.20') 78 78 version_conf.set('ANT_GIT_HASH', git_hash) 79 79 version_conf.set('ANT_BUILD_DATE', build_date) 80 80
+1444 -10
src/ant.c
··· 366 366 static jsval_t builtin_array_join(struct js *js, jsval_t *args, int nargs); 367 367 static jsval_t builtin_array_includes(struct js *js, jsval_t *args, int nargs); 368 368 static jsval_t builtin_array_every(struct js *js, jsval_t *args, int nargs); 369 + static jsval_t builtin_array_reverse(struct js *js, jsval_t *args, int nargs); 370 + static jsval_t builtin_array_map(struct js *js, jsval_t *args, int nargs); 371 + static jsval_t builtin_array_filter(struct js *js, jsval_t *args, int nargs); 372 + static jsval_t builtin_array_reduce(struct js *js, jsval_t *args, int nargs); 373 + static jsval_t builtin_array_flat(struct js *js, jsval_t *args, int nargs); 374 + static jsval_t builtin_array_concat(struct js *js, jsval_t *args, int nargs); 375 + static jsval_t builtin_array_at(struct js *js, jsval_t *args, int nargs); 376 + static jsval_t builtin_array_fill(struct js *js, jsval_t *args, int nargs); 377 + static jsval_t builtin_array_find(struct js *js, jsval_t *args, int nargs); 378 + static jsval_t builtin_array_findIndex(struct js *js, jsval_t *args, int nargs); 379 + static jsval_t builtin_array_findLast(struct js *js, jsval_t *args, int nargs); 380 + static jsval_t builtin_array_findLastIndex(struct js *js, jsval_t *args, int nargs); 381 + static jsval_t builtin_array_flatMap(struct js *js, jsval_t *args, int nargs); 382 + static jsval_t builtin_array_forEach(struct js *js, jsval_t *args, int nargs); 383 + static jsval_t builtin_array_indexOf(struct js *js, jsval_t *args, int nargs); 384 + static jsval_t builtin_array_lastIndexOf(struct js *js, jsval_t *args, int nargs); 385 + static jsval_t builtin_array_reduceRight(struct js *js, jsval_t *args, int nargs); 386 + static jsval_t builtin_array_shift(struct js *js, jsval_t *args, int nargs); 387 + static jsval_t builtin_array_unshift(struct js *js, jsval_t *args, int nargs); 388 + static jsval_t builtin_array_some(struct js *js, jsval_t *args, int nargs); 389 + static jsval_t builtin_array_sort(struct js *js, jsval_t *args, int nargs); 390 + static jsval_t builtin_array_splice(struct js *js, jsval_t *args, int nargs); 391 + static jsval_t builtin_array_copyWithin(struct js *js, jsval_t *args, int nargs); 392 + static jsval_t builtin_array_toReversed(struct js *js, jsval_t *args, int nargs); 393 + static jsval_t builtin_array_toSorted(struct js *js, jsval_t *args, int nargs); 394 + static jsval_t builtin_array_toSpliced(struct js *js, jsval_t *args, int nargs); 395 + static jsval_t builtin_array_with(struct js *js, jsval_t *args, int nargs); 396 + static jsval_t builtin_array_keys(struct js *js, jsval_t *args, int nargs); 397 + static jsval_t builtin_array_values(struct js *js, jsval_t *args, int nargs); 398 + static jsval_t builtin_array_entries(struct js *js, jsval_t *args, int nargs); 399 + static jsval_t builtin_array_toString(struct js *js, jsval_t *args, int nargs); 400 + static jsval_t builtin_Array_isArray(struct js *js, jsval_t *args, int nargs); 401 + static jsval_t builtin_Array_from(struct js *js, jsval_t *args, int nargs); 402 + static jsval_t builtin_Array_of(struct js *js, jsval_t *args, int nargs); 369 403 static jsval_t builtin_Error(struct js *js, jsval_t *args, int nargs); 370 404 static jsval_t js_import_stmt(struct js *js); 371 405 static jsval_t js_export_stmt(struct js *js); ··· 5087 5121 case TOK_WINDOW: 5088 5122 case TOK_GLOBAL_THIS: return js_glob(js); 5089 5123 5090 - case TOK_TYPEOF: return mkcoderef((jsoff_t) js->toff, (jsoff_t) js->tlen); 5091 - case TOK_FROM: return mkcoderef((jsoff_t) js->toff, (jsoff_t) js->tlen); 5092 - case TOK_VOID: return mkcoderef((jsoff_t) js->toff, (jsoff_t) js->tlen); 5093 - case TOK_DELETE: return mkcoderef((jsoff_t) js->toff, (jsoff_t) js->tlen); 5094 - case TOK_IMPORT: return mkcoderef((jsoff_t) js->toff, (jsoff_t) js->tlen); 5095 - case TOK_IDENTIFIER: return mkcoderef((jsoff_t) js->toff, (jsoff_t) js->tlen); 5096 - case TOK_CATCH: return mkcoderef((jsoff_t) js->toff, (jsoff_t) js->tlen); 5097 - case TOK_TRY: return mkcoderef((jsoff_t) js->toff, (jsoff_t) js->tlen); 5098 - case TOK_FINALLY: return mkcoderef((jsoff_t) js->toff, (jsoff_t) js->tlen); 5124 + case TOK_OF: 5125 + case TOK_WITH: 5126 + case TOK_TYPEOF: 5127 + case TOK_FROM: 5128 + case TOK_VOID: 5129 + case TOK_DELETE: 5130 + case TOK_IMPORT: 5131 + case TOK_IDENTIFIER: 5132 + case TOK_CATCH: 5133 + case TOK_TRY: 5134 + case TOK_FINALLY: return mkcoderef((jsoff_t) js->toff, (jsoff_t) js->tlen); 5099 5135 5100 - default: return js_mkerr(js, "bad expr"); 5136 + default: return js_mkerr(js, "bad expr"); 5101 5137 } 5102 5138 } 5103 5139 ··· 9166 9202 return mkval(T_BOOL, 1); 9167 9203 } 9168 9204 9205 + static jsval_t builtin_array_reverse(struct js *js, jsval_t *args, int nargs) { 9206 + (void) args; 9207 + (void) nargs; 9208 + jsval_t arr = js->this_val; 9209 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9210 + return js_mkerr(js, "reverse called on non-array"); 9211 + } 9212 + 9213 + jsoff_t off = lkp(js, arr, "length", 6); 9214 + jsoff_t len = 0; 9215 + if (off != 0) { 9216 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9217 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9218 + } 9219 + 9220 + for (jsoff_t i = 0; i < len / 2; i++) { 9221 + jsoff_t j = len - 1 - i; 9222 + char idx_i[16], idx_j[16]; 9223 + snprintf(idx_i, sizeof(idx_i), "%u", (unsigned) i); 9224 + snprintf(idx_j, sizeof(idx_j), "%u", (unsigned) j); 9225 + 9226 + jsoff_t off_i = lkp(js, arr, idx_i, strlen(idx_i)); 9227 + jsoff_t off_j = lkp(js, arr, idx_j, strlen(idx_j)); 9228 + 9229 + jsval_t val_i = off_i ? resolveprop(js, mkval(T_PROP, off_i)) : js_mkundef(); 9230 + jsval_t val_j = off_j ? resolveprop(js, mkval(T_PROP, off_j)) : js_mkundef(); 9231 + 9232 + jsval_t key_i = js_mkstr(js, idx_i, strlen(idx_i)); 9233 + jsval_t key_j = js_mkstr(js, idx_j, strlen(idx_j)); 9234 + setprop(js, arr, key_i, val_j); 9235 + setprop(js, arr, key_j, val_i); 9236 + } 9237 + 9238 + return arr; 9239 + } 9240 + 9241 + static jsval_t builtin_array_map(struct js *js, jsval_t *args, int nargs) { 9242 + jsval_t arr = js->this_val; 9243 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9244 + return js_mkerr(js, "map called on non-array"); 9245 + } 9246 + 9247 + if (nargs == 0 || vtype(args[0]) != T_FUNC) { 9248 + return js_mkerr(js, "map requires a function argument"); 9249 + } 9250 + 9251 + jsval_t callback = args[0]; 9252 + jsoff_t off = lkp(js, arr, "length", 6); 9253 + jsoff_t len = 0; 9254 + if (off != 0) { 9255 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9256 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9257 + } 9258 + 9259 + jsval_t result = mkarr(js); 9260 + if (is_err(result)) return result; 9261 + 9262 + for (jsoff_t i = 0; i < len; i++) { 9263 + char idxstr[16]; 9264 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 9265 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 9266 + 9267 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 9268 + jsval_t call_args[3] = { elem, tov((double)i), arr }; 9269 + jsval_t mapped = call_js_with_args(js, callback, call_args, 3); 9270 + if (is_err(mapped)) return mapped; 9271 + 9272 + jsval_t key = js_mkstr(js, idxstr, strlen(idxstr)); 9273 + setprop(js, result, key, mapped); 9274 + } 9275 + 9276 + jsval_t len_key = js_mkstr(js, "length", 6); 9277 + setprop(js, result, len_key, tov((double) len)); 9278 + return mkval(T_ARR, vdata(result)); 9279 + } 9280 + 9281 + static jsval_t builtin_array_filter(struct js *js, jsval_t *args, int nargs) { 9282 + jsval_t arr = js->this_val; 9283 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9284 + return js_mkerr(js, "filter called on non-array"); 9285 + } 9286 + 9287 + if (nargs == 0 || vtype(args[0]) != T_FUNC) { 9288 + return js_mkerr(js, "filter requires a function argument"); 9289 + } 9290 + 9291 + jsval_t callback = args[0]; 9292 + jsoff_t off = lkp(js, arr, "length", 6); 9293 + jsoff_t len = 0; 9294 + if (off != 0) { 9295 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9296 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9297 + } 9298 + 9299 + jsval_t result = mkarr(js); 9300 + if (is_err(result)) return result; 9301 + jsoff_t result_idx = 0; 9302 + 9303 + for (jsoff_t i = 0; i < len; i++) { 9304 + char idxstr[16]; 9305 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 9306 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 9307 + 9308 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 9309 + jsval_t call_args[3] = { elem, tov((double)i), arr }; 9310 + jsval_t test = call_js_with_args(js, callback, call_args, 3); 9311 + if (is_err(test)) return test; 9312 + 9313 + if (js_truthy(js, test)) { 9314 + char res_idx[16]; 9315 + snprintf(res_idx, sizeof(res_idx), "%u", (unsigned) result_idx); 9316 + jsval_t key = js_mkstr(js, res_idx, strlen(res_idx)); 9317 + setprop(js, result, key, elem); 9318 + result_idx++; 9319 + } 9320 + } 9321 + 9322 + jsval_t len_key = js_mkstr(js, "length", 6); 9323 + setprop(js, result, len_key, tov((double) result_idx)); 9324 + return mkval(T_ARR, vdata(result)); 9325 + } 9326 + 9327 + static jsval_t builtin_array_reduce(struct js *js, jsval_t *args, int nargs) { 9328 + jsval_t arr = js->this_val; 9329 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9330 + return js_mkerr(js, "reduce called on non-array"); 9331 + } 9332 + 9333 + if (nargs == 0 || vtype(args[0]) != T_FUNC) { 9334 + return js_mkerr(js, "reduce requires a function argument"); 9335 + } 9336 + 9337 + jsval_t callback = args[0]; 9338 + jsoff_t off = lkp(js, arr, "length", 6); 9339 + jsoff_t len = 0; 9340 + if (off != 0) { 9341 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9342 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9343 + } 9344 + 9345 + jsoff_t start_idx = 0; 9346 + jsval_t accumulator; 9347 + 9348 + if (nargs >= 2) { 9349 + accumulator = args[1]; 9350 + } else { 9351 + if (len == 0) return js_mkerr(js, "reduce of empty array with no initial value"); 9352 + char idxstr[16]; 9353 + snprintf(idxstr, sizeof(idxstr), "%u", 0u); 9354 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 9355 + accumulator = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 9356 + start_idx = 1; 9357 + } 9358 + 9359 + for (jsoff_t i = start_idx; i < len; i++) { 9360 + char idxstr[16]; 9361 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 9362 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 9363 + 9364 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 9365 + jsval_t call_args[4] = { accumulator, elem, tov((double)i), arr }; 9366 + accumulator = call_js_with_args(js, callback, call_args, 4); 9367 + if (is_err(accumulator)) return accumulator; 9368 + } 9369 + 9370 + return accumulator; 9371 + } 9372 + 9373 + static void flat_helper(struct js *js, jsval_t arr, jsval_t result, jsoff_t *result_idx, int depth) { 9374 + jsoff_t off = lkp(js, arr, "length", 6); 9375 + jsoff_t len = 0; 9376 + if (off != 0) { 9377 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9378 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9379 + } 9380 + 9381 + for (jsoff_t i = 0; i < len; i++) { 9382 + char idxstr[16]; 9383 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 9384 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 9385 + 9386 + if (elem_off != 0) { 9387 + jsval_t elem = resolveprop(js, mkval(T_PROP, elem_off)); 9388 + if (depth > 0 && (vtype(elem) == T_ARR || vtype(elem) == T_OBJ)) { 9389 + flat_helper(js, elem, result, result_idx, depth - 1); 9390 + } else { 9391 + char res_idx[16]; 9392 + snprintf(res_idx, sizeof(res_idx), "%u", (unsigned) *result_idx); 9393 + jsval_t key = js_mkstr(js, res_idx, strlen(res_idx)); 9394 + setprop(js, result, key, elem); 9395 + (*result_idx)++; 9396 + } 9397 + } 9398 + } 9399 + } 9400 + 9401 + static jsval_t builtin_array_flat(struct js *js, jsval_t *args, int nargs) { 9402 + jsval_t arr = js->this_val; 9403 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9404 + return js_mkerr(js, "flat called on non-array"); 9405 + } 9406 + 9407 + int depth = 1; 9408 + if (nargs >= 1 && vtype(args[0]) == T_NUM) { 9409 + depth = (int) tod(args[0]); 9410 + if (depth < 0) depth = 0; 9411 + } 9412 + 9413 + jsval_t result = mkarr(js); 9414 + if (is_err(result)) return result; 9415 + jsoff_t result_idx = 0; 9416 + 9417 + flat_helper(js, arr, result, &result_idx, depth); 9418 + 9419 + jsval_t len_key = js_mkstr(js, "length", 6); 9420 + setprop(js, result, len_key, tov((double) result_idx)); 9421 + return mkval(T_ARR, vdata(result)); 9422 + } 9423 + 9424 + static jsval_t builtin_array_concat(struct js *js, jsval_t *args, int nargs) { 9425 + jsval_t arr = js->this_val; 9426 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9427 + return js_mkerr(js, "concat called on non-array"); 9428 + } 9429 + 9430 + jsval_t result = mkarr(js); 9431 + if (is_err(result)) return result; 9432 + jsoff_t result_idx = 0; 9433 + 9434 + jsoff_t off = lkp(js, arr, "length", 6); 9435 + jsoff_t len = 0; 9436 + if (off != 0) { 9437 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9438 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9439 + } 9440 + 9441 + for (jsoff_t i = 0; i < len; i++) { 9442 + char idxstr[16]; 9443 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 9444 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 9445 + if (elem_off != 0) { 9446 + jsval_t elem = resolveprop(js, mkval(T_PROP, elem_off)); 9447 + char res_idx[16]; 9448 + snprintf(res_idx, sizeof(res_idx), "%u", (unsigned) result_idx); 9449 + jsval_t key = js_mkstr(js, res_idx, strlen(res_idx)); 9450 + setprop(js, result, key, elem); 9451 + } 9452 + result_idx++; 9453 + } 9454 + 9455 + for (int a = 0; a < nargs; a++) { 9456 + jsval_t arg = args[a]; 9457 + if (vtype(arg) == T_ARR || vtype(arg) == T_OBJ) { 9458 + jsoff_t arg_off = lkp(js, arg, "length", 6); 9459 + jsoff_t arg_len = 0; 9460 + if (arg_off != 0) { 9461 + jsval_t len_val = resolveprop(js, mkval(T_PROP, arg_off)); 9462 + if (vtype(len_val) == T_NUM) arg_len = (jsoff_t) tod(len_val); 9463 + } 9464 + 9465 + for (jsoff_t i = 0; i < arg_len; i++) { 9466 + char idxstr[16]; 9467 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 9468 + jsoff_t elem_off = lkp(js, arg, idxstr, strlen(idxstr)); 9469 + if (elem_off != 0) { 9470 + jsval_t elem = resolveprop(js, mkval(T_PROP, elem_off)); 9471 + char res_idx[16]; 9472 + snprintf(res_idx, sizeof(res_idx), "%u", (unsigned) result_idx); 9473 + jsval_t key = js_mkstr(js, res_idx, strlen(res_idx)); 9474 + setprop(js, result, key, elem); 9475 + } 9476 + result_idx++; 9477 + } 9478 + } else { 9479 + char res_idx[16]; 9480 + snprintf(res_idx, sizeof(res_idx), "%u", (unsigned) result_idx); 9481 + jsval_t key = js_mkstr(js, res_idx, strlen(res_idx)); 9482 + setprop(js, result, key, arg); 9483 + result_idx++; 9484 + } 9485 + } 9486 + 9487 + jsval_t len_key = js_mkstr(js, "length", 6); 9488 + setprop(js, result, len_key, tov((double) result_idx)); 9489 + return mkval(T_ARR, vdata(result)); 9490 + } 9491 + 9492 + static jsval_t builtin_array_at(struct js *js, jsval_t *args, int nargs) { 9493 + jsval_t arr = js->this_val; 9494 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9495 + return js_mkerr(js, "at called on non-array"); 9496 + } 9497 + 9498 + if (nargs == 0 || vtype(args[0]) != T_NUM) return js_mkundef(); 9499 + 9500 + jsoff_t off = lkp(js, arr, "length", 6); 9501 + jsoff_t len = 0; 9502 + if (off != 0) { 9503 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9504 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9505 + } 9506 + 9507 + int idx = (int) tod(args[0]); 9508 + if (idx < 0) idx = (int)len + idx; 9509 + if (idx < 0 || (jsoff_t)idx >= len) return js_mkundef(); 9510 + 9511 + char idxstr[16]; 9512 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) idx); 9513 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 9514 + return elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 9515 + } 9516 + 9517 + static jsval_t builtin_array_fill(struct js *js, jsval_t *args, int nargs) { 9518 + jsval_t arr = js->this_val; 9519 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9520 + return js_mkerr(js, "fill called on non-array"); 9521 + } 9522 + 9523 + jsval_t value = nargs >= 1 ? args[0] : js_mkundef(); 9524 + 9525 + jsoff_t off = lkp(js, arr, "length", 6); 9526 + jsoff_t len = 0; 9527 + if (off != 0) { 9528 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9529 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9530 + } 9531 + 9532 + jsoff_t start = 0, end = len; 9533 + if (nargs >= 2 && vtype(args[1]) == T_NUM) { 9534 + int s = (int) tod(args[1]); 9535 + if (s < 0) s = (int)len + s; 9536 + if (s < 0) s = 0; 9537 + start = (jsoff_t) s; 9538 + } 9539 + if (nargs >= 3 && vtype(args[2]) == T_NUM) { 9540 + int e = (int) tod(args[2]); 9541 + if (e < 0) e = (int)len + e; 9542 + if (e < 0) e = 0; 9543 + end = (jsoff_t) e; 9544 + } 9545 + if (start > len) start = len; 9546 + if (end > len) end = len; 9547 + 9548 + for (jsoff_t i = start; i < end; i++) { 9549 + char idxstr[16]; 9550 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 9551 + jsval_t key = js_mkstr(js, idxstr, strlen(idxstr)); 9552 + setprop(js, arr, key, value); 9553 + } 9554 + 9555 + return arr; 9556 + } 9557 + 9558 + static jsval_t builtin_array_find(struct js *js, jsval_t *args, int nargs) { 9559 + jsval_t arr = js->this_val; 9560 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9561 + return js_mkerr(js, "find called on non-array"); 9562 + } 9563 + if (nargs == 0 || vtype(args[0]) != T_FUNC) { 9564 + return js_mkerr(js, "find requires a function argument"); 9565 + } 9566 + 9567 + jsval_t callback = args[0]; 9568 + jsoff_t off = lkp(js, arr, "length", 6); 9569 + jsoff_t len = 0; 9570 + if (off != 0) { 9571 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9572 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9573 + } 9574 + 9575 + for (jsoff_t i = 0; i < len; i++) { 9576 + char idxstr[16]; 9577 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 9578 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 9579 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 9580 + jsval_t call_args[3] = { elem, tov((double)i), arr }; 9581 + jsval_t result = call_js_with_args(js, callback, call_args, 3); 9582 + if (is_err(result)) return result; 9583 + if (js_truthy(js, result)) return elem; 9584 + } 9585 + return js_mkundef(); 9586 + } 9587 + 9588 + static jsval_t builtin_array_findIndex(struct js *js, jsval_t *args, int nargs) { 9589 + jsval_t arr = js->this_val; 9590 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9591 + return js_mkerr(js, "findIndex called on non-array"); 9592 + } 9593 + if (nargs == 0 || vtype(args[0]) != T_FUNC) { 9594 + return js_mkerr(js, "findIndex requires a function argument"); 9595 + } 9596 + 9597 + jsval_t callback = args[0]; 9598 + jsoff_t off = lkp(js, arr, "length", 6); 9599 + jsoff_t len = 0; 9600 + if (off != 0) { 9601 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9602 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9603 + } 9604 + 9605 + for (jsoff_t i = 0; i < len; i++) { 9606 + char idxstr[16]; 9607 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 9608 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 9609 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 9610 + jsval_t call_args[3] = { elem, tov((double)i), arr }; 9611 + jsval_t result = call_js_with_args(js, callback, call_args, 3); 9612 + if (is_err(result)) return result; 9613 + if (js_truthy(js, result)) return tov((double)i); 9614 + } 9615 + return tov(-1); 9616 + } 9617 + 9618 + static jsval_t builtin_array_findLast(struct js *js, jsval_t *args, int nargs) { 9619 + jsval_t arr = js->this_val; 9620 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9621 + return js_mkerr(js, "findLast called on non-array"); 9622 + } 9623 + if (nargs == 0 || vtype(args[0]) != T_FUNC) { 9624 + return js_mkerr(js, "findLast requires a function argument"); 9625 + } 9626 + 9627 + jsval_t callback = args[0]; 9628 + jsoff_t off = lkp(js, arr, "length", 6); 9629 + jsoff_t len = 0; 9630 + if (off != 0) { 9631 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9632 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9633 + } 9634 + 9635 + for (jsoff_t i = len; i > 0; i--) { 9636 + char idxstr[16]; 9637 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned)(i - 1)); 9638 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 9639 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 9640 + jsval_t call_args[3] = { elem, tov((double)(i - 1)), arr }; 9641 + jsval_t result = call_js_with_args(js, callback, call_args, 3); 9642 + if (is_err(result)) return result; 9643 + if (js_truthy(js, result)) return elem; 9644 + } 9645 + return js_mkundef(); 9646 + } 9647 + 9648 + static jsval_t builtin_array_findLastIndex(struct js *js, jsval_t *args, int nargs) { 9649 + jsval_t arr = js->this_val; 9650 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9651 + return js_mkerr(js, "findLastIndex called on non-array"); 9652 + } 9653 + if (nargs == 0 || vtype(args[0]) != T_FUNC) { 9654 + return js_mkerr(js, "findLastIndex requires a function argument"); 9655 + } 9656 + 9657 + jsval_t callback = args[0]; 9658 + jsoff_t off = lkp(js, arr, "length", 6); 9659 + jsoff_t len = 0; 9660 + if (off != 0) { 9661 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9662 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9663 + } 9664 + 9665 + for (jsoff_t i = len; i > 0; i--) { 9666 + char idxstr[16]; 9667 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned)(i - 1)); 9668 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 9669 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 9670 + jsval_t call_args[3] = { elem, tov((double)(i - 1)), arr }; 9671 + jsval_t result = call_js_with_args(js, callback, call_args, 3); 9672 + if (is_err(result)) return result; 9673 + if (js_truthy(js, result)) return tov((double)(i - 1)); 9674 + } 9675 + return tov(-1); 9676 + } 9677 + 9678 + static jsval_t builtin_array_flatMap(struct js *js, jsval_t *args, int nargs) { 9679 + jsval_t arr = js->this_val; 9680 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9681 + return js_mkerr(js, "flatMap called on non-array"); 9682 + } 9683 + if (nargs == 0 || vtype(args[0]) != T_FUNC) { 9684 + return js_mkerr(js, "flatMap requires a function argument"); 9685 + } 9686 + 9687 + jsval_t callback = args[0]; 9688 + jsoff_t off = lkp(js, arr, "length", 6); 9689 + jsoff_t len = 0; 9690 + if (off != 0) { 9691 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9692 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9693 + } 9694 + 9695 + jsval_t result = mkarr(js); 9696 + if (is_err(result)) return result; 9697 + jsoff_t result_idx = 0; 9698 + 9699 + for (jsoff_t i = 0; i < len; i++) { 9700 + char idxstr[16]; 9701 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 9702 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 9703 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 9704 + jsval_t call_args[3] = { elem, tov((double)i), arr }; 9705 + jsval_t mapped = call_js_with_args(js, callback, call_args, 3); 9706 + if (is_err(mapped)) return mapped; 9707 + 9708 + if (vtype(mapped) == T_ARR || vtype(mapped) == T_OBJ) { 9709 + jsoff_t m_off = lkp(js, mapped, "length", 6); 9710 + jsoff_t m_len = 0; 9711 + if (m_off != 0) { 9712 + jsval_t m_len_val = resolveprop(js, mkval(T_PROP, m_off)); 9713 + if (vtype(m_len_val) == T_NUM) m_len = (jsoff_t) tod(m_len_val); 9714 + } 9715 + for (jsoff_t j = 0; j < m_len; j++) { 9716 + char jstr[16]; 9717 + snprintf(jstr, sizeof(jstr), "%u", (unsigned) j); 9718 + jsoff_t m_elem_off = lkp(js, mapped, jstr, strlen(jstr)); 9719 + if (m_elem_off != 0) { 9720 + jsval_t m_elem = resolveprop(js, mkval(T_PROP, m_elem_off)); 9721 + char res_idx[16]; 9722 + snprintf(res_idx, sizeof(res_idx), "%u", (unsigned) result_idx); 9723 + jsval_t key = js_mkstr(js, res_idx, strlen(res_idx)); 9724 + setprop(js, result, key, m_elem); 9725 + } 9726 + result_idx++; 9727 + } 9728 + } else { 9729 + char res_idx[16]; 9730 + snprintf(res_idx, sizeof(res_idx), "%u", (unsigned) result_idx); 9731 + jsval_t key = js_mkstr(js, res_idx, strlen(res_idx)); 9732 + setprop(js, result, key, mapped); 9733 + result_idx++; 9734 + } 9735 + } 9736 + 9737 + jsval_t len_key = js_mkstr(js, "length", 6); 9738 + setprop(js, result, len_key, tov((double) result_idx)); 9739 + return mkval(T_ARR, vdata(result)); 9740 + } 9741 + 9742 + static jsval_t builtin_array_forEach(struct js *js, jsval_t *args, int nargs) { 9743 + jsval_t arr = js->this_val; 9744 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9745 + return js_mkerr(js, "forEach called on non-array"); 9746 + } 9747 + if (nargs == 0 || vtype(args[0]) != T_FUNC) { 9748 + return js_mkerr(js, "forEach requires a function argument"); 9749 + } 9750 + 9751 + jsval_t callback = args[0]; 9752 + jsoff_t off = lkp(js, arr, "length", 6); 9753 + jsoff_t len = 0; 9754 + if (off != 0) { 9755 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9756 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9757 + } 9758 + 9759 + for (jsoff_t i = 0; i < len; i++) { 9760 + char idxstr[16]; 9761 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 9762 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 9763 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 9764 + jsval_t call_args[3] = { elem, tov((double)i), arr }; 9765 + jsval_t result = call_js_with_args(js, callback, call_args, 3); 9766 + if (is_err(result)) return result; 9767 + } 9768 + return js_mkundef(); 9769 + } 9770 + 9771 + static int js_compare_values(struct js *js, jsval_t a, jsval_t b, jsval_t compareFn) { 9772 + if (vtype(compareFn) == T_FUNC) { 9773 + jsval_t call_args[2] = { a, b }; 9774 + jsval_t result = call_js_with_args(js, compareFn, call_args, 2); 9775 + if (vtype(result) == T_NUM) return (int) tod(result); 9776 + return 0; 9777 + } 9778 + const char *sa = js_str(js, a); 9779 + const char *sb = js_str(js, b); 9780 + return strcmp(sa, sb); 9781 + } 9782 + 9783 + static jsval_t builtin_array_indexOf(struct js *js, jsval_t *args, int nargs) { 9784 + jsval_t arr = js->this_val; 9785 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9786 + return js_mkerr(js, "indexOf called on non-array"); 9787 + } 9788 + if (nargs == 0) return tov(-1); 9789 + 9790 + jsval_t search = args[0]; 9791 + jsoff_t off = lkp(js, arr, "length", 6); 9792 + jsoff_t len = 0; 9793 + if (off != 0) { 9794 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9795 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9796 + } 9797 + 9798 + jsoff_t start = 0; 9799 + if (nargs >= 2 && vtype(args[1]) == T_NUM) { 9800 + int s = (int) tod(args[1]); 9801 + if (s < 0) s = (int)len + s; 9802 + if (s < 0) s = 0; 9803 + start = (jsoff_t) s; 9804 + } 9805 + 9806 + for (jsoff_t i = start; i < len; i++) { 9807 + char idxstr[16]; 9808 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 9809 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 9810 + if (elem_off != 0) { 9811 + jsval_t elem = resolveprop(js, mkval(T_PROP, elem_off)); 9812 + if (vtype(elem) == vtype(search)) { 9813 + if (vtype(elem) == T_NUM && tod(elem) == tod(search)) return tov((double)i); 9814 + if (vtype(elem) == T_BOOL && vdata(elem) == vdata(search)) return tov((double)i); 9815 + if (vtype(elem) == T_STR) { 9816 + jsoff_t el, eo = vstr(js, elem, &el); 9817 + jsoff_t sl, so = vstr(js, search, &sl); 9818 + if (el == sl && memcmp(&js->mem[eo], &js->mem[so], el) == 0) return tov((double)i); 9819 + } 9820 + if ((vtype(elem) == T_OBJ || vtype(elem) == T_ARR || vtype(elem) == T_FUNC) && vdata(elem) == vdata(search)) return tov((double)i); 9821 + } 9822 + } 9823 + } 9824 + return tov(-1); 9825 + } 9826 + 9827 + static jsval_t builtin_array_lastIndexOf(struct js *js, jsval_t *args, int nargs) { 9828 + jsval_t arr = js->this_val; 9829 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9830 + return js_mkerr(js, "lastIndexOf called on non-array"); 9831 + } 9832 + if (nargs == 0) return tov(-1); 9833 + 9834 + jsval_t search = args[0]; 9835 + jsoff_t off = lkp(js, arr, "length", 6); 9836 + jsoff_t len = 0; 9837 + if (off != 0) { 9838 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9839 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9840 + } 9841 + 9842 + int start = (int)len - 1; 9843 + if (nargs >= 2 && vtype(args[1]) == T_NUM) { 9844 + start = (int) tod(args[1]); 9845 + if (start < 0) start = (int)len + start; 9846 + } 9847 + if (start >= (int)len) start = (int)len - 1; 9848 + 9849 + for (int i = start; i >= 0; i--) { 9850 + char idxstr[16]; 9851 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 9852 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 9853 + if (elem_off != 0) { 9854 + jsval_t elem = resolveprop(js, mkval(T_PROP, elem_off)); 9855 + if (vtype(elem) == vtype(search)) { 9856 + if (vtype(elem) == T_NUM && tod(elem) == tod(search)) return tov((double)i); 9857 + if (vtype(elem) == T_BOOL && vdata(elem) == vdata(search)) return tov((double)i); 9858 + if (vtype(elem) == T_STR) { 9859 + jsoff_t el, eo = vstr(js, elem, &el); 9860 + jsoff_t sl, so = vstr(js, search, &sl); 9861 + if (el == sl && memcmp(&js->mem[eo], &js->mem[so], el) == 0) return tov((double)i); 9862 + } 9863 + if ((vtype(elem) == T_OBJ || vtype(elem) == T_ARR || vtype(elem) == T_FUNC) && vdata(elem) == vdata(search)) return tov((double)i); 9864 + } 9865 + } 9866 + } 9867 + return tov(-1); 9868 + } 9869 + 9870 + static jsval_t builtin_array_reduceRight(struct js *js, jsval_t *args, int nargs) { 9871 + jsval_t arr = js->this_val; 9872 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9873 + return js_mkerr(js, "reduceRight called on non-array"); 9874 + } 9875 + if (nargs == 0 || vtype(args[0]) != T_FUNC) { 9876 + return js_mkerr(js, "reduceRight requires a function argument"); 9877 + } 9878 + 9879 + jsval_t callback = args[0]; 9880 + jsoff_t off = lkp(js, arr, "length", 6); 9881 + jsoff_t len = 0; 9882 + if (off != 0) { 9883 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9884 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9885 + } 9886 + 9887 + int start_idx = (int)len - 1; 9888 + jsval_t accumulator; 9889 + 9890 + if (nargs >= 2) { 9891 + accumulator = args[1]; 9892 + } else { 9893 + if (len == 0) return js_mkerr(js, "reduceRight of empty array with no initial value"); 9894 + char idxstr[16]; 9895 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned)(len - 1)); 9896 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 9897 + accumulator = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 9898 + start_idx = (int)len - 2; 9899 + } 9900 + 9901 + for (int i = start_idx; i >= 0; i--) { 9902 + char idxstr[16]; 9903 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 9904 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 9905 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 9906 + jsval_t call_args[4] = { accumulator, elem, tov((double)i), arr }; 9907 + accumulator = call_js_with_args(js, callback, call_args, 4); 9908 + if (is_err(accumulator)) return accumulator; 9909 + } 9910 + 9911 + return accumulator; 9912 + } 9913 + 9914 + static jsval_t builtin_array_shift(struct js *js, jsval_t *args, int nargs) { 9915 + (void) args; 9916 + (void) nargs; 9917 + jsval_t arr = js->this_val; 9918 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9919 + return js_mkerr(js, "shift called on non-array"); 9920 + } 9921 + 9922 + jsoff_t off = lkp(js, arr, "length", 6); 9923 + jsoff_t len = 0; 9924 + if (off != 0) { 9925 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9926 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9927 + } 9928 + 9929 + if (len == 0) return js_mkundef(); 9930 + 9931 + jsoff_t first_off = lkp(js, arr, "0", 1); 9932 + jsval_t first = first_off ? resolveprop(js, mkval(T_PROP, first_off)) : js_mkundef(); 9933 + 9934 + for (jsoff_t i = 1; i < len; i++) { 9935 + char src[16], dst[16]; 9936 + snprintf(src, sizeof(src), "%u", (unsigned) i); 9937 + snprintf(dst, sizeof(dst), "%u", (unsigned)(i - 1)); 9938 + jsoff_t elem_off = lkp(js, arr, src, strlen(src)); 9939 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 9940 + jsval_t key = js_mkstr(js, dst, strlen(dst)); 9941 + setprop(js, arr, key, elem); 9942 + } 9943 + 9944 + jsval_t len_key = js_mkstr(js, "length", 6); 9945 + setprop(js, arr, len_key, tov((double)(len - 1))); 9946 + return first; 9947 + } 9948 + 9949 + static jsval_t builtin_array_unshift(struct js *js, jsval_t *args, int nargs) { 9950 + jsval_t arr = js->this_val; 9951 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9952 + return js_mkerr(js, "unshift called on non-array"); 9953 + } 9954 + 9955 + jsoff_t off = lkp(js, arr, "length", 6); 9956 + jsoff_t len = 0; 9957 + if (off != 0) { 9958 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9959 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 9960 + } 9961 + 9962 + for (int i = (int)len - 1; i >= 0; i--) { 9963 + char src[16], dst[16]; 9964 + snprintf(src, sizeof(src), "%u", (unsigned) i); 9965 + snprintf(dst, sizeof(dst), "%u", (unsigned)(i + nargs)); 9966 + jsoff_t elem_off = lkp(js, arr, src, strlen(src)); 9967 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 9968 + jsval_t key = js_mkstr(js, dst, strlen(dst)); 9969 + setprop(js, arr, key, elem); 9970 + } 9971 + 9972 + for (int i = 0; i < nargs; i++) { 9973 + char idxstr[16]; 9974 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 9975 + jsval_t key = js_mkstr(js, idxstr, strlen(idxstr)); 9976 + setprop(js, arr, key, args[i]); 9977 + } 9978 + 9979 + jsval_t len_key = js_mkstr(js, "length", 6); 9980 + jsoff_t new_len = len + nargs; 9981 + setprop(js, arr, len_key, tov((double) new_len)); 9982 + return tov((double) new_len); 9983 + } 9984 + 9985 + static jsval_t builtin_array_some(struct js *js, jsval_t *args, int nargs) { 9986 + jsval_t arr = js->this_val; 9987 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 9988 + return js_mkerr(js, "some called on non-array"); 9989 + } 9990 + if (nargs == 0 || vtype(args[0]) != T_FUNC) { 9991 + return js_mkerr(js, "some requires a function argument"); 9992 + } 9993 + 9994 + jsval_t callback = args[0]; 9995 + jsoff_t off = lkp(js, arr, "length", 6); 9996 + jsoff_t len = 0; 9997 + if (off != 0) { 9998 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 9999 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 10000 + } 10001 + 10002 + for (jsoff_t i = 0; i < len; i++) { 10003 + char idxstr[16]; 10004 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 10005 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 10006 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 10007 + jsval_t call_args[3] = { elem, tov((double)i), arr }; 10008 + jsval_t result = call_js_with_args(js, callback, call_args, 3); 10009 + if (is_err(result)) return result; 10010 + if (js_truthy(js, result)) return mkval(T_BOOL, 1); 10011 + } 10012 + return mkval(T_BOOL, 0); 10013 + } 10014 + 10015 + static jsval_t builtin_array_sort(struct js *js, jsval_t *args, int nargs) { 10016 + jsval_t arr = js->this_val; 10017 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 10018 + return js_mkerr(js, "sort called on non-array"); 10019 + } 10020 + 10021 + jsval_t compareFn = (nargs >= 1 && vtype(args[0]) == T_FUNC) ? args[0] : js_mkundef(); 10022 + 10023 + jsoff_t off = lkp(js, arr, "length", 6); 10024 + jsoff_t len = 0; 10025 + if (off != 0) { 10026 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 10027 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 10028 + } 10029 + 10030 + for (jsoff_t i = 0; i < len; i++) { 10031 + for (jsoff_t j = i + 1; j < len; j++) { 10032 + char idx_i[16], idx_j[16]; 10033 + snprintf(idx_i, sizeof(idx_i), "%u", (unsigned) i); 10034 + snprintf(idx_j, sizeof(idx_j), "%u", (unsigned) j); 10035 + 10036 + jsoff_t off_i = lkp(js, arr, idx_i, strlen(idx_i)); 10037 + jsoff_t off_j = lkp(js, arr, idx_j, strlen(idx_j)); 10038 + jsval_t val_i = off_i ? resolveprop(js, mkval(T_PROP, off_i)) : js_mkundef(); 10039 + jsval_t val_j = off_j ? resolveprop(js, mkval(T_PROP, off_j)) : js_mkundef(); 10040 + 10041 + if (js_compare_values(js, val_i, val_j, compareFn) > 0) { 10042 + jsval_t key_i = js_mkstr(js, idx_i, strlen(idx_i)); 10043 + jsval_t key_j = js_mkstr(js, idx_j, strlen(idx_j)); 10044 + setprop(js, arr, key_i, val_j); 10045 + setprop(js, arr, key_j, val_i); 10046 + } 10047 + } 10048 + } 10049 + return arr; 10050 + } 10051 + 10052 + static jsval_t builtin_array_splice(struct js *js, jsval_t *args, int nargs) { 10053 + jsval_t arr = js->this_val; 10054 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 10055 + return js_mkerr(js, "splice called on non-array"); 10056 + } 10057 + 10058 + jsoff_t off = lkp(js, arr, "length", 6); 10059 + jsoff_t len = 0; 10060 + if (off != 0) { 10061 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 10062 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 10063 + } 10064 + 10065 + int start = 0; 10066 + if (nargs >= 1 && vtype(args[0]) == T_NUM) { 10067 + start = (int) tod(args[0]); 10068 + if (start < 0) start = (int)len + start; 10069 + if (start < 0) start = 0; 10070 + if (start > (int)len) start = (int)len; 10071 + } 10072 + 10073 + int deleteCount = (int)len - start; 10074 + if (nargs >= 2 && vtype(args[1]) == T_NUM) { 10075 + deleteCount = (int) tod(args[1]); 10076 + if (deleteCount < 0) deleteCount = 0; 10077 + if (deleteCount > (int)len - start) deleteCount = (int)len - start; 10078 + } 10079 + 10080 + int insertCount = nargs > 2 ? nargs - 2 : 0; 10081 + 10082 + jsval_t removed = mkarr(js); 10083 + if (is_err(removed)) return removed; 10084 + 10085 + for (int i = 0; i < deleteCount; i++) { 10086 + char src[16], dst[16]; 10087 + snprintf(src, sizeof(src), "%u", (unsigned)(start + i)); 10088 + snprintf(dst, sizeof(dst), "%u", (unsigned) i); 10089 + jsoff_t elem_off = lkp(js, arr, src, strlen(src)); 10090 + if (elem_off != 0) { 10091 + jsval_t elem = resolveprop(js, mkval(T_PROP, elem_off)); 10092 + jsval_t key = js_mkstr(js, dst, strlen(dst)); 10093 + setprop(js, removed, key, elem); 10094 + } 10095 + } 10096 + jsval_t rem_len_key = js_mkstr(js, "length", 6); 10097 + setprop(js, removed, rem_len_key, tov((double) deleteCount)); 10098 + 10099 + int shift = insertCount - deleteCount; 10100 + if (shift > 0) { 10101 + for (int i = (int)len - 1; i >= start + deleteCount; i--) { 10102 + char src[16], dst[16]; 10103 + snprintf(src, sizeof(src), "%u", (unsigned) i); 10104 + snprintf(dst, sizeof(dst), "%u", (unsigned)(i + shift)); 10105 + jsoff_t elem_off = lkp(js, arr, src, strlen(src)); 10106 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 10107 + jsval_t key = js_mkstr(js, dst, strlen(dst)); 10108 + setprop(js, arr, key, elem); 10109 + } 10110 + } else if (shift < 0) { 10111 + for (int i = start + deleteCount; i < (int)len; i++) { 10112 + char src[16], dst[16]; 10113 + snprintf(src, sizeof(src), "%u", (unsigned) i); 10114 + snprintf(dst, sizeof(dst), "%u", (unsigned)(i + shift)); 10115 + jsoff_t elem_off = lkp(js, arr, src, strlen(src)); 10116 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 10117 + jsval_t key = js_mkstr(js, dst, strlen(dst)); 10118 + setprop(js, arr, key, elem); 10119 + } 10120 + } 10121 + 10122 + for (int i = 0; i < insertCount; i++) { 10123 + char idxstr[16]; 10124 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned)(start + i)); 10125 + jsval_t key = js_mkstr(js, idxstr, strlen(idxstr)); 10126 + setprop(js, arr, key, args[2 + i]); 10127 + } 10128 + 10129 + jsval_t len_key = js_mkstr(js, "length", 6); 10130 + setprop(js, arr, len_key, tov((double)((int)len + shift))); 10131 + return mkval(T_ARR, vdata(removed)); 10132 + } 10133 + 10134 + static jsval_t builtin_array_copyWithin(struct js *js, jsval_t *args, int nargs) { 10135 + jsval_t arr = js->this_val; 10136 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 10137 + return js_mkerr(js, "copyWithin called on non-array"); 10138 + } 10139 + 10140 + jsoff_t off = lkp(js, arr, "length", 6); 10141 + jsoff_t len = 0; 10142 + if (off != 0) { 10143 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 10144 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 10145 + } 10146 + 10147 + int target = 0, start = 0, end = (int)len; 10148 + if (nargs >= 1 && vtype(args[0]) == T_NUM) { 10149 + target = (int) tod(args[0]); 10150 + if (target < 0) target = (int)len + target; 10151 + if (target < 0) target = 0; 10152 + } 10153 + if (nargs >= 2 && vtype(args[1]) == T_NUM) { 10154 + start = (int) tod(args[1]); 10155 + if (start < 0) start = (int)len + start; 10156 + if (start < 0) start = 0; 10157 + } 10158 + if (nargs >= 3 && vtype(args[2]) == T_NUM) { 10159 + end = (int) tod(args[2]); 10160 + if (end < 0) end = (int)len + end; 10161 + if (end < 0) end = 0; 10162 + } 10163 + if (end > (int)len) end = (int)len; 10164 + 10165 + int count = end - start; 10166 + if (count > (int)len - target) count = (int)len - target; 10167 + 10168 + jsval_t *temp = (jsval_t *)malloc(count * sizeof(jsval_t)); 10169 + for (int i = 0; i < count; i++) { 10170 + char idxstr[16]; 10171 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned)(start + i)); 10172 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 10173 + temp[i] = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 10174 + } 10175 + 10176 + for (int i = 0; i < count; i++) { 10177 + char idxstr[16]; 10178 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned)(target + i)); 10179 + jsval_t key = js_mkstr(js, idxstr, strlen(idxstr)); 10180 + setprop(js, arr, key, temp[i]); 10181 + } 10182 + 10183 + free(temp); 10184 + return arr; 10185 + } 10186 + 10187 + static jsval_t builtin_array_toReversed(struct js *js, jsval_t *args, int nargs) { 10188 + (void) args; 10189 + (void) nargs; 10190 + jsval_t arr = js->this_val; 10191 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 10192 + return js_mkerr(js, "toReversed called on non-array"); 10193 + } 10194 + 10195 + jsoff_t off = lkp(js, arr, "length", 6); 10196 + jsoff_t len = 0; 10197 + if (off != 0) { 10198 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 10199 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 10200 + } 10201 + 10202 + jsval_t result = mkarr(js); 10203 + if (is_err(result)) return result; 10204 + 10205 + for (jsoff_t i = 0; i < len; i++) { 10206 + char src[16], dst[16]; 10207 + snprintf(src, sizeof(src), "%u", (unsigned)(len - 1 - i)); 10208 + snprintf(dst, sizeof(dst), "%u", (unsigned) i); 10209 + jsoff_t elem_off = lkp(js, arr, src, strlen(src)); 10210 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 10211 + jsval_t key = js_mkstr(js, dst, strlen(dst)); 10212 + setprop(js, result, key, elem); 10213 + } 10214 + 10215 + jsval_t len_key = js_mkstr(js, "length", 6); 10216 + setprop(js, result, len_key, tov((double) len)); 10217 + return mkval(T_ARR, vdata(result)); 10218 + } 10219 + 10220 + static jsval_t builtin_array_toSorted(struct js *js, jsval_t *args, int nargs) { 10221 + jsval_t arr = js->this_val; 10222 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 10223 + return js_mkerr(js, "toSorted called on non-array"); 10224 + } 10225 + 10226 + jsval_t compareFn = (nargs >= 1 && vtype(args[0]) == T_FUNC) ? args[0] : js_mkundef(); 10227 + 10228 + jsoff_t off = lkp(js, arr, "length", 6); 10229 + jsoff_t len = 0; 10230 + if (off != 0) { 10231 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 10232 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 10233 + } 10234 + 10235 + jsval_t result = mkarr(js); 10236 + if (is_err(result)) return result; 10237 + 10238 + for (jsoff_t i = 0; i < len; i++) { 10239 + char idxstr[16]; 10240 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 10241 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 10242 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 10243 + jsval_t key = js_mkstr(js, idxstr, strlen(idxstr)); 10244 + setprop(js, result, key, elem); 10245 + } 10246 + jsval_t len_key = js_mkstr(js, "length", 6); 10247 + setprop(js, result, len_key, tov((double) len)); 10248 + 10249 + for (jsoff_t i = 0; i < len; i++) { 10250 + for (jsoff_t j = i + 1; j < len; j++) { 10251 + char idx_i[16], idx_j[16]; 10252 + snprintf(idx_i, sizeof(idx_i), "%u", (unsigned) i); 10253 + snprintf(idx_j, sizeof(idx_j), "%u", (unsigned) j); 10254 + 10255 + jsoff_t off_i = lkp(js, result, idx_i, strlen(idx_i)); 10256 + jsoff_t off_j = lkp(js, result, idx_j, strlen(idx_j)); 10257 + jsval_t val_i = off_i ? resolveprop(js, mkval(T_PROP, off_i)) : js_mkundef(); 10258 + jsval_t val_j = off_j ? resolveprop(js, mkval(T_PROP, off_j)) : js_mkundef(); 10259 + 10260 + if (js_compare_values(js, val_i, val_j, compareFn) > 0) { 10261 + jsval_t key_i = js_mkstr(js, idx_i, strlen(idx_i)); 10262 + jsval_t key_j = js_mkstr(js, idx_j, strlen(idx_j)); 10263 + setprop(js, result, key_i, val_j); 10264 + setprop(js, result, key_j, val_i); 10265 + } 10266 + } 10267 + } 10268 + return mkval(T_ARR, vdata(result)); 10269 + } 10270 + 10271 + static jsval_t builtin_array_toSpliced(struct js *js, jsval_t *args, int nargs) { 10272 + jsval_t arr = js->this_val; 10273 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 10274 + return js_mkerr(js, "toSpliced called on non-array"); 10275 + } 10276 + 10277 + jsoff_t off = lkp(js, arr, "length", 6); 10278 + jsoff_t len = 0; 10279 + if (off != 0) { 10280 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 10281 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 10282 + } 10283 + 10284 + int start = 0; 10285 + if (nargs >= 1 && vtype(args[0]) == T_NUM) { 10286 + start = (int) tod(args[0]); 10287 + if (start < 0) start = (int)len + start; 10288 + if (start < 0) start = 0; 10289 + if (start > (int)len) start = (int)len; 10290 + } 10291 + 10292 + int deleteCount = (int)len - start; 10293 + if (nargs >= 2 && vtype(args[1]) == T_NUM) { 10294 + deleteCount = (int) tod(args[1]); 10295 + if (deleteCount < 0) deleteCount = 0; 10296 + if (deleteCount > (int)len - start) deleteCount = (int)len - start; 10297 + } 10298 + 10299 + int insertCount = nargs > 2 ? nargs - 2 : 0; 10300 + 10301 + jsval_t result = mkarr(js); 10302 + if (is_err(result)) return result; 10303 + jsoff_t result_idx = 0; 10304 + 10305 + for (int i = 0; i < start; i++) { 10306 + char src[16], dst[16]; 10307 + snprintf(src, sizeof(src), "%u", (unsigned) i); 10308 + snprintf(dst, sizeof(dst), "%u", (unsigned) result_idx); 10309 + jsoff_t elem_off = lkp(js, arr, src, strlen(src)); 10310 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 10311 + jsval_t key = js_mkstr(js, dst, strlen(dst)); 10312 + setprop(js, result, key, elem); 10313 + result_idx++; 10314 + } 10315 + 10316 + for (int i = 0; i < insertCount; i++) { 10317 + char dst[16]; 10318 + snprintf(dst, sizeof(dst), "%u", (unsigned) result_idx); 10319 + jsval_t key = js_mkstr(js, dst, strlen(dst)); 10320 + setprop(js, result, key, args[2 + i]); 10321 + result_idx++; 10322 + } 10323 + 10324 + for (int i = start + deleteCount; i < (int)len; i++) { 10325 + char src[16], dst[16]; 10326 + snprintf(src, sizeof(src), "%u", (unsigned) i); 10327 + snprintf(dst, sizeof(dst), "%u", (unsigned) result_idx); 10328 + jsoff_t elem_off = lkp(js, arr, src, strlen(src)); 10329 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 10330 + jsval_t key = js_mkstr(js, dst, strlen(dst)); 10331 + setprop(js, result, key, elem); 10332 + result_idx++; 10333 + } 10334 + 10335 + jsval_t len_key = js_mkstr(js, "length", 6); 10336 + setprop(js, result, len_key, tov((double) result_idx)); 10337 + return mkval(T_ARR, vdata(result)); 10338 + } 10339 + 10340 + static jsval_t builtin_array_with(struct js *js, jsval_t *args, int nargs) { 10341 + jsval_t arr = js->this_val; 10342 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 10343 + return js_mkerr(js, "with called on non-array"); 10344 + } 10345 + 10346 + if (nargs < 2) return js_mkerr(js, "with requires index and value arguments"); 10347 + 10348 + jsoff_t off = lkp(js, arr, "length", 6); 10349 + jsoff_t len = 0; 10350 + if (off != 0) { 10351 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 10352 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 10353 + } 10354 + 10355 + int idx = (int) tod(args[0]); 10356 + if (idx < 0) idx = (int)len + idx; 10357 + if (idx < 0 || (jsoff_t)idx >= len) return js_mkerr(js, "Invalid index"); 10358 + 10359 + jsval_t result = mkarr(js); 10360 + if (is_err(result)) return result; 10361 + 10362 + for (jsoff_t i = 0; i < len; i++) { 10363 + char idxstr[16]; 10364 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 10365 + jsval_t elem; 10366 + if ((jsoff_t)idx == i) { 10367 + elem = args[1]; 10368 + } else { 10369 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 10370 + elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 10371 + } 10372 + jsval_t key = js_mkstr(js, idxstr, strlen(idxstr)); 10373 + setprop(js, result, key, elem); 10374 + } 10375 + 10376 + jsval_t len_key = js_mkstr(js, "length", 6); 10377 + setprop(js, result, len_key, tov((double) len)); 10378 + return mkval(T_ARR, vdata(result)); 10379 + } 10380 + 10381 + static jsval_t builtin_array_keys(struct js *js, jsval_t *args, int nargs) { 10382 + (void) args; 10383 + (void) nargs; 10384 + jsval_t arr = js->this_val; 10385 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 10386 + return js_mkerr(js, "keys called on non-array"); 10387 + } 10388 + 10389 + jsoff_t off = lkp(js, arr, "length", 6); 10390 + jsoff_t len = 0; 10391 + if (off != 0) { 10392 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 10393 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 10394 + } 10395 + 10396 + jsval_t result = mkarr(js); 10397 + if (is_err(result)) return result; 10398 + 10399 + for (jsoff_t i = 0; i < len; i++) { 10400 + char idxstr[16]; 10401 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 10402 + jsval_t key = js_mkstr(js, idxstr, strlen(idxstr)); 10403 + setprop(js, result, key, tov((double) i)); 10404 + } 10405 + 10406 + jsval_t len_key = js_mkstr(js, "length", 6); 10407 + setprop(js, result, len_key, tov((double) len)); 10408 + return mkval(T_ARR, vdata(result)); 10409 + } 10410 + 10411 + static jsval_t builtin_array_values(struct js *js, jsval_t *args, int nargs) { 10412 + (void) args; 10413 + (void) nargs; 10414 + jsval_t arr = js->this_val; 10415 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 10416 + return js_mkerr(js, "values called on non-array"); 10417 + } 10418 + 10419 + jsoff_t off = lkp(js, arr, "length", 6); 10420 + jsoff_t len = 0; 10421 + if (off != 0) { 10422 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 10423 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 10424 + } 10425 + 10426 + jsval_t result = mkarr(js); 10427 + if (is_err(result)) return result; 10428 + 10429 + for (jsoff_t i = 0; i < len; i++) { 10430 + char idxstr[16]; 10431 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 10432 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 10433 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 10434 + jsval_t key = js_mkstr(js, idxstr, strlen(idxstr)); 10435 + setprop(js, result, key, elem); 10436 + } 10437 + 10438 + jsval_t len_key = js_mkstr(js, "length", 6); 10439 + setprop(js, result, len_key, tov((double) len)); 10440 + return mkval(T_ARR, vdata(result)); 10441 + } 10442 + 10443 + static jsval_t builtin_array_entries(struct js *js, jsval_t *args, int nargs) { 10444 + (void) args; 10445 + (void) nargs; 10446 + jsval_t arr = js->this_val; 10447 + if (vtype(arr) != T_ARR && vtype(arr) != T_OBJ) { 10448 + return js_mkerr(js, "entries called on non-array"); 10449 + } 10450 + 10451 + jsoff_t off = lkp(js, arr, "length", 6); 10452 + jsoff_t len = 0; 10453 + if (off != 0) { 10454 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 10455 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 10456 + } 10457 + 10458 + jsval_t result = mkarr(js); 10459 + if (is_err(result)) return result; 10460 + 10461 + for (jsoff_t i = 0; i < len; i++) { 10462 + jsval_t entry = mkarr(js); 10463 + if (is_err(entry)) return entry; 10464 + 10465 + char idxstr[16]; 10466 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 10467 + jsoff_t elem_off = lkp(js, arr, idxstr, strlen(idxstr)); 10468 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 10469 + 10470 + setprop(js, entry, js_mkstr(js, "0", 1), tov((double) i)); 10471 + setprop(js, entry, js_mkstr(js, "1", 1), elem); 10472 + setprop(js, entry, js_mkstr(js, "length", 6), tov(2)); 10473 + 10474 + jsval_t key = js_mkstr(js, idxstr, strlen(idxstr)); 10475 + setprop(js, result, key, mkval(T_ARR, vdata(entry))); 10476 + } 10477 + 10478 + jsval_t len_key = js_mkstr(js, "length", 6); 10479 + setprop(js, result, len_key, tov((double) len)); 10480 + return mkval(T_ARR, vdata(result)); 10481 + } 10482 + 10483 + static jsval_t builtin_array_toString(struct js *js, jsval_t *args, int nargs) { 10484 + (void) args; 10485 + (void) nargs; 10486 + jsval_t arr = js->this_val; 10487 + jsval_t sep_args[1] = { js_mkstr(js, ",", 1) }; 10488 + jsval_t old_this = js->this_val; 10489 + js->this_val = arr; 10490 + jsval_t result = builtin_array_join(js, sep_args, 1); 10491 + js->this_val = old_this; 10492 + return result; 10493 + } 10494 + 10495 + static jsval_t builtin_Array_isArray(struct js *js, jsval_t *args, int nargs) { 10496 + (void) js; 10497 + if (nargs == 0) return mkval(T_BOOL, 0); 10498 + return mkval(T_BOOL, vtype(args[0]) == T_ARR ? 1 : 0); 10499 + } 10500 + 10501 + static jsval_t builtin_Array_from(struct js *js, jsval_t *args, int nargs) { 10502 + if (nargs == 0) return mkarr(js); 10503 + 10504 + jsval_t src = args[0]; 10505 + jsval_t mapFn = (nargs >= 2 && vtype(args[1]) == T_FUNC) ? args[1] : js_mkundef(); 10506 + 10507 + jsval_t result = mkarr(js); 10508 + if (is_err(result)) return result; 10509 + 10510 + if (vtype(src) == T_STR) { 10511 + jsoff_t str_len, str_off = vstr(js, src, &str_len); 10512 + const char *str_ptr = (const char *)&js->mem[str_off]; 10513 + for (jsoff_t i = 0; i < str_len; i++) { 10514 + char idxstr[16]; 10515 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 10516 + jsval_t elem = js_mkstr(js, str_ptr + i, 1); 10517 + if (vtype(mapFn) == T_FUNC) { 10518 + jsval_t call_args[2] = { elem, tov((double)i) }; 10519 + elem = call_js_with_args(js, mapFn, call_args, 2); 10520 + if (is_err(elem)) return elem; 10521 + } 10522 + jsval_t key = js_mkstr(js, idxstr, strlen(idxstr)); 10523 + setprop(js, result, key, elem); 10524 + } 10525 + jsval_t len_key = js_mkstr(js, "length", 6); 10526 + setprop(js, result, len_key, tov((double) str_len)); 10527 + } else if (vtype(src) == T_ARR || vtype(src) == T_OBJ) { 10528 + jsoff_t off = lkp(js, src, "length", 6); 10529 + jsoff_t len = 0; 10530 + if (off != 0) { 10531 + jsval_t len_val = resolveprop(js, mkval(T_PROP, off)); 10532 + if (vtype(len_val) == T_NUM) len = (jsoff_t) tod(len_val); 10533 + } 10534 + for (jsoff_t i = 0; i < len; i++) { 10535 + char idxstr[16]; 10536 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 10537 + jsoff_t elem_off = lkp(js, src, idxstr, strlen(idxstr)); 10538 + jsval_t elem = elem_off ? resolveprop(js, mkval(T_PROP, elem_off)) : js_mkundef(); 10539 + if (vtype(mapFn) == T_FUNC) { 10540 + jsval_t call_args[2] = { elem, tov((double)i) }; 10541 + elem = call_js_with_args(js, mapFn, call_args, 2); 10542 + if (is_err(elem)) return elem; 10543 + } 10544 + jsval_t key = js_mkstr(js, idxstr, strlen(idxstr)); 10545 + setprop(js, result, key, elem); 10546 + } 10547 + jsval_t len_key = js_mkstr(js, "length", 6); 10548 + setprop(js, result, len_key, tov((double) len)); 10549 + } 10550 + 10551 + return mkval(T_ARR, vdata(result)); 10552 + } 10553 + 10554 + static jsval_t builtin_Array_of(struct js *js, jsval_t *args, int nargs) { 10555 + jsval_t arr = mkarr(js); 10556 + if (is_err(arr)) return arr; 10557 + 10558 + for (int i = 0; i < nargs; i++) { 10559 + char idxstr[16]; 10560 + snprintf(idxstr, sizeof(idxstr), "%u", (unsigned) i); 10561 + jsval_t key = js_mkstr(js, idxstr, strlen(idxstr)); 10562 + setprop(js, arr, key, args[i]); 10563 + } 10564 + jsval_t len_key = js_mkstr(js, "length", 6); 10565 + setprop(js, arr, len_key, tov((double) nargs)); 10566 + return mkval(T_ARR, vdata(arr)); 10567 + } 10568 + 9169 10569 static jsval_t builtin_string_indexOf(struct js *js, jsval_t *args, int nargs) { 9170 10570 jsval_t str = js->this_val; 9171 10571 if (vtype(str) != T_STR) return js_mkerr(js, "indexOf called on non-string"); ··· 12109 13509 setprop(js, array_proto, js_mkstr(js, "join", 4), js_mkfun(builtin_array_join)); 12110 13510 setprop(js, array_proto, js_mkstr(js, "includes", 8), js_mkfun(builtin_array_includes)); 12111 13511 setprop(js, array_proto, js_mkstr(js, "every", 5), js_mkfun(builtin_array_every)); 13512 + setprop(js, array_proto, js_mkstr(js, "reverse", 7), js_mkfun(builtin_array_reverse)); 13513 + setprop(js, array_proto, js_mkstr(js, "map", 3), js_mkfun(builtin_array_map)); 13514 + setprop(js, array_proto, js_mkstr(js, "filter", 6), js_mkfun(builtin_array_filter)); 13515 + setprop(js, array_proto, js_mkstr(js, "reduce", 6), js_mkfun(builtin_array_reduce)); 13516 + setprop(js, array_proto, js_mkstr(js, "flat", 4), js_mkfun(builtin_array_flat)); 13517 + setprop(js, array_proto, js_mkstr(js, "concat", 6), js_mkfun(builtin_array_concat)); 13518 + setprop(js, array_proto, js_mkstr(js, "at", 2), js_mkfun(builtin_array_at)); 13519 + setprop(js, array_proto, js_mkstr(js, "fill", 4), js_mkfun(builtin_array_fill)); 13520 + setprop(js, array_proto, js_mkstr(js, "find", 4), js_mkfun(builtin_array_find)); 13521 + setprop(js, array_proto, js_mkstr(js, "findIndex", 9), js_mkfun(builtin_array_findIndex)); 13522 + setprop(js, array_proto, js_mkstr(js, "findLast", 8), js_mkfun(builtin_array_findLast)); 13523 + setprop(js, array_proto, js_mkstr(js, "findLastIndex", 13), js_mkfun(builtin_array_findLastIndex)); 13524 + setprop(js, array_proto, js_mkstr(js, "flatMap", 7), js_mkfun(builtin_array_flatMap)); 13525 + setprop(js, array_proto, js_mkstr(js, "forEach", 7), js_mkfun(builtin_array_forEach)); 13526 + setprop(js, array_proto, js_mkstr(js, "indexOf", 7), js_mkfun(builtin_array_indexOf)); 13527 + setprop(js, array_proto, js_mkstr(js, "lastIndexOf", 11), js_mkfun(builtin_array_lastIndexOf)); 13528 + setprop(js, array_proto, js_mkstr(js, "reduceRight", 11), js_mkfun(builtin_array_reduceRight)); 13529 + setprop(js, array_proto, js_mkstr(js, "shift", 5), js_mkfun(builtin_array_shift)); 13530 + setprop(js, array_proto, js_mkstr(js, "unshift", 7), js_mkfun(builtin_array_unshift)); 13531 + setprop(js, array_proto, js_mkstr(js, "some", 4), js_mkfun(builtin_array_some)); 13532 + setprop(js, array_proto, js_mkstr(js, "sort", 4), js_mkfun(builtin_array_sort)); 13533 + setprop(js, array_proto, js_mkstr(js, "splice", 6), js_mkfun(builtin_array_splice)); 13534 + setprop(js, array_proto, js_mkstr(js, "copyWithin", 10), js_mkfun(builtin_array_copyWithin)); 13535 + setprop(js, array_proto, js_mkstr(js, "toReversed", 10), js_mkfun(builtin_array_toReversed)); 13536 + setprop(js, array_proto, js_mkstr(js, "toSorted", 8), js_mkfun(builtin_array_toSorted)); 13537 + setprop(js, array_proto, js_mkstr(js, "toSpliced", 9), js_mkfun(builtin_array_toSpliced)); 13538 + setprop(js, array_proto, js_mkstr(js, "with", 4), js_mkfun(builtin_array_with)); 13539 + setprop(js, array_proto, js_mkstr(js, "keys", 4), js_mkfun(builtin_array_keys)); 13540 + setprop(js, array_proto, js_mkstr(js, "values", 6), js_mkfun(builtin_array_values)); 13541 + setprop(js, array_proto, js_mkstr(js, "entries", 7), js_mkfun(builtin_array_entries)); 13542 + setprop(js, array_proto, js_mkstr(js, "toString", 8), js_mkfun(builtin_array_toString)); 12112 13543 12113 13544 jsval_t string_proto = js_mkobj(js); 12114 13545 set_proto(js, string_proto, object_proto); ··· 12233 13664 set_proto(js, arr_ctor_obj, function_proto); 12234 13665 setprop(js, arr_ctor_obj, js_mkstr(js, "__native_func", 13), js_mkfun(builtin_Array)); 12235 13666 setprop(js, arr_ctor_obj, js_mkstr(js, "prototype", 9), array_proto); 13667 + setprop(js, arr_ctor_obj, js_mkstr(js, "isArray", 7), js_mkfun(builtin_Array_isArray)); 13668 + setprop(js, arr_ctor_obj, js_mkstr(js, "from", 4), js_mkfun(builtin_Array_from)); 13669 + setprop(js, arr_ctor_obj, js_mkstr(js, "of", 2), js_mkfun(builtin_Array_of)); 12236 13670 setprop(js, glob, js_mkstr(js, "Array", 5), mkval(T_FUNC, vdata(arr_ctor_obj))); 12237 13671 12238 13672 jsval_t map_ctor_obj = mkobj(js, 0);