@@ -570,6 +570,9 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
570570 DUK_ASSERT (!DUK_HEAPHDR_HAS_READONLY ((duk_heaphdr * ) obj ));
571571 DUK_ASSERT_VALSTACK_SPACE (thr , DUK__VALSTACK_SPACE );
572572
573+ /* Invalidate property cache. FIXME: also at the end? */
574+ duk_propcache_invalidate (thr );
575+
573576 /*
574577 * Pre resize assertions.
575578 */
@@ -2668,10 +2671,11 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
26682671 */
26692672 duk_tval * storage ;
26702673 storage = duk_propcache_lookup (thr , curr , key );
2674+ DUK_D (DUK_DPRINT ("propcache GETPROP lookup: %!O %!O -> %p" , orig_base , key , (void * ) storage ));
26712675 if (storage ) {
2672- DUK_D (DUK_DPRINT ("cached lookup %!O -> %!T" , key , storage ));
2673- duk_pop (ctx );
2676+ DUK_D (DUK_DPRINT ("cached GETPROP lookup %!O -> %!T" , key , storage ));
26742677 duk_push_tval (ctx , storage );
2678+ duk_remove (ctx , -2 ); /* FIXME: careful with order */
26752679 /* FIXME: assume no post process? */
26762680 return 1 ;
26772681 }
@@ -2802,9 +2806,13 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
28022806 }
28032807#endif /* !DUK_USE_NONSTD_FUNC_CALLER_PROPERTY */
28042808
2805- if (orig_base && arr_idx == DUK__NO_ARRAY_INDEX ) { /* FIXME: condition */
2809+ if (orig_base && arr_idx == DUK__NO_ARRAY_INDEX && desc . e_idx >= 0 ) { /* FIXME: condition */
28062810 /* FIXME: other conditions, e.g. not a getter */
2807- duk_propcache_insert (thr , orig_base , key , DUK_GET_TVAL_NEGIDX (ctx , -1 ));
2811+ /* FIXME: note that caching is based on orig_base, but storage location is in 'curr'! */
2812+ duk_tval * tv_storage ;
2813+ tv_storage = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR (thr -> heap , curr , desc .e_idx );
2814+ DUK_D (DUK_DPRINT ("insert propcache GETPROP %!O" , key ));
2815+ duk_propcache_insert (thr , orig_base , key , tv_storage );
28082816 }
28092817
28102818 duk_remove_m2 (ctx ); /* [key result] -> [result] */
@@ -3338,6 +3346,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
33383346 duk_tval tv_key_copy ;
33393347 duk_tval tv_val_copy ;
33403348 duk_hobject * orig = NULL ; /* NULL if tv_obj is primitive */
3349+ duk_hobject * orig_base ;
33413350 duk_hobject * curr ;
33423351 duk_hstring * key = NULL ;
33433352 duk_propdesc desc ;
@@ -3362,7 +3371,12 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
33623371
33633372 DUK_ASSERT_VALSTACK_SPACE (thr , DUK__VALSTACK_SPACE );
33643373
3374+ /* FIXME... with storage location caching, only need to invalidate
3375+ * if new properties are established (may shadow existing chains)?
3376+ */
3377+ #if 0
33653378 duk_propcache_invalidate (thr );
3379+ #endif
33663380
33673381 /*
33683382 * Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of
@@ -3664,6 +3678,23 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
36643678
36653679 lookup :
36663680
3681+ DUK_ASSERT (curr != NULL );
3682+ orig_base = curr ;
3683+
3684+ {
3685+ /* FIXME: when base is primitive, we cache the "wrong" property,
3686+ * which is fine.
3687+ */
3688+ duk_tval * storage ;
3689+ storage = duk_propcache_lookup (thr , orig_base , key );
3690+ DUK_D (DUK_DPRINT ("propcache PUTPROP lookup: %!O %!O -> %p" , orig_base , key , (void * ) storage ));
3691+ if (storage ) {
3692+ DUK_D (DUK_DPRINT ("cached PUTPROP lookup %!O -> old value %!T" , key , storage ));
3693+ DUK_TVAL_SET_TVAL_UPDREF (thr , storage , tv_val );
3694+ goto success_no_arguments_exotic ;
3695+ }
3696+ }
3697+
36673698 /*
36683699 * Check whether the property already exists in the prototype chain.
36693700 * Note that the actual write goes into the original base object
@@ -3888,6 +3919,14 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
38883919
38893920 if (desc .e_idx >= 0 ) {
38903921 tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR (thr -> heap , orig , desc .e_idx );
3922+
3923+ /* FIXME argument exotic condition... */
3924+ if (1 ) { /* FIXME: condition */
3925+ /* FIXME: other conditions, e.g. not a getter */
3926+ DUK_D (DUK_DPRINT ("insert propcache PUTPROP %!O" , key ));
3927+ duk_propcache_insert (thr , orig_base , key , tv );
3928+ }
3929+
38913930 DUK_DDD (DUK_DDDPRINT ("previous entry value: %!iT" , (duk_tval * ) tv ));
38923931 DUK_TVAL_SET_TVAL_UPDREF (thr , tv , tv_val ); /* side effects; e_idx may be invalidated */
38933932 /* don't touch property attributes or hash part */
@@ -4090,6 +4129,12 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
40904129
40914130 write_to_entry_part :
40924131
4132+ /* Must invalidate: new property may affect existing inheritance
4133+ * chains.
4134+ */
4135+ duk_propcache_invalidate (thr );
4136+
4137+
40934138 /*
40944139 * Write to entry part
40954140 */
0 commit comments