@@ -100,6 +100,12 @@ impl Engine {
100
100
}
101
101
102
102
/// Get the value at the indexed position of a base type.
103
+ ///
104
+ /// # Panics
105
+ ///
106
+ /// Panics if the target object is shared.
107
+ ///
108
+ /// Shared objects should be handled (dereferenced) before calling this method.
103
109
fn get_indexed_mut < ' t > (
104
110
& self ,
105
111
global : & mut GlobalRuntimeState ,
@@ -430,10 +436,10 @@ impl Engine {
430
436
let value = self
431
437
. eval_expr ( global, caches, scope, this_ptr. as_deref_mut ( ) , lhs_expr) ?
432
438
. flatten ( ) ;
433
- let obj_ptr = & mut value. into ( ) ;
439
+ let item_ptr = & mut value. into ( ) ;
434
440
435
441
self . eval_dot_index_chain_raw (
436
- global, caches, scope2, this_ptr, lhs_expr, expr, obj_ptr , rhs, idx_values,
442
+ global, caches, scope2, this_ptr, lhs_expr, expr, item_ptr , rhs, idx_values,
437
443
None ,
438
444
)
439
445
}
@@ -575,19 +581,30 @@ impl Engine {
575
581
let idx_pos = x. lhs . start_position ( ) ;
576
582
577
583
let ( try_setter, result) = {
578
- let target = target. as_mut ( ) ;
579
- let mut obj = self . get_indexed_mut (
580
- global, caches, target, idx_val, idx_pos, op_pos, false , true ,
584
+ let obj = target. as_mut ( ) ;
585
+
586
+ #[ cfg( not( feature = "no_closure" ) ) ]
587
+ let mut target_guard;
588
+ #[ cfg( not( feature = "no_closure" ) ) ]
589
+ let obj = if obj. is_shared ( ) {
590
+ target_guard = obj. write_lock :: < Dynamic > ( ) . unwrap ( ) ;
591
+ & mut * target_guard
592
+ } else {
593
+ obj
594
+ } ;
595
+
596
+ let mut item = self . get_indexed_mut (
597
+ global, caches, obj, idx_val, idx_pos, op_pos, false , true ,
581
598
) ?;
582
- let is_obj_temp_val = obj . is_temp_value ( ) ;
583
- let obj_ptr = & mut obj ;
599
+ let is_item_temp_val = item . is_temp_value ( ) ;
600
+ let item_ptr = & mut item ;
584
601
585
602
match self . eval_dot_index_chain_raw (
586
- global, caches, _scope, this_ptr, root, rhs, obj_ptr , & x. rhs ,
603
+ global, caches, _scope, this_ptr, root, rhs, item_ptr , & x. rhs ,
587
604
idx_values, new_val,
588
605
) {
589
- Ok ( ( result, true ) ) if is_obj_temp_val => {
590
- ( Some ( obj . take_or_clone ( ) ) , ( result, true ) )
606
+ Ok ( ( result, true ) ) if is_item_temp_val => {
607
+ ( Some ( item . take_or_clone ( ) ) , ( result, true ) )
591
608
}
592
609
Ok ( result) => ( None , result) ,
593
610
Err ( err) => return Err ( err) ,
@@ -617,19 +634,30 @@ impl Engine {
617
634
#[ cfg( feature = "debugging" ) ]
618
635
self . run_debugger ( global, caches, _scope, this_ptr, parent) ?;
619
636
620
- let target = target. as_mut ( ) ;
637
+ let obj = target. as_mut ( ) ;
638
+
639
+ #[ cfg( not( feature = "no_closure" ) ) ]
640
+ let mut target_guard;
641
+ #[ cfg( not( feature = "no_closure" ) ) ]
642
+ let obj = if obj. is_shared ( ) {
643
+ target_guard = obj. write_lock :: < Dynamic > ( ) . unwrap ( ) ;
644
+ & mut * target_guard
645
+ } else {
646
+ obj
647
+ } ;
648
+
621
649
let idx_val = & mut idx_values. pop ( ) . unwrap ( ) ;
622
650
let idx = & mut idx_val. clone ( ) ;
623
651
624
652
let try_setter = match self
625
- . get_indexed_mut ( global, caches, target , idx, pos, op_pos, true , false )
653
+ . get_indexed_mut ( global, caches, obj , idx, pos, op_pos, true , false )
626
654
{
627
655
// Indexed value is not a temp value - update directly
628
- Ok ( ref mut obj_ptr ) => {
656
+ Ok ( ref mut item_ptr ) => {
629
657
self . eval_op_assignment (
630
- global, caches, op_info, root, obj_ptr , new_val,
658
+ global, caches, op_info, root, item_ptr , new_val,
631
659
) ?;
632
- self . check_data_size ( obj_ptr . as_ref ( ) , op_info. position ( ) ) ?;
660
+ self . check_data_size ( item_ptr . as_ref ( ) , op_info. position ( ) ) ?;
633
661
None
634
662
}
635
663
// Indexed value cannot be referenced - use indexer
@@ -646,7 +674,7 @@ impl Engine {
646
674
647
675
// Call the index getter to get the current value
648
676
if let Ok ( val) =
649
- self . call_indexer_get ( global, caches, target , idx, op_pos)
677
+ self . call_indexer_get ( global, caches, obj , idx, op_pos)
650
678
{
651
679
let mut val = val. into ( ) ;
652
680
// Run the op-assignment
@@ -663,7 +691,7 @@ impl Engine {
663
691
let new_val = & mut new_val;
664
692
// The return value of a indexer setter (usually `()`) is thrown away and not used.
665
693
let _ = self . call_indexer_set (
666
- global, caches, target , idx_val, new_val, is_ref_mut, op_pos,
694
+ global, caches, obj , idx_val, new_val, is_ref_mut, op_pos,
667
695
) ?;
668
696
}
669
697
@@ -674,13 +702,22 @@ impl Engine {
674
702
#[ cfg( feature = "debugging" ) ]
675
703
self . run_debugger ( global, caches, _scope, this_ptr, parent) ?;
676
704
677
- let target = target. as_mut ( ) ;
705
+ let obj = target. as_mut ( ) ;
706
+
707
+ #[ cfg( not( feature = "no_closure" ) ) ]
708
+ let mut target_guard;
709
+ #[ cfg( not( feature = "no_closure" ) ) ]
710
+ let obj = if obj. is_shared ( ) {
711
+ target_guard = obj. write_lock :: < Dynamic > ( ) . unwrap ( ) ;
712
+ & mut * target_guard
713
+ } else {
714
+ obj
715
+ } ;
716
+
678
717
let idx_val = & mut idx_values. pop ( ) . unwrap ( ) ;
679
718
680
- self . get_indexed_mut (
681
- global, caches, target, idx_val, pos, op_pos, false , true ,
682
- )
683
- . map ( |v| ( v. take_or_clone ( ) , false ) )
719
+ self . get_indexed_mut ( global, caches, obj, idx_val, pos, op_pos, false , true )
720
+ . map ( |v| ( v. take_or_clone ( ) , false ) )
684
721
}
685
722
}
686
723
}
@@ -731,13 +768,22 @@ impl Engine {
731
768
732
769
let index = & mut x. 2 . clone ( ) . into ( ) ;
733
770
{
734
- let target = target. as_mut ( ) ;
735
- let val_target = & mut self . get_indexed_mut (
736
- global, caches, target, index, * pos, op_pos, true , false ,
737
- ) ?;
738
- self . eval_op_assignment (
739
- global, caches, op_info, root, val_target, new_val,
771
+ let obj = target. as_mut ( ) ;
772
+
773
+ #[ cfg( not( feature = "no_closure" ) ) ]
774
+ let mut target_guard;
775
+ #[ cfg( not( feature = "no_closure" ) ) ]
776
+ let obj = if obj. is_shared ( ) {
777
+ target_guard = obj. write_lock :: < Dynamic > ( ) . unwrap ( ) ;
778
+ & mut * target_guard
779
+ } else {
780
+ obj
781
+ } ;
782
+
783
+ let item = & mut self . get_indexed_mut (
784
+ global, caches, obj, index, * pos, op_pos, true , false ,
740
785
) ?;
786
+ self . eval_op_assignment ( global, caches, op_info, root, item, new_val) ?;
741
787
}
742
788
self . check_data_size ( target. source ( ) , op_info. position ( ) ) ?;
743
789
Ok ( ( Dynamic :: UNIT , true ) )
@@ -747,12 +793,23 @@ impl Engine {
747
793
#[ cfg( feature = "debugging" ) ]
748
794
self . run_debugger ( global, caches, _scope, this_ptr, rhs) ?;
749
795
750
- let target = target. as_mut ( ) ;
796
+ let obj = target. as_mut ( ) ;
797
+
798
+ #[ cfg( not( feature = "no_closure" ) ) ]
799
+ let mut target_guard;
800
+ #[ cfg( not( feature = "no_closure" ) ) ]
801
+ let obj = if obj. is_shared ( ) {
802
+ target_guard = obj. write_lock :: < Dynamic > ( ) . unwrap ( ) ;
803
+ & mut * target_guard
804
+ } else {
805
+ obj
806
+ } ;
807
+
751
808
let index = & mut x. 2 . clone ( ) . into ( ) ;
752
- let val = self . get_indexed_mut (
753
- global, caches, target , index, * pos, op_pos, false , false ,
809
+ let item = self . get_indexed_mut (
810
+ global, caches, obj , index, * pos, op_pos, false , false ,
754
811
) ?;
755
- Ok ( ( val . take_or_clone ( ) , false ) )
812
+ Ok ( ( item . take_or_clone ( ) , false ) )
756
813
}
757
814
// xxx.id op= ???
758
815
( Expr :: Property ( x, pos) , Some ( ( mut new_val, op_info) ) , false ) => {
@@ -856,16 +913,27 @@ impl Engine {
856
913
let _node = & x. lhs ;
857
914
let mut _this_ptr = this_ptr;
858
915
let _tp = _this_ptr. as_deref_mut ( ) ;
916
+ #[ cfg( not( feature = "no_closure" ) ) ]
917
+ let mut target_guard;
859
918
860
- let val_target = & mut match x. lhs {
919
+ let item = & mut match x. lhs {
861
920
Expr :: Property ( ref p, pos) => {
862
921
#[ cfg( feature = "debugging" ) ]
863
922
self . run_debugger ( global, caches, _scope, _tp, _node) ?;
864
923
865
- let target = target. as_mut ( ) ;
924
+ let obj = target. as_mut ( ) ;
925
+
926
+ #[ cfg( not( feature = "no_closure" ) ) ]
927
+ let obj = if obj. is_shared ( ) {
928
+ target_guard = obj. write_lock :: < Dynamic > ( ) . unwrap ( ) ;
929
+ & mut * target_guard
930
+ } else {
931
+ obj
932
+ } ;
933
+
866
934
let index = & mut p. 2 . clone ( ) . into ( ) ;
867
935
self . get_indexed_mut (
868
- global, caches, target , index, pos, op_pos, false , true ,
936
+ global, caches, obj , index, pos, op_pos, false , true ,
869
937
) ?
870
938
}
871
939
// {xxx:map}.fn_name(arg_expr_list)[expr] | {xxx:map}.fn_name(arg_expr_list).expr
@@ -902,8 +970,8 @@ impl Engine {
902
970
} ;
903
971
904
972
self . eval_dot_index_chain_raw (
905
- global, caches, _scope, _this_ptr, root, rhs, val_target , & x. rhs ,
906
- idx_values , new_val,
973
+ global, caches, _scope, _this_ptr, root, rhs, item , & x. rhs , idx_values ,
974
+ new_val,
907
975
)
908
976
}
909
977
// xxx.sub_lhs[expr] | xxx.sub_lhs.expr
0 commit comments