@@ -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 */
@@ -2666,10 +2669,11 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
26662669 */
26672670 duk_tval * storage ;
26682671 storage = duk_propcache_lookup (thr , curr , key );
2672+ DUK_D (DUK_DPRINT ("propcache GETPROP lookup: %!O %!O -> %p" , orig_base , key , (void * ) storage ));
26692673 if (storage ) {
2670- DUK_D (DUK_DPRINT ("cached lookup %!O -> %!T" , key , storage ));
2671- duk_pop (ctx );
2674+ DUK_D (DUK_DPRINT ("cached GETPROP lookup %!O -> %!T" , key , storage ));
26722675 duk_push_tval (ctx , storage );
2676+ duk_remove (ctx , -2 ); /* FIXME: careful with order */
26732677 /* FIXME: assume no post process? */
26742678 return 1 ;
26752679 }
@@ -2800,9 +2804,13 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
28002804 }
28012805#endif /* !DUK_USE_NONSTD_FUNC_CALLER_PROPERTY */
28022806
2803- if (orig_base && arr_idx == DUK__NO_ARRAY_INDEX ) { /* FIXME: condition */
2807+ if (orig_base && arr_idx == DUK__NO_ARRAY_INDEX && desc . e_idx >= 0 ) { /* FIXME: condition */
28042808 /* FIXME: other conditions, e.g. not a getter */
2805- duk_propcache_insert (thr , orig_base , key , DUK_GET_TVAL_NEGIDX (ctx , -1 ));
2809+ /* FIXME: note that caching is based on orig_base, but storage location is in 'curr'! */
2810+ duk_tval * tv_storage ;
2811+ tv_storage = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR (thr -> heap , curr , desc .e_idx );
2812+ DUK_D (DUK_DPRINT ("insert propcache GETPROP %!O" , key ));
2813+ duk_propcache_insert (thr , orig_base , key , tv_storage );
28062814 }
28072815
28082816 duk_remove_m2 (ctx ); /* [key result] -> [result] */
@@ -3336,6 +3344,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
33363344 duk_tval tv_key_copy ;
33373345 duk_tval tv_val_copy ;
33383346 duk_hobject * orig = NULL ; /* NULL if tv_obj is primitive */
3347+ duk_hobject * orig_base ;
33393348 duk_hobject * curr ;
33403349 duk_hstring * key = NULL ;
33413350 duk_propdesc desc ;
@@ -3360,7 +3369,12 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
33603369
33613370 DUK_ASSERT_VALSTACK_SPACE (thr , DUK__VALSTACK_SPACE );
33623371
3372+ /* FIXME... with storage location caching, only need to invalidate
3373+ * if new properties are established (may shadow existing chains)?
3374+ */
3375+ #if 0
33633376 duk_propcache_invalidate (thr );
3377+ #endif
33643378
33653379 /*
33663380 * Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of
@@ -3662,6 +3676,23 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
36623676
36633677 lookup :
36643678
3679+ DUK_ASSERT (curr != NULL );
3680+ orig_base = curr ;
3681+
3682+ {
3683+ /* FIXME: when base is primitive, we cache the "wrong" property,
3684+ * which is fine.
3685+ */
3686+ duk_tval * storage ;
3687+ storage = duk_propcache_lookup (thr , orig_base , key );
3688+ DUK_D (DUK_DPRINT ("propcache PUTPROP lookup: %!O %!O -> %p" , orig_base , key , (void * ) storage ));
3689+ if (storage ) {
3690+ DUK_D (DUK_DPRINT ("cached PUTPROP lookup %!O -> old value %!T" , key , storage ));
3691+ DUK_TVAL_SET_TVAL_UPDREF (thr , storage , tv_val );
3692+ goto success_no_arguments_exotic ;
3693+ }
3694+ }
3695+
36653696 /*
36663697 * Check whether the property already exists in the prototype chain.
36673698 * Note that the actual write goes into the original base object
@@ -3886,6 +3917,14 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
38863917
38873918 if (desc .e_idx >= 0 ) {
38883919 tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR (thr -> heap , orig , desc .e_idx );
3920+
3921+ /* FIXME argument exotic condition... */
3922+ if (1 ) { /* FIXME: condition */
3923+ /* FIXME: other conditions, e.g. not a getter */
3924+ DUK_D (DUK_DPRINT ("insert propcache PUTPROP %!O" , key ));
3925+ duk_propcache_insert (thr , orig_base , key , tv );
3926+ }
3927+
38893928 DUK_DDD (DUK_DDDPRINT ("previous entry value: %!iT" , (duk_tval * ) tv ));
38903929 DUK_TVAL_SET_TVAL_UPDREF (thr , tv , tv_val ); /* side effects; e_idx may be invalidated */
38913930 /* don't touch property attributes or hash part */
@@ -4088,6 +4127,12 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
40884127
40894128 write_to_entry_part :
40904129
4130+ /* Must invalidate: new property may affect existing inheritance
4131+ * chains.
4132+ */
4133+ duk_propcache_invalidate (thr );
4134+
4135+
40914136 /*
40924137 * Write to entry part
40934138 */
0 commit comments