@@ -412,67 +412,134 @@ ecma_builtin_object_object_define_properties (ecma_value_t this_arg __attr_unuse
412
412
{
413
413
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
414
414
415
+ // 1.
415
416
if (!ecma_is_value_object (arg1))
416
417
{
417
418
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
418
- return ret_value;
419
419
}
420
+ else
421
+ {
422
+ ecma_object_t *obj_p = ecma_get_object_from_value (arg1);
420
423
421
- ecma_object_t *obj_p = ecma_get_object_from_value (arg1);
422
- ecma_object_t *props_p = ecma_get_object_from_value (arg2);
424
+ // 2.
425
+ ECMA_TRY_CATCH (props,
426
+ ecma_op_to_object (arg2),
427
+ ret_value);
423
428
424
- ecma_property_t *property_p;
429
+ ecma_object_t *props_p = ecma_get_object_from_completion_value (props);
430
+ ecma_property_t *property_p;
425
431
426
- for (property_p = ecma_get_property_list (props_p);
427
- property_p != NULL ;
428
- property_p = ECMA_GET_POINTER (ecma_property_t , property_p->next_property_p ))
429
- {
430
- ecma_string_t *property_name_p;
432
+ // First we need to know how many properties should be stored
433
+ uint32_t property_number = 0 ;
434
+ for (property_p = ecma_get_property_list (props_p);
435
+ property_p != NULL ;
436
+ property_p = ECMA_GET_POINTER (ecma_property_t , property_p->next_property_p ))
437
+ {
438
+ if ((property_p->type == ECMA_PROPERTY_NAMEDDATA || property_p->type == ECMA_PROPERTY_NAMEDACCESSOR)
439
+ && ecma_is_property_enumerable (property_p))
440
+ {
441
+ property_number++;
442
+ }
443
+ }
431
444
432
- if (property_p->type == ECMA_PROPERTY_NAMEDDATA)
445
+ // 3.
446
+ MEM_DEFINE_LOCAL_ARRAY (property_names_p, property_number, ecma_string_t *);
447
+
448
+ uint32_t index = 0 ;
449
+ for (property_p = ecma_get_property_list (props_p);
450
+ property_p != NULL ;
451
+ property_p = ECMA_GET_POINTER (ecma_property_t , property_p->next_property_p ))
433
452
{
434
- property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t ,
435
- property_p->u .named_data_property .name_p );
453
+ ecma_string_t *property_name_p;
454
+
455
+ if (property_p->type == ECMA_PROPERTY_NAMEDDATA)
456
+ {
457
+ property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t ,
458
+ property_p->u .named_data_property .name_p );
459
+ }
460
+ else if (property_p->type == ECMA_PROPERTY_NAMEDACCESSOR)
461
+ {
462
+ property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t ,
463
+ property_p->u .named_accessor_property .name_p );
464
+ }
465
+ else
466
+ {
467
+ continue ;
468
+ }
469
+
470
+ if (ecma_is_property_enumerable (property_p))
471
+ {
472
+ property_names_p[index++] = ecma_copy_or_ref_ecma_string (property_name_p);
473
+ }
436
474
}
437
- else if (property_p->type == ECMA_PROPERTY_NAMEDACCESSOR)
475
+
476
+ // 4.
477
+ MEM_DEFINE_LOCAL_ARRAY (property_descriptors, property_number, ecma_property_descriptor_t );
478
+ uint32_t property_descriptor_number = 0 ;
479
+
480
+ for (index = 0 ;
481
+ index < property_number && ecma_is_completion_value_empty (ret_value);
482
+ index++)
438
483
{
439
- property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t ,
440
- property_p->u .named_accessor_property .name_p );
484
+ // 5.a
485
+ ECMA_TRY_CATCH (desc_obj,
486
+ ecma_op_object_get (props_p, property_names_p[index]),
487
+ ret_value);
488
+
489
+ // 5.b
490
+ ECMA_TRY_CATCH (conv_result,
491
+ ecma_op_to_property_descriptor (ecma_get_completion_value_value (desc_obj),
492
+ &property_descriptors[index]),
493
+ ret_value);
494
+
495
+ property_descriptor_number++;
496
+
497
+ ECMA_FINALIZE (conv_result);
498
+ ECMA_FINALIZE (desc_obj);
441
499
}
442
- else
500
+
501
+ // 6.
502
+ for (index = 0 ;
503
+ index < property_number && ecma_is_completion_value_empty (ret_value);
504
+ index++)
443
505
{
444
- continue ;
506
+ ECMA_TRY_CATCH (define_own_prop_ret,
507
+ ecma_op_object_define_own_property (obj_p,
508
+ property_names_p[index],
509
+ &property_descriptors[index],
510
+ true ),
511
+ ret_value);
512
+
513
+ ECMA_FINALIZE (define_own_prop_ret);
445
514
}
446
- ecma_property_descriptor_t prop_desc;
447
515
448
- ECMA_TRY_CATCH (descObj,
449
- ecma_op_general_object_get (props_p, property_name_p),
450
- ret_value);
516
+ // Clean up
517
+ for (index = 0 ;
518
+ index < property_descriptor_number;
519
+ index++)
520
+ {
521
+ ecma_free_property_descriptor (&property_descriptors[index]);
522
+ }
451
523
452
- ECMA_TRY_CATCH (conv_result,
453
- ecma_op_to_property_descriptor (ecma_get_completion_value_value (descObj),
454
- &prop_desc),
455
- ret_value);
524
+ MEM_FINALIZE_LOCAL_ARRAY (property_descriptors);
456
525
457
- ECMA_TRY_CATCH (define_own_prop_ret,
458
- ecma_op_object_define_own_property (obj_p,
459
- property_name_p,
460
- &prop_desc,
461
- true ),
462
- ret_value);
526
+ for (index = 0 ;
527
+ index < property_number;
528
+ index++)
529
+ {
530
+ ecma_deref_ecma_string (property_names_p[index]);
531
+ }
463
532
464
- ECMA_FINALIZE (define_own_prop_ret);
465
- ecma_free_property_descriptor (&prop_desc);
466
- ECMA_FINALIZE (conv_result);
467
- ECMA_FINALIZE (descObj);
533
+ MEM_FINALIZE_LOCAL_ARRAY (property_names_p);
468
534
469
- if (ecma_is_completion_value_throw (ret_value))
535
+ // 7.
536
+ if (ecma_is_completion_value_empty (ret_value))
470
537
{
471
- return ret_value;
538
+ ret_value = ecma_make_normal_completion_value ( ecma_copy_value (arg1, true )) ;
472
539
}
473
- }
474
540
475
- ret_value = ecma_make_normal_completion_value (ecma_copy_value (arg1, true ));
541
+ ECMA_FINALIZE (props);
542
+ }
476
543
477
544
return ret_value;
478
545
} /* ecma_builtin_object_object_define_properties */
0 commit comments