|
15 | 15 |
|
16 | 16 | #include "ecma-alloc.h"
|
17 | 17 | #include "ecma-builtins.h"
|
| 18 | +#include "ecma-comparison.h" |
18 | 19 | #include "ecma-conversion.h"
|
19 | 20 | #include "ecma-exceptions.h"
|
20 | 21 | #include "ecma-gc.h"
|
@@ -266,6 +267,136 @@ ecma_builtin_array_prototype_object_push (ecma_value_t this_arg, /**< this argum
|
266 | 267 | return ret_value;
|
267 | 268 | } /* ecma_builtin_array_prototype_object_push */
|
268 | 269 |
|
| 270 | +/** |
| 271 | + * The Array.prototype object's 'indexOf' routine |
| 272 | + * |
| 273 | + * See also: |
| 274 | + * ECMA-262 v5, 15.4.4.14 |
| 275 | + * |
| 276 | + * @return completion value |
| 277 | + * Returned value must be freed with ecma_free_completion_value. |
| 278 | + */ |
| 279 | +static ecma_completion_value_t |
| 280 | +ecma_builtin_array_prototype_object_index_of (ecma_value_t this_arg, /**< this argument */ |
| 281 | + ecma_value_t arg1, /**< searchElement */ |
| 282 | + ecma_value_t arg2) /**< fromIndex */ |
| 283 | +{ |
| 284 | + ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); |
| 285 | + |
| 286 | + /* 1. */ |
| 287 | + ECMA_TRY_CATCH (obj_this, |
| 288 | + ecma_op_to_object (this_arg), |
| 289 | + ret_value); |
| 290 | + |
| 291 | + ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); |
| 292 | + ecma_string_t *magic_string_length_p = ecma_get_magic_string (ECMA_MAGIC_STRING_LENGTH); |
| 293 | + |
| 294 | + /* 2. */ |
| 295 | + ECMA_TRY_CATCH (len_value, |
| 296 | + ecma_op_object_get (obj_p, magic_string_length_p), |
| 297 | + ret_value); |
| 298 | + |
| 299 | + ECMA_OP_TO_NUMBER_TRY_CATCH (len_number, len_value, ret_value); |
| 300 | + |
| 301 | + /* 3. */ |
| 302 | + uint32_t len = ecma_number_to_uint32 (len_number); |
| 303 | + |
| 304 | + ecma_number_t* num_p = ecma_alloc_number (); |
| 305 | + *num_p = ecma_int32_to_number (-1); |
| 306 | + |
| 307 | + /* 4. */ |
| 308 | + if (len == 0) |
| 309 | + { |
| 310 | + ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p)); |
| 311 | + } |
| 312 | + else |
| 313 | + { |
| 314 | + /* 5. */ |
| 315 | + ECMA_OP_TO_NUMBER_TRY_CATCH (arg_from_idx, arg2, ret_value); |
| 316 | + |
| 317 | + int32_t from_idx_int = ecma_number_to_int32 (arg_from_idx); |
| 318 | + |
| 319 | + /* 6. */ |
| 320 | + if (from_idx_int > 0 && (uint32_t) from_idx_int >= len) |
| 321 | + { |
| 322 | + ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p)); |
| 323 | + } |
| 324 | + else |
| 325 | + { |
| 326 | + uint32_t k; |
| 327 | + |
| 328 | + /* 7 */ |
| 329 | + if (from_idx_int >= 0) |
| 330 | + { |
| 331 | + k = (uint32_t) from_idx_int; |
| 332 | + } |
| 333 | + /* 8. */ |
| 334 | + else |
| 335 | + { |
| 336 | + from_idx_int = -from_idx_int; |
| 337 | + |
| 338 | + /* As opposed to the standard, we prevent k from being negative, so that we can use an uint32 */ |
| 339 | + if ((uint32_t) from_idx_int < len) |
| 340 | + { |
| 341 | + /* 8.a */ |
| 342 | + k = len - (uint32_t) from_idx_int; |
| 343 | + } |
| 344 | + /* If k would've been negative */ |
| 345 | + else |
| 346 | + { |
| 347 | + /* 8.b */ |
| 348 | + k = 0; |
| 349 | + } |
| 350 | + |
| 351 | + } |
| 352 | + JERRY_ASSERT (k < len); |
| 353 | + |
| 354 | + for (; k < len && *num_p < 0 && ecma_is_completion_value_empty (ret_value); k++) |
| 355 | + { |
| 356 | + ecma_string_t *idx_str_p = ecma_new_ecma_string_from_uint32 (k); |
| 357 | + |
| 358 | + /* 9.a */ |
| 359 | + if (ecma_op_object_get_property (obj_p, idx_str_p) != NULL) |
| 360 | + { |
| 361 | + /* 9.b.i */ |
| 362 | + ECMA_TRY_CATCH (get_value, ecma_op_object_get (obj_p, idx_str_p), ret_value); |
| 363 | + |
| 364 | + /* 9.b.ii */ |
| 365 | + if (ecma_op_strict_equality_compare (arg1, get_value)) |
| 366 | + { |
| 367 | + *num_p = ecma_uint32_to_number (k); |
| 368 | + } |
| 369 | + |
| 370 | + ECMA_FINALIZE (get_value); |
| 371 | + } |
| 372 | + |
| 373 | + ecma_deref_ecma_string (idx_str_p); |
| 374 | + } |
| 375 | + |
| 376 | + if (ecma_is_completion_value_empty (ret_value)) |
| 377 | + { |
| 378 | + ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p)); |
| 379 | + } |
| 380 | + else |
| 381 | + { |
| 382 | + ecma_dealloc_number (num_p); |
| 383 | + } |
| 384 | + } |
| 385 | + |
| 386 | + ECMA_OP_TO_NUMBER_FINALIZE (arg_from_idx); |
| 387 | + } |
| 388 | + |
| 389 | + ECMA_OP_TO_NUMBER_FINALIZE (len_number); |
| 390 | + |
| 391 | + ECMA_FINALIZE (len_value); |
| 392 | + |
| 393 | + ecma_deref_ecma_string (magic_string_length_p); |
| 394 | + |
| 395 | + ECMA_FINALIZE (obj_this); |
| 396 | + |
| 397 | + return ret_value; |
| 398 | +} /* ecma_builtin_array_prototype_object_index_of */ |
| 399 | + |
269 | 400 | /**
|
270 | 401 | * @}
|
271 | 402 | * @}
|
|
0 commit comments