@@ -281,14 +281,17 @@ namespace rt::core
281281 : objects::DynObject(cownPrototypeObject(), objects::cown_region)
282282 {
283283 status = Status::Pending;
284- auto region = objects::get_region (obj);
284+ auto old = set (" value" , obj);
285+ assert (!old);
286+ }
285287
286- if (!obj->is_immutable () && !obj->is_cown ())
287- {
288- // TODO: Make sure we're parenting the region and add third state, like
289- // pending
290- // Staring in an aquired state will allow the normal usage of `set`
288+ [[nodiscard]] DynObject* set (std::string name, DynObject* obj) override
289+ {
290+ assert_modifiable ();
291291
292+ if (obj && !obj->is_immutable () && !obj->is_cown ())
293+ {
294+ auto region = objects::get_region (obj);
292295 // Potentiall error message
293296 std::stringstream ss;
294297 ss << " Object is neither immutable nor a cown, attempted to threat it "
@@ -307,16 +310,23 @@ namespace rt::core
307310 << region->parent ->bridge ;
308311 ui::error (ss.str (), {this , " " , obj});
309312 }
313+
314+ region->cown = this ;
310315 }
311316
312- auto old = set ( " value " , obj) ;
313- assert (!old) ;
317+ DynObject* old = fields[name] ;
318+ fields[name] = obj ;
314319
315- // 1x LRC from the stack
316- if (region->local_reference_count == 1 )
320+ if (old && !old->is_immutable () && !old->is_cown ())
317321 {
318- status = Status::Released;
322+ auto old_reg = objects::get_region (old);
323+ assert (old_reg->cown == this );
324+ old_reg->cown = nullptr ;
319325 }
326+
327+ update_status ();
328+
329+ return old;
320330 }
321331
322332 std::string get_name () override
@@ -346,6 +356,34 @@ namespace rt::core
346356 return true ;
347357 }
348358 }
359+
360+ bool is_released ()
361+ {
362+ return this ->status == Status::Released;
363+ }
364+
365+ // / This function updates the status of the cown. It mainly checks if a
366+ // / cown in the pending state can be released.
367+ void update_status ()
368+ {
369+ if (status != Status::Pending)
370+ {
371+ return ;
372+ }
373+
374+ auto value = this ->get (" value" ).value ();
375+ if (!value || value->is_immutable () || value->is_cown ())
376+ {
377+ status = Status::Released;
378+ return ;
379+ }
380+
381+ auto region = objects::get_region (value);
382+ if (region->combined_lrc () == 0 )
383+ {
384+ status = Status::Released;
385+ }
386+ }
349387 };
350388
351389 inline std::set<objects::DynObject*>* globals ()
0 commit comments