serious bugfix in Raise_IdxError (number got formatted as string, causing a segmentat...
[vox.git] / src / core / object.cpp
blob43d4493e909a2d791253ec4a2e233a5f9e15e1fe
2 #include "pcheader.hpp"
3 #include "vm.hpp"
4 #include "string.hpp"
5 #include "table.hpp"
6 #include "userdata.hpp"
7 #include "funcproto.hpp"
8 #include "class.hpp"
9 #include "closure.hpp"
14 VXWeakRefObj *VXRefCountedObj::GetWeakRef(VXOType type)
16 if(!_weakref)
18 vox_new(_weakref,VXWeakRefObj);
19 _weakref->_obj._type = type;
20 _weakref->_obj._unVal.pRefCounted = this;
22 return _weakref;
25 VXRefCountedObj::~VXRefCountedObj()
27 if(_weakref)
29 _weakref->_obj._type = VX_OT_NULL;
30 _weakref->_obj._unVal.pRefCounted = NULL;
34 void VXWeakRefObj::Release()
36 if(ISREFCOUNTED(_obj._type))
38 _obj._unVal.pRefCounted->_weakref = NULL;
40 vox_delete(this,VXWeakRefObj);
43 bool VXDelegableObj::GetMetaMethod(VXState *v,VXMetaMethod mm,VXObject &res)
45 if(_delegate)
47 return _delegate->Get((*_ss(v)->_metamethods)[mm],res);
49 return false;
52 bool VXDelegableObj::SetDelegate(VXTableObj *mt)
54 VXTableObj *temp = mt;
55 if(temp == this)
57 return false;
59 while(temp)
61 // loop detected
62 if(temp->_delegate == this)
64 return false;
66 temp = temp->_delegate;
68 if(mt)
70 __ObjAddRef(mt);
72 __ObjRelease(_delegate);
73 this->_delegate = mt;
74 return true;
77 bool VXGeneratorObj::Yield(VXState *v,VXInteger target)
79 if(_state==eSuspended)
81 v->ThrowError("internal vm error, yielding dead generator");
82 return false;
84 if(_state==eDead)
86 v->ThrowError("internal vm error, yielding a dead generator");
87 return false;
89 VXInteger size = ((v->_top) - (v->_stackbase));
90 _stack.resize(size);
91 VXRawObj _this = v->_stack[v->_stackbase];
92 _stack.values()[0] = (
93 ISREFCOUNTED(type(_this)) ?
94 VXObject(_refcounted(_this)->GetWeakRef(type(_this))) :
95 _this);
96 for(VXInteger n =1; n<target; n++)
98 _stack.values()[n] = v->_stack[v->_stackbase+n];
100 for(VXInteger j =0; j < size; j++)
102 v->_stack[v->_stackbase+j].Null();
105 _ci = *v->ci;
106 _ci._generator=NULL;
107 for(VXInteger i=0;i<_ci._etraps;i++)
109 _etraps.push_back(v->_etraps.top());
110 v->_etraps.pop_back();
112 _state=eSuspended;
113 return true;
116 bool VXGeneratorObj::Resume(VXState *v,VXObject &dest)
118 if(_state==eDead)
120 v->ThrowError("resuming dead generator");
121 return false;
123 if(_state==eRunning)
125 v->ThrowError("resuming active generator");
126 return false;
128 VXInteger size = _stack.size();
129 VXInteger target = &dest - &(v->_stack.values()[v->_stackbase]);
130 vox_assert(target>=0 && target<=255);
131 if(!v->EnterFrame(v->_top, v->_top + size, false))
133 return false;
135 v->ci->_generator = this;
136 v->ci->_target = (VXInt32)target;
137 v->ci->_closure = _ci._closure;
138 v->ci->_ip = _ci._ip;
139 v->ci->_literals = _ci._literals;
140 v->ci->_ncalls = _ci._ncalls;
141 v->ci->_etraps = _ci._etraps;
142 v->ci->_root = _ci._root;
143 for(VXInteger i=0;i<_ci._etraps;i++)
145 v->_etraps.push_back(_etraps.top());
146 _etraps.pop_back();
148 VXRawObj _this = _stack.values()[0];
149 v->_stack[v->_stackbase] = type(_this) == VX_OT_WEAKREF ? _weakref(_this)->_obj : _this;
151 for(VXInteger n = 1; n<size; n++)
153 v->_stack[v->_stackbase+n] = _stack.values()[n];
154 _stack.values()[n].Null();
157 _state=eRunning;
158 if (v->_debughook)
160 v->CallDebugHook('c');
162 return true;
166 void VXInstanceObj::Mark(VXCollectable **chain)
168 START_MARK()
169 _class->Mark(chain);
170 VXUnsignedInteger nvalues = _class->_defaultvalues.size();
171 for(VXUnsignedInteger i =0; i< nvalues; i++)
173 VXSharedState::MarkObject(_values[i], chain);
175 END_MARK()
178 void VXGeneratorObj::Mark(VXCollectable **chain)
180 START_MARK()
181 for(VXUnsignedInteger i = 0; i < _stack.size(); i++)
183 VXSharedState::MarkObject(_stack[i], chain);
185 VXSharedState::MarkObject(_closure, chain);
186 END_MARK()
191 void VXOuterObj::Mark(VXCollectable **chain)
193 START_MARK()
194 /* If the valptr points to a closed value, that value is alive */
195 if(_valptr == &_value)
197 VXSharedState::MarkObject(_value, chain);
199 END_MARK()
202 void VXUserDataObj::Mark(VXCollectable **chain)
204 START_MARK()
205 if(_delegate)
207 _delegate->Mark(chain);
209 END_MARK()
212 void VXCollectable::UnMark()
214 _uiRef&=~MARK_FLAG;
219 void VXObject::Null()
221 __Release(_type ,_unVal);
222 _type = VX_OT_NULL;
223 _unVal.raw = (VXRawValue)NULL;
226 bool VXObject::IsNull() const
228 return (_unVal.raw == (VXRawValue)NULL);
231 bool VXObject::IsNumeric() const
233 return (Type() & VXOBJECT_NUMERIC);
238 * Object instance access methods
241 VXInteger VXObject::Integer()
243 return _unVal.nInteger;
246 VXInteger VXObject::Integer() const
248 return _unVal.nInteger;
251 VXFloat VXObject::Float()
253 return _unVal.fFloat;
256 VXFloat VXObject::Float() const
258 return _unVal.fFloat;
261 VXStringObj* VXObject::String()
263 return _unVal.pString;
267 VXStringObj* VXObject::String() const
269 return _unVal.pString;
272 void VXObject::String(const char** dest, VXInteger* len_dest) const
274 VXStringObj* ob = this->String();
275 (*dest) = ob->_val;
276 if(len_dest != NULL)
278 (*len_dest) = ob->_len;
282 VXTableObj* VXObject::Table()
284 return _unVal.pTable;
287 VXTableObj* VXObject::Table() const
289 return _unVal.pTable;
292 VXArrayObj* VXObject::Array()
294 return _unVal.pArray;
297 VXArrayObj* VXObject::Array() const
299 return _unVal.pArray;
301 VXForeignClosureObj* VXObject::Closure()
303 return _unVal.pClosure;
306 VXGeneratorObj* VXObject::Generator()
308 return _unVal.pGenerator;
311 VXNativeClosureObj* VXObject::NativeClosure()
313 return _unVal.pNativeClosure;
316 VXUserDataObj* VXObject::UserData()
318 return _unVal.pUserData;
321 VXUserPointer VXObject::UserPointer()
323 return _unVal.pUserPointer;
326 VXState* VXObject::Thread()
328 return _unVal.pThread;
331 VXFuncProtoObj* VXObject::FuncProto()
333 return _unVal.pFunctionProto;
336 VXClassObj* VXObject::Class()
338 return _unVal.pClass;
341 VXClassObj* VXObject::Class() const
343 return _unVal.pClass;
346 VXInstanceObj* VXObject::Instance()
348 return _unVal.pInstance;
351 VXDelegableObj* VXObject::Delegable()
353 return (VXDelegableObj*)(_unVal.pDelegable);
356 VXWeakRefObj* VXObject::WeakRef()
358 return _unVal.pWeakRef;
361 VXOuterObj* VXObject::Outer()
363 return _unVal.pOuter;
366 VXRefCountedObj* VXObject::RefCounted()
368 return _unVal.pRefCounted;
371 VXRefCountedObj* VXObject::RefCounted() const
373 return _unVal.pRefCounted;
376 VXRawValue VXObject::Raw()
378 return _unVal.raw;
382 template<> VXFloat VXObject::As<VXFloat>()
384 return Float();
387 template<> VXInteger VXObject::As<VXInteger>()
389 return Integer();
393 * Type Information
396 VXOType VXObject::Type() const
398 return _type;
401 const char* VXObject::TypeString() const
403 return IdType2Name(this->Type());
406 bool VXObject::Is(VXOType tp) const
408 return Type() == tp;
411 bool VXObject::IsTable() const
413 return Is(VX_OT_TABLE);
416 bool VXObject::IsArray() const
418 return Is(VX_OT_ARRAY);
421 bool VXObject::IsFunction() const
423 return Is(VX_OT_FUNCPROTO);
425 bool VXObject::IsClosure() const
427 return Is(VX_OT_CLOSURE);
430 bool VXObject::IsNativeClosure() const
432 return Is(VX_OT_NATIVECLOSURE);
435 bool VXObject::IsGenerator() const
437 return Is(VX_OT_GENERATOR);
440 bool VXObject::IsString() const
442 return Is(VX_OT_STRING);
445 bool VXObject::IsInteger() const
447 return Is(VX_OT_INTEGER);
450 bool VXObject::IsFloat() const
452 return Is(VX_OT_FLOAT);
455 bool VXObject::IsUserPointer() const
457 return Is(VX_OT_USERPOINTER);
460 bool VXObject::IsUserData() const
462 return Is(VX_OT_USERDATA);
465 bool VXObject::IsThread() const
467 return Is(VX_OT_THREAD);
470 bool VXObject::IsClass() const
472 return Is(VX_OT_CLASS);
475 bool VXObject::IsInstance() const
477 return Is(VX_OT_INSTANCE);
480 bool VXObject::IsBool() const
482 return Is(VX_OT_BOOL);
485 bool VXObject::IsWeakRef() const
487 return Is(VX_OT_WEAKREF);
491 * Constructors
494 VXObject::~VXObject()
496 __Release(_type,_unVal);
499 VXObject::VXObject()
501 VX_OBJECT_RAWINIT(this)
502 _type=VX_OT_NULL;
503 _unVal.pUserPointer=NULL;
505 VXObject::VXObject(const VXObject &o)
507 _type=o._type;
508 _unVal=o._unVal;
509 VX_ADDREF(_type,_unVal);
512 VXObject::VXObject(const VXRawObj &o)
514 _type=o._type;
515 _unVal=o._unVal;
516 VX_ADDREF(_type,_unVal);
520 VXObject::VXObject(bool bBool)
522 VX_OBJECT_RAWINIT(this)
523 _type = VX_OT_BOOL;
524 _unVal.nInteger = bBool?1:0;
527 VXObject::VXObject (VXTableObj * x)
529 VX_OBJECT_RAWINIT(this)
530 _type = VX_OT_TABLE;
531 _unVal.pTable = x;
532 vox_assert (_unVal.pTable);
533 _unVal.pRefCounted->_uiRef++;
536 VXObject::VXObject (VXClassObj * x)
538 VX_OBJECT_RAWINIT(this)
539 _type = VX_OT_CLASS;
540 _unVal.pClass = x;
541 vox_assert (_unVal.pTable);
542 _unVal.pRefCounted->_uiRef++;
545 VXObject & VXObject::operator= (VXClassObj * x)
547 VXOType tOldType;
548 VXRawObj::Value unOldVal;
549 tOldType = _type;
550 unOldVal = _unVal;
551 _type = VX_OT_CLASS;
552 VX_REFOBJECT_INIT (this)
553 _unVal.pClass = x;
554 _unVal.pRefCounted->_uiRef++;
555 __Release (tOldType, unOldVal);
556 return *this;
559 VXObject::VXObject (VXInstanceObj * x)
561 VX_OBJECT_RAWINIT(this)
562 _type = VX_OT_INSTANCE;
563 _unVal.pInstance = x;
564 vox_assert (_unVal.pTable);
565 _unVal.pRefCounted->_uiRef++;
568 VXObject::VXObject(VXArrayObj * x)
570 VX_OBJECT_RAWINIT(this)
571 _type = VX_OT_ARRAY;
572 _unVal.pArray = x;
573 vox_assert(_unVal.pTable);
574 _unVal.pRefCounted->_uiRef++;
579 VXObject::VXObject (VXForeignClosureObj * x)
581 VX_OBJECT_RAWINIT(this)
582 _type = VX_OT_CLOSURE;
583 _unVal.pClosure = x;
584 vox_assert (_unVal.pTable);
585 _unVal.pRefCounted->_uiRef++;
590 VXObject::VXObject (VXNativeClosureObj * x)
592 VX_OBJECT_RAWINIT(this)
593 _type = VX_OT_NATIVECLOSURE;
594 _unVal.pNativeClosure = x;
595 vox_assert (_unVal.pTable);
596 _unVal.pRefCounted->_uiRef++;
601 VXObject::VXObject (VXOuterObj * x)
603 VX_OBJECT_RAWINIT(this)
604 _type = VX_OT_OUTER;
605 _unVal.pOuter = x;
606 vox_assert (_unVal.pTable);
607 _unVal.pRefCounted->_uiRef++;
611 VXObject::VXObject (VXGeneratorObj * x)
613 VX_OBJECT_RAWINIT(this)
614 _type = VX_OT_GENERATOR;
615 _unVal.pGenerator = x;
616 vox_assert (_unVal.pTable);
617 _unVal.pRefCounted->_uiRef++;
620 VXObject::VXObject (VXStringObj * x)
622 VX_OBJECT_RAWINIT(this)
623 _type = VX_OT_STRING;
624 _unVal.pString = x;
625 vox_assert (_unVal.pTable);
626 _unVal.pRefCounted->_uiRef++;
629 VXObject::VXObject (VXUserDataObj * x)
631 VX_OBJECT_RAWINIT(this)
632 _type = VX_OT_USERDATA;
633 _unVal.pUserData = x;
634 vox_assert (_unVal.pTable);
635 _unVal.pRefCounted->_uiRef++;
639 VXObject::VXObject (VXWeakRefObj * x)
641 VX_OBJECT_RAWINIT(this)
642 _type = VX_OT_WEAKREF;
643 _unVal.pWeakRef = x;
644 vox_assert (_unVal.pTable);
645 _unVal.pRefCounted->_uiRef++;
649 VXObject::VXObject (VXState * x)
651 VX_OBJECT_RAWINIT(this)
652 _type = VX_OT_THREAD;
653 _unVal.pThread = x;
654 vox_assert (_unVal.pTable);
655 _unVal.pRefCounted->_uiRef++;
659 VXObject::VXObject (VXFuncProtoObj * x)
661 VX_OBJECT_RAWINIT(this)
662 _unVal.pFunctionProto = x;
663 _type = VX_OT_FUNCPROTO;
664 vox_assert (_unVal.pTable);
665 _unVal.pRefCounted->_uiRef++;
668 VXObject::VXObject(VXInteger x)
670 VX_OBJECT_RAWINIT(this)
671 _type = VX_OT_INTEGER;
672 _unVal.nInteger = x;
675 VXObject::VXObject (VXFloat x)
677 VX_OBJECT_RAWINIT(this)
678 _type = VX_OT_FLOAT;
679 _unVal.fFloat = x;
682 VXObject::VXObject (VXUserPointer x)
684 VX_OBJECT_RAWINIT(this)
685 _type = VX_OT_USERPOINTER;
686 _unVal.pUserPointer = x;
690 * operator=() methods
693 VXObject & VXObject::operator= (VXGeneratorObj * x)
695 VXOType tOldType;
696 VXRawObj::Value unOldVal;
697 tOldType = _type;
698 unOldVal = _unVal;
699 _type = VX_OT_GENERATOR;
700 VX_REFOBJECT_INIT (this)
701 _unVal.pGenerator = x;
702 _unVal.pRefCounted->_uiRef++;
703 __Release (tOldType, unOldVal);
704 return *this;
707 VXObject & VXObject::operator= (VXOuterObj * x)
709 VXOType tOldType;
710 VXRawObj::Value unOldVal;
711 tOldType = _type;
712 unOldVal = _unVal;
713 _type = VX_OT_OUTER;
714 VX_REFOBJECT_INIT (this)
715 _unVal.pOuter = x;
716 _unVal.pRefCounted->_uiRef++;
717 __Release (tOldType, unOldVal);
718 return *this;
722 VXObject & VXObject::operator= (VXNativeClosureObj * x)
724 VXOType tOldType;
725 VXRawObj::Value unOldVal;
726 tOldType = _type;
727 unOldVal = _unVal;
728 _type = VX_OT_NATIVECLOSURE;
729 VX_REFOBJECT_INIT (this)
730 _unVal.pNativeClosure = x;
731 _unVal.pRefCounted->_uiRef++;
732 __Release (tOldType, unOldVal);
733 return *this;
736 VXObject & VXObject::operator= (VXForeignClosureObj * x)
738 VXOType tOldType;
739 VXRawObj::Value unOldVal;
740 tOldType = _type;
741 unOldVal = _unVal;
742 _type = VX_OT_CLOSURE;
743 VX_REFOBJECT_INIT (this)
744 _unVal.pClosure = x;
745 _unVal.pRefCounted->_uiRef++;
746 __Release (tOldType, unOldVal);
747 return *this;
750 VXObject & VXObject::operator= (VXArrayObj * x)
752 VXOType tOldType;
753 VXRawObj::Value unOldVal;
754 tOldType = _type;
755 unOldVal = _unVal;
756 _type = VX_OT_ARRAY;
757 VX_REFOBJECT_INIT(this)
758 _unVal.pArray = x;
759 _unVal.pRefCounted->_uiRef++;
760 __Release (tOldType, unOldVal);
761 return *this;
764 VXObject & VXObject::operator= (VXInstanceObj * x)
766 VXOType tOldType;
767 VXRawObj::Value unOldVal;
768 tOldType = _type;
769 unOldVal = _unVal;
770 _type = VX_OT_INSTANCE;
771 VX_REFOBJECT_INIT (this)
772 _unVal.pInstance = x;
773 _unVal.pRefCounted->_uiRef++;
774 __Release (tOldType, unOldVal);
775 return *this;
778 VXObject & VXObject::operator= (VXTableObj * x)
780 VXOType tOldType;
781 VXRawObj::Value unOldVal;
782 tOldType = _type;
783 unOldVal = _unVal;
784 _type = VX_OT_TABLE;
785 VX_REFOBJECT_INIT(this)
786 _unVal.pTable = x;
787 _unVal.pRefCounted->_uiRef++;
788 __Release (tOldType, unOldVal);
789 return *this;
792 VXObject& VXObject::operator=(const VXObject& obj)
794 VXOType tOldType;
795 VXRawObj::Value unOldVal;
796 tOldType=_type;
797 unOldVal=_unVal;
798 _unVal = obj._unVal;
799 _type = obj._type;
800 VX_ADDREF(_type,_unVal);
801 __Release(tOldType,unOldVal);
802 return *this;
805 VXObject& VXObject::operator=(const VXRawObj& obj)
807 VXOType tOldType;
808 VXRawObj::Value unOldVal;
809 tOldType=_type;
810 unOldVal=_unVal;
811 _unVal = obj._unVal;
812 _type = obj._type;
813 VX_ADDREF(_type,_unVal);
814 __Release(tOldType,unOldVal);
815 return *this;
818 VXObject& VXObject::operator=(bool b)
820 __Release(_type,_unVal);
821 VX_OBJECT_RAWINIT(this)
822 _type = VX_OT_BOOL;
823 _unVal.nInteger = b?1:0;
824 return *this;
827 VXObject & VXObject::operator= (VXStringObj * x)
829 VXOType tOldType;
830 VXRawObj::Value unOldVal;
831 tOldType = _type;
832 unOldVal = _unVal;
833 _type = VX_OT_STRING;
834 VX_REFOBJECT_INIT (this)
835 _unVal.pString = x;
836 _unVal.pRefCounted->_uiRef++;
837 __Release (tOldType, unOldVal);
838 return *this;
841 VXObject & VXObject::operator= (VXUserDataObj * x)
843 VXOType tOldType;
844 VXRawObj::Value unOldVal;
845 tOldType = _type;
846 unOldVal = _unVal;
847 _type = VX_OT_USERDATA;
848 VX_REFOBJECT_INIT (this)
849 _unVal.pUserData = x;
850 _unVal.pRefCounted->_uiRef++;
851 __Release (tOldType, unOldVal);
852 return *this;
855 VXObject & VXObject::operator= (VXWeakRefObj * x)
857 VXOType tOldType;
858 VXRawObj::Value unOldVal;
859 tOldType = _type;
860 unOldVal = _unVal;
861 _type = VX_OT_WEAKREF;
862 VX_REFOBJECT_INIT (this)
863 _unVal.pWeakRef = x;
864 _unVal.pRefCounted->_uiRef++;
865 __Release (tOldType, unOldVal);
866 return *this;
869 VXObject & VXObject::operator= (VXState * x)
871 VXOType tOldType;
872 VXRawObj::Value unOldVal;
873 tOldType = _type;
874 unOldVal = _unVal;
875 _type = VX_OT_THREAD;
876 VX_REFOBJECT_INIT (this)
877 _unVal.pThread = x;
878 _unVal.pRefCounted->_uiRef++;
879 __Release (tOldType, unOldVal);
880 return *this;
883 VXObject & VXObject::operator= (VXFuncProtoObj * x)
885 VXOType tOldType;
886 VXRawObj::Value unOldVal;
887 tOldType = _type;
888 unOldVal = _unVal;
889 _type = VX_OT_FUNCPROTO;
890 VX_REFOBJECT_INIT (this)
891 _unVal.pFunctionProto = x;
892 _unVal.pRefCounted->_uiRef++;
893 __Release (tOldType, unOldVal);
894 return *this;
898 VXObject & VXObject::operator= (VXFloat x)
900 __Release (_type, _unVal);
901 _type = VX_OT_FLOAT;
902 VX_OBJECT_RAWINIT(this)
903 _unVal.fFloat = x;
904 return *this;
907 VXObject & VXObject::operator= (VXInteger x)
909 __Release (_type, _unVal);
910 _type = VX_OT_INTEGER;
911 VX_OBJECT_RAWINIT(this)
912 _unVal.nInteger = x;
913 return *this;
916 VXObject & VXObject::operator= (VXUserPointer x)
918 __Release (_type, _unVal);
919 _type = VX_OT_USERPOINTER;
920 VX_OBJECT_RAWINIT(this)
921 _unVal.pUserPointer = x;
922 return *this;