Changeset 88180d in git


Ignore:
Timestamp:
Sep 4, 2012, 11:35:14 PM (12 years ago)
Author:
Alexander Dreyer <alexander.dreyer@…>
Branches:
(u'spielwiese', 'fe61d9c35bf7c61f2b6cbf1b56e25e2f08d536cc')
Children:
d94836e0b38201eda7edf1d2094a7376a0090806
Parents:
cda275f5c6745c233d1ee5261720c388c5286ec9
git-author:
Alexander Dreyer <alexander.dreyer@itwm.fraunhofer.de>2012-09-04 23:35:14+02:00
git-committer:
Oleksandr Motsak <motsak@mathematik.uni-kl.de>2012-09-05 15:52:17+02:00
Message:
fix: ensure we always have RefCounted object alive
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • Singular/countedref.cc

    rcda275f r88180d  
    4848/** @class CountedRefData
    4949 * This class stores a reference counter as well as a Singular interpreter object.
    50  * It also take care of the context, e.g. the current ring, indexed object, etc.
     50 * It also take care of the context, e.g. the current ring, wrap object, etc.
    5151 **/
    5252class CountedRefData:
     
    5959
    6060  /// Generate object linked to other reference (e.g. for subscripts)
    61   CountedRefData(leftv wrapped, back_ptr back):
    62     base(), m_data(wrapped), m_ring(back->m_ring), m_back(back) {
     61  CountedRefData(leftv wrapid, back_ptr back):
     62    base(), m_data(wrapid), m_ring(back->m_ring), m_back(back) {
    6363  }
    6464
     
    101101
    102102  /// Generate object for indexing
    103   ptr_type subscripted() { return new self(m_data.idify(root()), weakref()); }
     103  ptr_type wrapid() { return new self(m_data.idify(root()), weakref()); }
    104104
    105105  /// Gerenate  weak (but managed) reference to @c *this
     
    151151
    152152  /// Reassign actual object
    153   BOOLEAN assign(leftv result, leftv arg) {
     153  BOOLEAN assign(leftv result, leftv arg) {
     154
    154155    if (!m_data.isid()) {
    155156      (*this) = arg;
     
    183184  ring_ptr m_ring;
    184185
    185   /// Reference to actual object for indexed structures 
     186  /// Reference to actual object for wrap structures 
    186187  back_ptr m_back;
    187188};
     
    192193
    193194/// blackbox support - initialization
    194 /// @note deals as marker for compatible references, too.
    195195void* countedref_Init(blackbox*)
    196196{
     
    237237  }
    238238
    239   BOOLEAN assign(leftv result, leftv arg) { 
     239  BOOLEAN assign(leftv result, leftv arg) {
    240240    return m_data->assign(result,arg);
    241241  }
     
    317317  /// Recover the actual object from Singular interpreter object
    318318  static self cast(leftv arg) {
    319     assume((arg != NULL) && is_ref(arg));
     319    assume(arg != NULL); assume(is_ref(arg));
    320320    return self::cast(arg->Data());
    321321  }
     
    348348  }
    349349
    350 
    351350protected:
    352351  /// Store pointer to actual data
     
    380379  // Case: replace assignment behind reference
    381380  if (result->Data() != NULL) {
    382     return CountedRef::resolve(arg) ||
    383       CountedRef::cast(result).assign(result, arg);     
     381    CountedRef ref = CountedRef::cast(result);
     382    return CountedRef::resolve(arg) || ref.assign(result, arg);
    384383  }
    385384 
     
    409408  if(op == TYPEOF_CMD)
    410409    return blackboxDefaultOp1(op, res, head);
    411 
    412410
    413411  if (countedref_CheckInit(res, head)) return TRUE;
     
    418416  }
    419417
    420   if(op == LINK_CMD) {
    421     res->rtyp =  DEF_CMD;
    422     return CountedRef::cast(head).dereference(head) || iiAssign(res, head);
    423   }
    424 
    425   return CountedRef::cast(head).dereference(head) || iiExprArith1(res, head, op);
    426 }
    427 
    428 /// blackbox support - binary operations
     418  CountedRef ref = CountedRef::cast(head);
     419  return ref.dereference(head) ||
     420    iiExprArith1(res, head, op == LINK_CMD? head->Typ(): op);
     421}
     422
     423
     424
     425/// blackbox support - binary operations (resolve seocnd argument)
     426static BOOLEAN countedref_Op2_(int op, leftv res, leftv head, leftv arg)
     427{
     428  if (CountedRef::is_ref(arg)) {
     429    CountedRef ref = CountedRef::cast(arg);
     430    return ref.dereference(arg) || iiExprArith2(res, head, op, arg);
     431  }
     432  return  iiExprArith2(res, head, op, arg);
     433}
     434
    429435BOOLEAN countedref_Op2(int op, leftv res, leftv head, leftv arg)
    430436{
    431    return countedref_CheckInit(res, head) ||
    432     CountedRef::cast(head).dereference(head) ||
    433     CountedRef::resolve(arg) ||
    434     iiExprArith2(res, head, op, arg);
     437  if (countedref_CheckInit(res, head)) return TRUE;
     438  if (CountedRef::is_ref(head)) {
     439    CountedRef ref = CountedRef::cast(head);
     440    return ref.dereference(head) || countedref_Op2_(op, res, head, arg);
     441  }
     442  return countedref_Op2_(op, res, head, arg);
     443}
     444
     445static BOOLEAN countedref_Op3__(int op, leftv res, leftv head, leftv arg1, leftv arg2)
     446{
     447
     448  if (CountedRef::is_ref(arg2)) {
     449    CountedRef ref = CountedRef::cast(arg2);
     450    return ref.dereference(arg2) || iiExprArith3(res, op, head, arg1, arg2);
     451  }
     452  return iiExprArith3(res, op, head, arg1, arg2);
     453}
     454
     455static BOOLEAN countedref_Op3_(int op, leftv res, leftv head, leftv arg1, leftv arg2)
     456{
     457  if (CountedRef::is_ref(arg1)) {
     458    CountedRef ref = CountedRef::cast(arg1);
     459    return ref.dereference(arg1) || countedref_Op3__(op, res, head, arg1, arg2);
     460  }
     461  return countedref_Op3__(op, res, head, arg1, arg2);
    435462}
    436463
     
    439466BOOLEAN countedref_Op3(int op, leftv res, leftv head, leftv arg1, leftv arg2)
    440467{
    441   return countedref_CheckInit(res, head) ||
    442     CountedRef::cast(head).dereference(head) ||
    443     CountedRef::resolve(arg1) || CountedRef::resolve(arg2) ||
    444     iiExprArith3(res, op, head, arg1, arg2);
     468  if (countedref_CheckInit(res, head)) return TRUE;
     469  if (CountedRef::is_ref(head)) {
     470    CountedRef ref = CountedRef::cast(head);
     471    return ref.dereference(head) || countedref_Op3_(op, res, head, arg1, arg2);
     472  }
     473  return countedref_Op3_(op, res, head, arg1, arg2);
    445474}
    446475
     
    489518
    490519  /// Temporarily wrap with identifier for '[' and '.' operation
    491   self subscripted() { return self(m_data->subscripted()); }
    492 
    493   ///
     520  self wrapid() { return self(m_data->wrapid()); }
     521
     522  /// Generate weak reference (may get invalid)
    494523  data_type::back_ptr weakref() { return m_data->weakref(); }
    495524
     525  /// Recover more information (e.g. subexpression data) from computed result
    496526  BOOLEAN retrieve(leftv res, int typ) {
    497527    return (m_data->retrieve(res) && outcast(res, typ));
     
    505535}
    506536
     537/// Blackbox support - unary operation for shared data
     538BOOLEAN countedref_Op1Shared(int op, leftv res, leftv head)
     539{
     540  if(op == TYPEOF_CMD)
     541    return blackboxDefaultOp1(op, res, head);
     542
     543  if (countedref_CheckInit(res, head)) return TRUE;
     544
     545  if ((op == DEF_CMD) || (op == head->Typ())) {
     546    res->rtyp = head->Typ();
     547    return iiAssign(res, head);
     548  }
     549
     550  CountedRefShared ref = CountedRefShared::cast(head);
     551  CountedRefShared wrap = ref.wrapid();
     552  int typ = head->Typ();
     553  return wrap.dereference(head) ||
     554    iiExprArith1(res, head, op == LINK_CMD? head->Typ(): op) ||
     555    wrap.retrieve(res, typ);
     556}
     557
     558
    507559/// blackbox support - binary operations
    508560BOOLEAN countedref_Op2Shared(int op, leftv res, leftv head, leftv arg)
    509561{
    510   if  ((op == '[') || (op == '.')) {
    511     if (countedref_CheckInit(res, head))  return TRUE;
    512     CountedRefShared indexed = CountedRefShared::cast(head).subscripted();
    513 
     562  if (countedref_CheckInit(res, head))  return TRUE;
     563
     564  if (CountedRefShared::is_ref(head)) {
     565    CountedRefShared wrap = CountedRefShared::cast(head).wrapid();
    514566    int typ = head->Typ();
    515     return indexed.dereference(head) || CountedRefShared::resolve(arg) ||
    516       iiExprArith2(res, head, op, arg) || indexed.retrieve(res, typ);
    517   }
    518 
    519   return countedref_Op2(op, res, head, arg);
     567    return wrap.dereference(head) || countedref_Op2_(op, res, head, arg) ||
     568      wrap.retrieve(res, typ);
     569  }
     570
     571  return countedref_Op2_(op, res, head, arg);
    520572}
    521573
     
    566618    return jjLIST_PL(res, args);
    567619  }
    568 
    569   return CountedRef::cast(args).dereference(args) || iiExprArithM(res, args, op);
     620  CountedRef ref = CountedRef::cast(args);
     621  return ref.dereference(args) || iiExprArithM(res, args, op);
    570622}
    571623
     
    575627  /// Case: replace assignment behind reference
    576628  if ((result->Data() != NULL)  && !CountedRefShared::cast(result).unassigned()) {
    577     if (CountedRefShared::resolve(arg)) return TRUE;
    578     return CountedRefShared::cast(result).assign(result, arg);
    579     return FALSE;
     629    CountedRef ref = CountedRef::cast(result);
     630    return CountedRef::resolve(arg) || ref.assign(result, arg);
    580631  }
    581632 
     
    587638  } 
    588639  if(CountedRefShared::cast(result).unassigned()) {
    589    // CountedRefShared::cast(result) = arg;
    590640   return CountedRefShared::cast(result).assign(result, arg);
    591641
     
    649699  bbxshared->blackbox_Assign  = countedref_AssignShared;
    650700  bbxshared->blackbox_destroy = countedref_destroyShared;
     701  bbxshared->blackbox_Op1     = countedref_Op1Shared;
    651702  bbxshared->blackbox_Op2     = countedref_Op2Shared;
    652703  bbxshared->blackbox_Init    = countedref_InitShared;
Note: See TracChangeset for help on using the changeset viewer.