| … | … | @@ -43,19 +43,50 @@ SetValueLink::SetValueLink(const HandleSeq&& oset, Type t) |
| 43 | 43 | |
| 44 | 44 | // --------------------------------------------------------------- |
| 45 | 45 | |
| 46 | // SetValue must work in the local AtomSpace. This includes |
| 47 | // the evaluation of keys, as needed. |
| 48 | Handle SetValueLink::localize(AtomSpace* as, bool silent, const Handle& h) const |
| 49 | { |
| 50 | if (not h->is_executable()) |
| 51 | return as->add_atom(h); |
| 52 | |
| 53 | ValuePtr pap(h->execute(as, silent)); |
| 54 | if (pap and pap->is_atom()) |
| 55 | return as->add_atom(HandleCast(pap)); |
| 56 | return h; |
| 57 | } |
| 58 | |
| 46 | 59 | /// When executed, this will execute the third argument to obtain |
| 47 | 60 | /// a Value, and then set that Value at the indicated key on the |
| 48 | 61 | /// first argument. The computed value is returned. |
| 49 | 62 | /// The SetValueOn link returns the Atom, not the Value. |
| 50 | 63 | ValuePtr SetValueLink::execute(AtomSpace* as, bool silent) |
| 51 | 64 | { |
| 65 | // We cannot know the Value of the Atom unless we are |
| 66 | // working with the unique version that sits in the |
| 67 | // AtomSpace! It can happen, during evaluation e.g. of |
| 68 | // a PutLink, that we are given an Atom that is not in |
| 69 | // any AtomSpace. In this case, `as` will be a scratch |
| 70 | // space; we can add the Atom there, and things will |
| 71 | // trickle out properly in the end. |
| 72 | // |
| 73 | // Avoid null-pointer deref due to user error. |
| 74 | // This can happen with improperly built FilterLinks. |
| 75 | if (nullptr == as) |
| 76 | throw RuntimeException(TRACE_INFO, |
| 77 | "Expecting AtomSpace, got null pointer for %s\n", |
| 78 | to_string().c_str()); |
| 79 | |
| 80 | Handle ah(localize(as, silent, _outgoing[0])); |
| 81 | Handle ak(localize(as, silent, _outgoing[1])); |
| 82 | |
| 52 | 83 | // Default VoidValue |
| 53 | 84 | if (2 == _outgoing.size()) |
| 54 | 85 | { |
| 55 | 86 | ValuePtr pap(createVoidValue()); |
| 56 | | as->set_value(_outgoing[0], _outgoing[1], pap); |
| 87 | as->set_value(ah, ak, pap); |
| 57 | 88 | if (SET_VALUE_ON_LINK == get_type()) |
| 58 | | return _outgoing[0]; |
| 89 | return ah; |
| 59 | 90 | return pap; |
| 60 | 91 | } |
| 61 | 92 | |
| … | … | @@ -68,10 +99,10 @@ ValuePtr SetValueLink::execute(AtomSpace* as, bool silent) |
| 68 | 99 | else |
| 69 | 100 | pap = _outgoing[2]; |
| 70 | 101 | |
| 71 | | as->set_value(_outgoing[0], _outgoing[1], pap); |
| 102 | as->set_value(ah, ak, pap); |
| 72 | 103 | |
| 73 | 104 | if (SET_VALUE_ON_LINK == get_type()) |
| 74 | | return _outgoing[0]; |
| 105 | return ah; |
| 75 | 106 | return pap; |
| 76 | 107 | } |
| 77 | 108 | |
| … | … | @@ -99,10 +130,10 @@ ValuePtr SetValueLink::execute(AtomSpace* as, bool silent) |
| 99 | 130 | else |
| 100 | 131 | fsp = createFutureStream(exo); |
| 101 | 132 | |
| 102 | | as->set_value(_outgoing[0], _outgoing[1], fsp); |
| 133 | as->set_value(ah, ak, fsp); |
| 103 | 134 | |
| 104 | 135 | if (SET_VALUE_ON_LINK == get_type()) |
| 105 | | return _outgoing[0]; |
| 136 | return ah; |
| 106 | 137 | return fsp; |
| 107 | 138 | } |
| 108 | 139 | |