All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			added a in-class error information buffer to Sed
		
			
				
	
	
		
			3146 lines
		
	
	
		
			71 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			3146 lines
		
	
	
		
			71 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * $Id$
 | |
|  *
 | |
|     Copyright (c) 2006-2020 Chung, Hyung-Hwan. All rights reserved.
 | |
| 
 | |
|     Redistribution and use in source and binary forms, with or without
 | |
|     modification, are permitted provided that the following conditions
 | |
|     are met:
 | |
|     1. Redistributions of source code must retain the above copyright
 | |
|        notice, this list of conditions and the following disclaimer.
 | |
|     2. Redistributions in binary form must reproduce the above copyright
 | |
|        notice, this list of conditions and the following disclaimer in the
 | |
|        documentation and/or other materials provided with the distribution.
 | |
| 
 | |
|     THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
 | |
|     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | |
|     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 | |
|     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 | |
|     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 | |
|     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
|     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
|     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
|     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 | |
|     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
|  */
 | |
| 
 | |
| #include <Hawk.hpp>
 | |
| #include "hawk-prv.h"
 | |
| 
 | |
| /////////////////////////////////
 | |
| HAWK_BEGIN_NAMESPACE(HAWK)
 | |
| /////////////////////////////////
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////
 | |
| // Mmged
 | |
| //////////////////////////////////////////////////////////////////
 | |
| 
 | |
| Mmged::Mmged (Mmgr* mmgr)
 | |
| {
 | |
| 	if (!mmgr) mmgr = Mmgr::getDFL();
 | |
| 	this->_mmgr = mmgr;
 | |
| }
 | |
| 
 | |
| void Mmged::setMmgr (Mmgr* mmgr)
 | |
| {
 | |
| 	if (!mmgr) mmgr = Mmgr::getDFL();
 | |
| 	this->_mmgr = mmgr;
 | |
| }
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////
 | |
| // Mmgr
 | |
| //////////////////////////////////////////////////////////////////
 | |
| 
 | |
| 
 | |
| void* Mmgr::alloc_mem (mmgr_t* mmgr, hawk_oow_t n) HAWK_CXX_NOEXCEPT
 | |
| {
 | |
| 	return ((Mmgr*)mmgr->ctx)->allocMem (n);
 | |
| }
 | |
| 
 | |
| void* Mmgr::realloc_mem (mmgr_t* mmgr, void* ptr, hawk_oow_t n) HAWK_CXX_NOEXCEPT
 | |
| {
 | |
| 	return ((Mmgr*)mmgr->ctx)->reallocMem (ptr, n);
 | |
| }
 | |
| 
 | |
| void Mmgr::free_mem (mmgr_t* mmgr, void* ptr) HAWK_CXX_NOEXCEPT
 | |
| {
 | |
| 	((Mmgr*)mmgr->ctx)->freeMem (ptr);
 | |
| }
 | |
| 
 | |
| void* Mmgr::callocate (hawk_oow_t n, bool raise_exception) /*HAWK_CXX_THREXCEPT1(MemoryError)*/
 | |
| {
 | |
| 	void* ptr = this->allocate(n, raise_exception);
 | |
| 	HAWK_MEMSET (ptr, 0, n);
 | |
| 	return ptr;
 | |
| }
 | |
| 
 | |
| #if 0
 | |
| #if defined(__GNUC__)
 | |
| static MmgrStd __attribute__((init_priority(101))) std_dfl_mmgr; //<- this solved the problem
 | |
| #else
 | |
| static MmgrStd std_dfl_mmgr; //<-- has an issue for undefined initialization order
 | |
| #endif
 | |
| Mmgr* Mmgr::dfl_mmgr = &std_dfl_mmgr;
 | |
| //Mmgr* Mmgr::dfl_mmgr = MmgrStd::getInstance();  //<--- has an issue as well
 | |
| Mmgr* Mmgr::getDFL () HAWK_CXX_NOEXCEPT
 | |
| {
 | |
| 	return Mmgr::dfl_mmgr;
 | |
| }
 | |
| #else
 | |
| // C++ initialization order across translation units are not defined.
 | |
| // so it's tricky to work around this... the init_priority attribute
 | |
| // can solve this problem. but it's compiler dependent.
 | |
| // Mmgr::getDFL() resets dfl_mmgr to &std_dfl_mmgr if it's NULL.
 | |
| Mmgr* Mmgr::dfl_mmgr = HAWK_NULL;
 | |
| 
 | |
| Mmgr* Mmgr::getDFL () HAWK_CXX_NOEXCEPT
 | |
| {
 | |
| 	static MmgrStd std_dfl_mmgr;
 | |
| 	Mmgr* mmgr = Mmgr::dfl_mmgr;
 | |
| 	return mmgr? mmgr: &std_dfl_mmgr;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| void Mmgr::setDFL (Mmgr* mmgr) HAWK_CXX_NOEXCEPT
 | |
| {
 | |
| 	Mmgr::dfl_mmgr = mmgr;
 | |
| }
 | |
| 
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////
 | |
| // Hawk::Source
 | |
| //////////////////////////////////////////////////////////////////
 | |
| 
 | |
| struct xtn_t
 | |
| {
 | |
| 	Hawk* hawk;
 | |
| 	hawk_ecb_t ecb;
 | |
| };
 | |
| 
 | |
| struct rxtn_t
 | |
| {
 | |
| 	Hawk::Run* run;
 | |
| };
 | |
| 
 | |
| Hawk::NoSource Hawk::Source::NONE;
 | |
| 
 | |
| #if defined(HAWK_HAVE_INLINE)
 | |
| static HAWK_INLINE xtn_t* GET_XTN(hawk_t* hawk) { return (xtn_t*)((hawk_uint8_t*)hawk_getxtn(hawk) - HAWK_SIZEOF(xtn_t)); }
 | |
| static HAWK_INLINE rxtn_t* GET_RXTN(hawk_rtx_t* rtx) { return (rxtn_t*)((hawk_uint8_t*)hawk_rtx_getxtn(rtx) - HAWK_SIZEOF(rxtn_t)); }
 | |
| #else
 | |
| #define GET_XTN(hawk) ((xtn_t*)((hawk_uint8_t*)hawk_getxtn(hawk) - HAWK_SIZEOF(xtn_t)))
 | |
| #define GET_RXTN(rtx) ((rxtn_t*)((hawk_uint8_t*)hawk_rtx_getxtn(rtx) - HAWK_SIZEOF(rxtn_t)))
 | |
| #endif
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////
 | |
| // Hawk::Pipe
 | |
| //////////////////////////////////////////////////////////////////
 | |
| 
 | |
| Hawk::Pipe::Pipe (Run* run, hawk_rio_arg_t* riod): RIOBase (run, riod)
 | |
| {
 | |
| }
 | |
| 
 | |
| Hawk::Pipe::Mode Hawk::Pipe::getMode () const
 | |
| {
 | |
| 	return (Mode)riod->mode;
 | |
| }
 | |
| 
 | |
| Hawk::Pipe::CloseMode Hawk::Pipe::getCloseMode () const
 | |
| {
 | |
| 	return (CloseMode)riod->rwcmode;
 | |
| }
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////
 | |
| // Hawk::File
 | |
| //////////////////////////////////////////////////////////////////
 | |
| 
 | |
| Hawk::File::File (Run* run, hawk_rio_arg_t* riod): RIOBase (run, riod)
 | |
| {
 | |
| }
 | |
| 
 | |
| Hawk::File::Mode Hawk::File::getMode () const
 | |
| {
 | |
| 	return (Mode)riod->mode;
 | |
| }
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////
 | |
| // Hawk::Console
 | |
| //////////////////////////////////////////////////////////////////
 | |
| 
 | |
| Hawk::Console::Console (Run* run, hawk_rio_arg_t* riod):
 | |
| 	RIOBase (run, riod), filename (HAWK_NULL)
 | |
| {
 | |
| }
 | |
| 
 | |
| Hawk::Console::~Console ()
 | |
| {
 | |
| 	if (filename != HAWK_NULL)
 | |
| 	{
 | |
| 		hawk_freemem((hawk_t*)this, filename);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| int Hawk::Console::setFileName (const hawk_ooch_t* name)
 | |
| {
 | |
| 	if (this->getMode() == READ)
 | |
| 	{
 | |
| 		return hawk_rtx_setfilenamewithoochars(this->run->rtx, name, hawk_count_oocstr(name));
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		return hawk_rtx_setofilenamewithoochars(this->run->rtx, name, hawk_count_oocstr(name));
 | |
| 	}
 | |
| }
 | |
| 
 | |
| int Hawk::Console::setFNR (hawk_int_t fnr)
 | |
| {
 | |
| 	hawk_val_t* tmp;
 | |
| 	int n;
 | |
| 
 | |
| 	tmp = hawk_rtx_makeintval(this->run->rtx, fnr);
 | |
| 	if (tmp == HAWK_NULL) return -1;
 | |
| 
 | |
| 	hawk_rtx_refupval(this->run->rtx, tmp);
 | |
| 	n = hawk_rtx_setgbl(this->run->rtx, HAWK_GBL_FNR, tmp);
 | |
| 	hawk_rtx_refdownval(this->run->rtx, tmp);
 | |
| 
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| Hawk::Console::Mode Hawk::Console::getMode () const
 | |
| {
 | |
| 	return (Mode)riod->mode;
 | |
| }
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////
 | |
| // Hawk::Value
 | |
| //////////////////////////////////////////////////////////////////
 | |
| 
 | |
| Hawk::Value::IndexIterator Hawk::Value::IndexIterator::END;
 | |
| 
 | |
| const hawk_ooch_t* Hawk::Value::getEmptyStr()
 | |
| {
 | |
| 	static const hawk_ooch_t* EMPTY_STRING = HAWK_T("");
 | |
| 	return EMPTY_STRING;
 | |
| }
 | |
| const hawk_bch_t* Hawk::Value::getEmptyMbs()
 | |
| {
 | |
| 	static const hawk_bch_t* EMPTY_STRING = HAWK_BT("");
 | |
| 	return EMPTY_STRING;
 | |
| }
 | |
| 
 | |
| const void* Hawk::Value::getEmptyBob()
 | |
| {
 | |
| 	static const hawk_uint8_t EMPTY_BOB = 0;
 | |
| 	return &EMPTY_BOB;
 | |
| }
 | |
| 
 | |
| Hawk::Value::IntIndex::IntIndex (hawk_int_t x)
 | |
| {
 | |
| 	ptr = buf;
 | |
| 	len = 0;
 | |
| 
 | |
| #define NTOC(n) (HAWK_T("0123456789")[n])
 | |
| 
 | |
| 	int base = 10;
 | |
| 	hawk_int_t last = x % base;
 | |
| 	hawk_int_t y = 0;
 | |
| 	int dig = 0;
 | |
| 
 | |
| 	if (x < 0) buf[len++] = HAWK_T('-');
 | |
| 
 | |
| 	x = x / base;
 | |
| 	if (x < 0) x = -x;
 | |
| 
 | |
| 	while (x > 0)
 | |
| 	{
 | |
| 		y = y * base + (x % base);
 | |
| 		x = x / base;
 | |
| 		dig++;
 | |
| 	}
 | |
| 
 | |
|         while (y > 0)
 | |
|         {
 | |
| 		buf[len++] = NTOC (y % base);
 | |
| 		y = y / base;
 | |
| 		dig--;
 | |
| 	}
 | |
| 
 | |
| 	while (dig > 0)
 | |
| 	{
 | |
| 		dig--;
 | |
| 		buf[len++] = HAWK_T('0');
 | |
| 	}
 | |
| 	if (last < 0) last = -last;
 | |
| 	buf[len++] = NTOC(last);
 | |
| 
 | |
| 	buf[len] = HAWK_T('\0');
 | |
| 
 | |
| #undef NTOC
 | |
| }
 | |
| 
 | |
| #if defined(HAWK_VALUE_USE_IN_CLASS_PLACEMENT_NEW)
 | |
| void* Hawk::Value::operator new (hawk_oow_t n, Run* run) throw ()
 | |
| {
 | |
| 	void* ptr = hawk_rtx_allocmem(run->rtx, HAWK_SIZEOF(run) + n);
 | |
| 	if (HAWK_UNLIKELY(!ptr)) return HAWK_NULL;
 | |
| 
 | |
| 	*(Run**)ptr = run;
 | |
| 	return (char*)ptr + HAWK_SIZEOF(run);
 | |
| }
 | |
| 
 | |
| void* Hawk::Value::operator new[] (hawk_oow_t n, Run* run) throw ()
 | |
| {
 | |
| 	void* ptr = hawk_rtx_allocmem(run->rtx, HAWK_SIZEOF(run) + n);
 | |
| 	if (HAWK_UNLIKELY(!ptr)) return HAWK_NULL;
 | |
| 
 | |
| 	*(Run**)ptr = run;
 | |
| 	return (char*)ptr + HAWK_SIZEOF(run);
 | |
| }
 | |
| 
 | |
| #if !defined(__BORLANDC__) && !defined(__WATCOMC__)
 | |
| void Hawk::Value::operator delete (void* ptr, Run* run)
 | |
| {
 | |
| 	// this placement delete is to be called when the constructor
 | |
| 	// throws an exception and it's caught by the caller.
 | |
| 	hawk_rtx_freemem(run->rtx, (char*)ptr - HAWK_SIZEOF(run));
 | |
| }
 | |
| 
 | |
| void Hawk::Value::operator delete[] (void* ptr, Run* run)
 | |
| {
 | |
| 	// this placement delete is to be called when the constructor
 | |
| 	// throws an exception and it's caught by the caller.
 | |
| 	hawk_rtx_freemem(run->rtx, (char*)ptr - HAWK_SIZEOF(run));
 | |
| }
 | |
| #endif
 | |
| 
 | |
| void Hawk::Value::operator delete (void* ptr)
 | |
| {
 | |
| 	// this delete is to be called for normal destruction.
 | |
| 	void* p = (char*)ptr - HAWK_SIZEOF(Run*);
 | |
| 	hawk_rtx_freemem((*(Run**)p)->rtx, p);
 | |
| }
 | |
| 
 | |
| void Hawk::Value::operator delete[] (void* ptr)
 | |
| {
 | |
| 	// this delete is to be called for normal destruction.
 | |
| 	void* p = (char*)ptr - HAWK_SIZEOF(Run*);
 | |
| 	hawk_rtx_freemem((*(Run**)p)->rtx, p);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| Hawk::Value::Value (): run(HAWK_NULL), val(hawk_get_nil_val())
 | |
| {
 | |
| 	this->cached.str.ptr = HAWK_NULL;
 | |
| 	this->cached.str.len = 0;
 | |
| 	this->cached.mbs.ptr = HAWK_NULL;
 | |
| 	this->cached.mbs.len = 0;
 | |
| }
 | |
| 
 | |
| Hawk::Value::Value (Run& run): run(&run), val(hawk_get_nil_val())
 | |
| {
 | |
| 	this->cached.str.ptr = HAWK_NULL;
 | |
| 	this->cached.str.len = 0;
 | |
| 	this->cached.mbs.ptr = HAWK_NULL;
 | |
| 	this->cached.mbs.len = 0;
 | |
| }
 | |
| 
 | |
| Hawk::Value::Value (Run* run): run(run), val(hawk_get_nil_val())
 | |
| {
 | |
| 	this->cached.str.ptr = HAWK_NULL;
 | |
| 	this->cached.str.len = 0;
 | |
| 	this->cached.mbs.ptr = HAWK_NULL;
 | |
| 	this->cached.mbs.len = 0;
 | |
| }
 | |
| 
 | |
| Hawk::Value::Value (const Value& v): run(v.run), val(v.val)
 | |
| {
 | |
| 	if (this->run) hawk_rtx_refupval(this->run->rtx, this->val);
 | |
| 
 | |
| 	this->cached.str.ptr = HAWK_NULL;
 | |
| 	this->cached.str.len = 0;
 | |
| 	this->cached.mbs.ptr = HAWK_NULL;
 | |
| 	this->cached.mbs.len = 0;
 | |
| }
 | |
| 
 | |
| Hawk::Value::~Value ()
 | |
| {
 | |
| 	if (this->run)
 | |
| 	{
 | |
| 		hawk_rtx_refdownval(this->run->rtx, val);
 | |
| 		if (this->cached.str.ptr) hawk_rtx_freemem(this->run->rtx, cached.str.ptr);
 | |
| 		if (this->cached.mbs.ptr) hawk_rtx_freemem(this->run->rtx, cached.mbs.ptr);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| Hawk::Value& Hawk::Value::operator= (const Value& v)
 | |
| {
 | |
| 	if (this == &v) return *this;
 | |
| 
 | |
| 	if (this->run)
 | |
| 	{
 | |
| 		hawk_rtx_refdownval(this->run->rtx, this->val);
 | |
| 		if (this->cached.str.ptr)
 | |
| 		{
 | |
| 			hawk_rtx_freemem(this->run->rtx, this->cached.str.ptr);
 | |
| 			this->cached.str.ptr = HAWK_NULL;
 | |
| 			this->cached.str.len = 0;
 | |
| 		}
 | |
| 		if (this->cached.mbs.ptr)
 | |
| 		{
 | |
| 			hawk_rtx_freemem(this->run->rtx, this->cached.mbs.ptr);
 | |
| 			this->cached.mbs.ptr = HAWK_NULL;
 | |
| 			this->cached.mbs.len = 0;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	this->run = v.run;
 | |
| 	this->val = v.val;
 | |
| 
 | |
| 	if (this->run) hawk_rtx_refupval(this->run->rtx, this->val);
 | |
| 
 | |
| 	return *this;
 | |
| }
 | |
| 
 | |
| void Hawk::Value::clear ()
 | |
| {
 | |
| 	if (this->run)
 | |
| 	{
 | |
| 		hawk_rtx_refdownval(this->run->rtx, this->val);
 | |
| 
 | |
| 		if (this->cached.str.ptr)
 | |
| 		{
 | |
| 			hawk_rtx_freemem(this->run->rtx, this->cached.str.ptr);
 | |
| 			this->cached.str.ptr = HAWK_NULL;
 | |
| 			this->cached.str.len = 0;
 | |
| 		}
 | |
| 		if (this->cached.mbs.ptr)
 | |
| 		{
 | |
| 			hawk_rtx_freemem(this->run->rtx, this->cached.mbs.ptr);
 | |
| 			this->cached.mbs.ptr = HAWK_NULL;
 | |
| 			this->cached.mbs.len = 0;
 | |
| 		}
 | |
| 
 | |
| 		this->run = HAWK_NULL;
 | |
| 		this->val = hawk_get_nil_val();
 | |
| 	}
 | |
| }
 | |
| 
 | |
| Hawk::Value::operator hawk_int_t () const
 | |
| {
 | |
| 	hawk_int_t v;
 | |
| 	if (this->getInt(&v) <= -1) v = 0;
 | |
| 	return v;
 | |
| }
 | |
| 
 | |
| Hawk::Value::operator hawk_flt_t () const
 | |
| {
 | |
| 	hawk_flt_t v;
 | |
| 	if (this->getFlt(&v) <= -1) v = 0.0;
 | |
| 	return v;
 | |
| }
 | |
| 
 | |
| Hawk::Value::operator const hawk_ooch_t* () const
 | |
| {
 | |
| 	const hawk_ooch_t* ptr;
 | |
| 	hawk_oow_t len;
 | |
| 	if (Hawk::Value::getStr(&ptr, &len) <= -1) ptr = getEmptyStr();
 | |
| 	return ptr;
 | |
| }
 | |
| 
 | |
| #if defined(HAWK_OOCH_IS_UCH)
 | |
| Hawk::Value::operator const hawk_bch_t* () const
 | |
| {
 | |
| 	const hawk_bch_t* ptr;
 | |
| 	hawk_oow_t len;
 | |
| 	if (Hawk::Value::getMbs(&ptr, &len) <= -1) ptr = getEmptyMbs();
 | |
| 	return ptr;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| int Hawk::Value::getInt (hawk_int_t* v) const
 | |
| {
 | |
| 	hawk_int_t lv = 0;
 | |
| 
 | |
| 	HAWK_ASSERT(this->val != HAWK_NULL);
 | |
| 
 | |
| 	if (this->run)
 | |
| 	{
 | |
| 		int n = hawk_rtx_valtoint(this->run->rtx, this->val, &lv);
 | |
| 		if (n <= -1)
 | |
| 		{
 | |
| 			run->hawk->retrieveError(this->run);
 | |
| 			return -1;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	*v = lv;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int Hawk::Value::getFlt (hawk_flt_t* v) const
 | |
| {
 | |
| 	hawk_flt_t rv = 0;
 | |
| 
 | |
| 	HAWK_ASSERT(this->val != HAWK_NULL);
 | |
| 
 | |
| 	if (this->run)
 | |
| 	{
 | |
| 		int n = hawk_rtx_valtoflt(this->run->rtx, this->val, &rv);
 | |
| 		if (n <= -1)
 | |
| 		{
 | |
| 			run->hawk->retrieveError(this->run);
 | |
| 			return -1;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	*v = rv;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int Hawk::Value::getNum (hawk_int_t* lv, hawk_flt_t* fv) const
 | |
| {
 | |
| 	HAWK_ASSERT(this->val != HAWK_NULL);
 | |
| 
 | |
| 	if (this->run)
 | |
| 	{
 | |
| 		int n = hawk_rtx_valtonum(this->run->rtx, this->val, lv, fv);
 | |
| 		if (n <= -1)
 | |
| 		{
 | |
| 			run->hawk->retrieveError(this->run);
 | |
| 			return -1;
 | |
| 		}
 | |
| 		return n;
 | |
| 	}
 | |
| 
 | |
| 	*lv = 0;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int Hawk::Value::getStr (const hawk_ooch_t** str, hawk_oow_t* len) const
 | |
| {
 | |
| 	const hawk_ooch_t* p = getEmptyStr();
 | |
| 	hawk_oow_t l = 0;
 | |
| 
 | |
| 	HAWK_ASSERT(this->val != HAWK_NULL);
 | |
| 
 | |
| 	if (this->run)
 | |
| 	{
 | |
| 		if (HAWK_RTX_GETVALTYPE(this->run->rtx, this->val) == HAWK_VAL_STR)
 | |
| 		{
 | |
| 			p = ((hawk_val_str_t*)this->val)->val.ptr;
 | |
| 			l = ((hawk_val_str_t*)this->val)->val.len;
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			if (!cached.str.ptr)
 | |
| 			{
 | |
| 				hawk_rtx_valtostr_out_t out;
 | |
| 				out.type = HAWK_RTX_VALTOSTR_CPLDUP;
 | |
| 				if (hawk_rtx_valtostr(this->run->rtx, this->val, &out) <= -1)
 | |
| 				{
 | |
| 					run->hawk->retrieveError(this->run);
 | |
| 					return -1;
 | |
| 				}
 | |
| 
 | |
| 				p = out.u.cpldup.ptr;
 | |
| 				l = out.u.cpldup.len;
 | |
| 
 | |
| 				cached.str.ptr = out.u.cpldup.ptr;
 | |
| 				cached.str.len = out.u.cpldup.len;
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				p = cached.str.ptr;
 | |
| 				l = cached.str.len;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	*str = p;
 | |
| 	*len = l;
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int Hawk::Value::getMbs (const hawk_bch_t** str, hawk_oow_t* len) const
 | |
| {
 | |
| 	const hawk_bch_t* p = getEmptyMbs();
 | |
| 	hawk_oow_t l = 0;
 | |
| 
 | |
| 	HAWK_ASSERT(this->val != HAWK_NULL);
 | |
| 
 | |
| 	if (this->run)
 | |
| 	{
 | |
| 		if (HAWK_RTX_GETVALTYPE(this->run->rtx, this->val) == HAWK_VAL_MBS)
 | |
| 		{
 | |
| 			p = ((hawk_val_mbs_t*)this->val)->val.ptr;
 | |
| 			l = ((hawk_val_mbs_t*)this->val)->val.len;
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			if (!cached.mbs.ptr)
 | |
| 			{
 | |
| 				p = hawk_rtx_valtobcstrdup(this->run->rtx, this->val, &l);
 | |
| 				if (!p)
 | |
| 				{
 | |
| 					run->hawk->retrieveError(this->run);
 | |
| 					return -1;
 | |
| 				}
 | |
| 
 | |
| 				cached.mbs.ptr = (hawk_bch_t*)p;
 | |
| 				cached.mbs.len = l;
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				p = cached.mbs.ptr;
 | |
| 				l = cached.mbs.len;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	*str = p;
 | |
| 	*len = l;
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int Hawk::Value::getBob (const void** ptr, hawk_oow_t* len) const
 | |
| {
 | |
| 	const void* p = getEmptyBob();
 | |
| 	hawk_oow_t l = 0;
 | |
| 
 | |
| 	HAWK_ASSERT(this->val != HAWK_NULL);
 | |
| 
 | |
| 	if (this->run)
 | |
| 	{
 | |
| 		if (HAWK_RTX_GETVALTYPE(this->run->rtx, this->val) == HAWK_VAL_BOB)
 | |
| 		{
 | |
| 			p = ((hawk_val_bob_t*)this->val)->val.ptr;
 | |
| 			l = ((hawk_val_bob_t*)this->val)->val.len;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	*ptr = p;
 | |
| 	*len = l;
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////
 | |
| 
 | |
| int Hawk::Value::setVal (hawk_val_t* v)
 | |
| {
 | |
| 	if (this->run == HAWK_NULL)
 | |
| 	{
 | |
| 		/* no runtime context assoicated. unfortunately, i can't
 | |
| 		 * set an error number for the same reason */
 | |
| 		return -1;
 | |
| 	}
 | |
| 	return this->setVal(this->run, v);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setVal (Run* r, hawk_val_t* v)
 | |
| {
 | |
| 	if (this->run != HAWK_NULL)
 | |
| 	{
 | |
| 		hawk_rtx_refdownval(this->run->rtx, val);
 | |
| 		if (cached.str.ptr)
 | |
| 		{
 | |
| 			hawk_rtx_freemem(this->run->rtx, cached.str.ptr);
 | |
| 			cached.str.ptr = HAWK_NULL;
 | |
| 			cached.str.len = 0;
 | |
| 		}
 | |
| 		if (cached.mbs.ptr)
 | |
| 		{
 | |
| 			hawk_rtx_freemem(this->run->rtx, cached.mbs.ptr);
 | |
| 			cached.mbs.ptr = HAWK_NULL;
 | |
| 			cached.mbs.len = 0;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	HAWK_ASSERT(cached.str.ptr == HAWK_NULL);
 | |
| 	HAWK_ASSERT(cached.mbs.ptr == HAWK_NULL);
 | |
| 	hawk_rtx_refupval(r->rtx, v);
 | |
| 
 | |
| 	this->run = r;
 | |
| 	this->val = v;
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setInt (hawk_int_t v)
 | |
| {
 | |
| 	if (this->run == HAWK_NULL)
 | |
| 	{
 | |
| 		/* no runtime context assoicated. unfortunately, i can't
 | |
| 		 * set an error number for the same reason */
 | |
| 		return -1;
 | |
| 	}
 | |
| 	return this->setInt(this->run, v);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setInt (Run* r, hawk_int_t v)
 | |
| {
 | |
| 	hawk_val_t* tmp;
 | |
| 	tmp = hawk_rtx_makeintval(r->rtx, v);
 | |
| 	if (tmp == HAWK_NULL)
 | |
| 	{
 | |
| 		r->hawk->retrieveError(r);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	int n = this->setVal(r, tmp);
 | |
| 	HAWK_ASSERT(n == 0);
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setFlt (hawk_flt_t v)
 | |
| {
 | |
| 	if (this->run == HAWK_NULL)
 | |
| 	{
 | |
| 		/* no runtime context assoicated. unfortunately, i can't
 | |
| 		 * set an error number for the same reason */
 | |
| 		return -1;
 | |
| 	}
 | |
| 	return this->setFlt(this->run, v);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setFlt (Run* r, hawk_flt_t v)
 | |
| {
 | |
| 	hawk_val_t* tmp;
 | |
| 	tmp = hawk_rtx_makefltval(r->rtx, v);
 | |
| 	if (tmp == HAWK_NULL)
 | |
| 	{
 | |
| 		r->hawk->retrieveError(r);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	int n = this->setVal(r, tmp);
 | |
| 	HAWK_ASSERT(n == 0);
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////
 | |
| 
 | |
| int Hawk::Value::setStr (const hawk_uch_t* str, hawk_oow_t len, bool numeric)
 | |
| {
 | |
| 	if (this->run == HAWK_NULL)
 | |
| 	{
 | |
| 		/* no runtime context assoicated. unfortunately, i can't
 | |
| 		 * set an error number for the same reason */
 | |
| 		return -1;
 | |
| 	}
 | |
| 	return this->setStr(this->run, str, len, numeric);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setStr (Run* r, const hawk_uch_t* str, hawk_oow_t len, bool numeric)
 | |
| {
 | |
| 	hawk_val_t* tmp;
 | |
| 
 | |
| 	tmp = numeric? hawk_rtx_makenumorstrvalwithuchars(r->rtx, str, len):
 | |
| 	               hawk_rtx_makestrvalwithuchars(r->rtx, str, len);
 | |
| 	if (tmp == HAWK_NULL)
 | |
| 	{
 | |
| 		r->hawk->retrieveError(r);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	int n = this->setVal(r, tmp);
 | |
| 	HAWK_ASSERT(n == 0);
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setStr (const hawk_uch_t* str, bool numeric)
 | |
| {
 | |
| 	if (HAWK_UNLIKELY(!this->run)) return -1;
 | |
| 	return this->setStr(this->run, str, numeric);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setStr (Run* r, const hawk_uch_t* str, bool numeric)
 | |
| {
 | |
| 	hawk_val_t* tmp;
 | |
| 
 | |
| 	tmp = numeric? hawk_rtx_makenumorstrvalwithuchars(r->rtx, str, hawk_count_ucstr(str)):
 | |
| 	               hawk_rtx_makestrvalwithucstr(r->rtx, str);
 | |
| 	if (tmp == HAWK_NULL)
 | |
| 	{
 | |
| 		r->hawk->retrieveError(r);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	int n = this->setVal(r, tmp);
 | |
| 	HAWK_ASSERT(n == 0);
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////
 | |
| 
 | |
| int Hawk::Value::setStr (const hawk_bch_t* str, hawk_oow_t len, bool numeric)
 | |
| {
 | |
| 	if (this->run == HAWK_NULL)
 | |
| 	{
 | |
| 		/* no runtime context assoicated. unfortunately, i can't
 | |
| 		 * set an error number for the same reason */
 | |
| 		return -1;
 | |
| 	}
 | |
| 	return this->setStr(this->run, str, len, numeric);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setStr (Run* r, const hawk_bch_t* str, hawk_oow_t len, bool numeric)
 | |
| {
 | |
| 	hawk_val_t* tmp;
 | |
| 
 | |
| 	tmp = numeric? hawk_rtx_makenumorstrvalwithbchars(r->rtx, str, len):
 | |
| 	               hawk_rtx_makestrvalwithbchars(r->rtx, str, len);
 | |
| 	if (tmp == HAWK_NULL)
 | |
| 	{
 | |
| 		r->hawk->retrieveError(r);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	int n = this->setVal(r, tmp);
 | |
| 	HAWK_ASSERT(n == 0);
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setStr (const hawk_bch_t* str, bool numeric)
 | |
| {
 | |
| 	if (HAWK_UNLIKELY(!this->run)) return -1;
 | |
| 	return this->setStr(this->run, str, numeric);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setStr (Run* r, const hawk_bch_t* str, bool numeric)
 | |
| {
 | |
| 	hawk_val_t* tmp;
 | |
| 
 | |
| 	tmp = numeric? hawk_rtx_makenumorstrvalwithbchars(r->rtx, str, hawk_count_bcstr(str)):
 | |
| 	               hawk_rtx_makestrvalwithbcstr(r->rtx, str);
 | |
| 	if (tmp == HAWK_NULL)
 | |
| 	{
 | |
| 		r->hawk->retrieveError(r);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	int n = this->setVal(r, tmp);
 | |
| 	HAWK_ASSERT(n == 0);
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////
 | |
| int Hawk::Value::setMbs (const hawk_bch_t* str, hawk_oow_t len)
 | |
| {
 | |
| 	if (this->run == HAWK_NULL)
 | |
| 	{
 | |
| 		/* no runtime context assoicated. unfortunately, i can't
 | |
| 		 * set an error number for the same reason */
 | |
| 		return -1;
 | |
| 	}
 | |
| 	return this->setMbs(this->run, str, len);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setMbs (Run* r, const hawk_bch_t* str, hawk_oow_t len)
 | |
| {
 | |
| 	hawk_val_t* tmp;
 | |
| 
 | |
| 	hawk_bcs_t oocs;
 | |
| 	oocs.ptr = (hawk_bch_t*)str;
 | |
| 	oocs.len = len;
 | |
| 
 | |
| 	tmp = hawk_rtx_makembsvalwithbcs(r->rtx, &oocs);
 | |
| 	if (!tmp)
 | |
| 	{
 | |
| 		r->hawk->retrieveError(r);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	int n = this->setVal(r, tmp);
 | |
| 	HAWK_ASSERT(n == 0);
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setMbs (const hawk_bch_t* str)
 | |
| {
 | |
| 	if (HAWK_UNLIKELY(!this->run)) return -1;
 | |
| 	return this->setMbs(this->run, str);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setMbs (Run* r, const hawk_bch_t* str)
 | |
| {
 | |
| 	hawk_val_t* tmp;
 | |
| 	tmp = hawk_rtx_makembsvalwithbchars(r->rtx, str, hawk_count_bcstr(str));
 | |
| 	if (HAWK_UNLIKELY(!tmp))
 | |
| 	{
 | |
| 		r->hawk->retrieveError(r);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	int n = this->setVal(r, tmp);
 | |
| 	HAWK_ASSERT(n == 0);
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////////
 | |
| 
 | |
| int Hawk::Value::setBob (const void* ptr, hawk_oow_t len)
 | |
| {
 | |
| 	if (this->run == HAWK_NULL)
 | |
| 	{
 | |
| 		/* no runtime context assoicated. unfortunately, i can't
 | |
| 		 * set an error number for the same reason */
 | |
| 		return -1;
 | |
| 	}
 | |
| 	return this->setBob(this->run, ptr, len);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setBob (Run* r, const void* ptr, hawk_oow_t len)
 | |
| {
 | |
| 	hawk_val_t* tmp;
 | |
| 
 | |
| 	tmp = hawk_rtx_makebobval(r->rtx, ptr, len);
 | |
| 	if (HAWK_UNLIKELY(!tmp))
 | |
| 	{
 | |
| 		r->hawk->retrieveError(r);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	int n = this->setVal(r, tmp);
 | |
| 	HAWK_ASSERT(n == 0);
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////////
 | |
| int Hawk::Value::scaleArrayed (hawk_ooi_t size)
 | |
| {
 | |
| 	if (HAWK_UNLIKELY(!this->run)) return -1;
 | |
| 	return this->scaleArrayed(this->run, size);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::scaleArrayed (Run* r, hawk_ooi_t size)
 | |
| {
 | |
| 	HAWK_ASSERT(r != HAWK_NULL);
 | |
| 
 | |
| 	if (HAWK_RTX_GETVALTYPE(r->rtx, this->val) != HAWK_VAL_ARR)
 | |
| 	{
 | |
| 		// the previous value is not a arr.
 | |
| 		// a new arr value needs to be created first.
 | |
| 		hawk_val_t* arr = hawk_rtx_makearrval(r->rtx, size);
 | |
| 		if (arr == HAWK_NULL)
 | |
| 		{
 | |
| 			r->hawk->retrieveError(r);
 | |
| 			return -1;
 | |
| 		}
 | |
| 
 | |
| 		hawk_rtx_refupval(r->rtx, arr);
 | |
| 
 | |
| 		// free the previous value
 | |
| 		if (this->run)
 | |
| 		{
 | |
| 			// if val is not nil, this->run can't be NULL
 | |
| 			hawk_rtx_refdownval(this->run->rtx, this->val);
 | |
| 		}
 | |
| 
 | |
| 		this->run = r;
 | |
| 		this->val = arr;
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		HAWK_ASSERT(run != HAWK_NULL);
 | |
| 
 | |
| 		// if the previous value is a arr, things are a bit simpler
 | |
| 		// however it needs to check if the runtime context matches
 | |
| 		// with the previous one.
 | |
| 		if (this->run != r)
 | |
| 		{
 | |
| 			// it can't span across multiple runtime contexts
 | |
| 			this->run->setError(HAWK_EINVAL);
 | |
| 			this->run->hawk->retrieveError(run);
 | |
| 			return -1;
 | |
| 		}
 | |
| 
 | |
| 		// update the capacity of an array
 | |
| 		if (hawk_rtx_scalearrval(r->rtx, this->val, size) <= -1)
 | |
| 		{
 | |
| 			r->hawk->retrieveError(r);
 | |
| 			return -1;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::Value::getArrayedLength () const
 | |
| {
 | |
| 	if (HAWK_RTX_GETVALTYPE(r->rtx, this->val) != HAWK_VAL_ARR) return -1;
 | |
| 	return (hawk_ooi_t)HAWK_ARR_TALLY(((hawk_val_arr_t*)this->val)->arr);
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::Value::getArrayedSize () const
 | |
| {
 | |
| 	if (HAWK_RTX_GETVALTYPE(r->rtx, this->val) != HAWK_VAL_ARR) return -1;
 | |
| 	return (hawk_ooi_t)HAWK_ARR_SIZE(((hawk_val_arr_t*)this->val)->arr);
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::Value::getArrayedCapa () const
 | |
| {
 | |
| 	if (HAWK_RTX_GETVALTYPE(r->rtx, this->val) != HAWK_VAL_ARR) return -1;
 | |
| 	return (hawk_ooi_t)HAWK_ARR_CAPA(((hawk_val_arr_t*)this->val)->arr);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setArrayedVal (hawk_ooi_t idx, hawk_val_t* v)
 | |
| {
 | |
| 	if (HAWK_UNLIKELY(!this->run)) return -1;
 | |
| 	return this->setArrayedVal(this->run, idx, v);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setArrayedVal (Run* r, hawk_ooi_t idx, hawk_val_t* v)
 | |
| {
 | |
| 	HAWK_ASSERT(r != HAWK_NULL);
 | |
| 
 | |
| 	if (HAWK_RTX_GETVALTYPE(r->rtx, this->val) != HAWK_VAL_ARR)
 | |
| 	{
 | |
| 		// the previous value is not a arr.
 | |
| 		// a new arr value needs to be created first.
 | |
| 		hawk_val_t* arr = hawk_rtx_makearrval(r->rtx, -1); // TODO: can we change this to accept the initial value in the constructor
 | |
| 		if (arr == HAWK_NULL)
 | |
| 		{
 | |
| 			r->hawk->retrieveError(r);
 | |
| 			return -1;
 | |
| 		}
 | |
| 
 | |
| 		hawk_rtx_refupval(r->rtx, arr);
 | |
| 
 | |
| 		// update the arr with a given value
 | |
| 		if (hawk_rtx_setarrvalfld(r->rtx, arr, idx, v) == HAWK_NULL)
 | |
| 		{
 | |
| 			hawk_rtx_refdownval(r->rtx, arr);
 | |
| 			r->hawk->retrieveError(r);
 | |
| 			return -1;
 | |
| 		}
 | |
| 
 | |
| 		// free the previous value
 | |
| 		if (this->run)
 | |
| 		{
 | |
| 			// if val is not nil, this->run can't be NULL
 | |
| 			hawk_rtx_refdownval(this->run->rtx, this->val);
 | |
| 		}
 | |
| 
 | |
| 		this->run = r;
 | |
| 		this->val = arr;
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		HAWK_ASSERT(run != HAWK_NULL);
 | |
| 
 | |
| 		// if the previous value is a arr, things are a bit simpler
 | |
| 		// however it needs to check if the runtime context matches
 | |
| 		// with the previous one.
 | |
| 		if (this->run != r)
 | |
| 		{
 | |
| 			// it can't span across multiple runtime contexts
 | |
| 			this->run->setError(HAWK_EINVAL);
 | |
| 			this->run->hawk->retrieveError(run);
 | |
| 			return -1;
 | |
| 		}
 | |
| 
 | |
| 		// update the arr with a given value
 | |
| 		if (hawk_rtx_setarrvalfld(r->rtx, val, idx, v) == HAWK_NULL)
 | |
| 		{
 | |
| 			r->hawk->retrieveError(r);
 | |
| 			return -1;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| bool Hawk::Value::isArrayed () const
 | |
| {
 | |
| 	HAWK_ASSERT(val != HAWK_NULL);
 | |
| 	return HAWK_RTX_GETVALTYPE(this->run->rtx, val) == HAWK_VAL_ARR;
 | |
| }
 | |
| 
 | |
| 
 | |
| int Hawk::Value::getArrayed (hawk_ooi_t idx, Value* v) const
 | |
| {
 | |
| 	HAWK_ASSERT(val != HAWK_NULL);
 | |
| 
 | |
| 	// not a map. v is just nil. not an error
 | |
| 	if (HAWK_RTX_GETVALTYPE(this->run->rtx, val) != HAWK_VAL_ARR)
 | |
| 	{
 | |
| 		v->clear ();
 | |
| 		return 0;
 | |
| 	}
 | |
| 
 | |
| 	// get the value from the map.
 | |
| 	hawk_val_t* fv = hawk_rtx_getarrvalfld(this->run->rtx, val, idx);
 | |
| 
 | |
| 	// the key is not found. it is not an error. v is just nil
 | |
| 	if (fv == HAWK_NULL)
 | |
| 	{
 | |
| 		v->clear ();
 | |
| 		return 0;
 | |
| 	}
 | |
| 
 | |
| 	// if v.set fails, it should return an error
 | |
| 	return v->setVal(this->run, fv);
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////////
 | |
| 
 | |
| hawk_ooi_t Hawk::Value::getIndexedLength () const
 | |
| {
 | |
| 	if (HAWK_RTX_GETVALTYPE(r->rtx, this->val) != HAWK_VAL_MAP) return -1;
 | |
| 	return (hawk_ooi_t)HAWK_MAP_SIZE(((hawk_val_map_t*)this->val)->map);
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::Value::getIndexedSize () const
 | |
| {
 | |
| 	if (HAWK_RTX_GETVALTYPE(r->rtx, this->val) != HAWK_VAL_MAP) return -1;
 | |
| 	return (hawk_ooi_t)HAWK_MAP_SIZE(((hawk_val_map_t*)this->val)->map);
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::Value::getIndexedCapa () const
 | |
| {
 | |
| 	if (HAWK_RTX_GETVALTYPE(r->rtx, this->val) != HAWK_VAL_MAP) return -1;
 | |
| 	return (hawk_ooi_t)hawk_map_getcapa(((hawk_val_map_t*)this->val)->map);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setIndexedVal (const Index& idx, hawk_val_t* v)
 | |
| {
 | |
| 	if (HAWK_UNLIKELY(!this->run)) return -1;
 | |
| 	return this->setIndexedVal(this->run, idx, v);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setIndexedVal (Run* r, const Index& idx, hawk_val_t* v)
 | |
| {
 | |
| 	HAWK_ASSERT(r != HAWK_NULL);
 | |
| 
 | |
| 	if (HAWK_RTX_GETVALTYPE(r->rtx, this->val) != HAWK_VAL_MAP)
 | |
| 	{
 | |
| 		// the previous value is not a map.
 | |
| 		// a new map value needs to be created first.
 | |
| 		hawk_val_t* map = hawk_rtx_makemapval(r->rtx);
 | |
| 		if (map == HAWK_NULL)
 | |
| 		{
 | |
| 			r->hawk->retrieveError(r);
 | |
| 			return -1;
 | |
| 		}
 | |
| 
 | |
| 		hawk_rtx_refupval(r->rtx, map);
 | |
| 
 | |
| 		// update the map with a given value
 | |
| 		if (hawk_rtx_setmapvalfld(r->rtx, map, idx.ptr, idx.len, v) == HAWK_NULL)
 | |
| 		{
 | |
| 			hawk_rtx_refdownval(r->rtx, map);
 | |
| 			r->hawk->retrieveError(r);
 | |
| 			return -1;
 | |
| 		}
 | |
| 
 | |
| 		// free the previous value
 | |
| 		if (this->run)
 | |
| 		{
 | |
| 			// if val is not nil, this->run can't be NULL
 | |
| 			hawk_rtx_refdownval(this->run->rtx, this->val);
 | |
| 		}
 | |
| 
 | |
| 		this->run = r;
 | |
| 		this->val = map;
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		HAWK_ASSERT(run != HAWK_NULL);
 | |
| 
 | |
| 		// if the previous value is a map, things are a bit simpler
 | |
| 		// however it needs to check if the runtime context matches
 | |
| 		// with the previous one.
 | |
| 		if (this->run != r)
 | |
| 		{
 | |
| 			// it can't span across multiple runtime contexts
 | |
| 			this->run->setError(HAWK_EINVAL);
 | |
| 			this->run->hawk->retrieveError(run);
 | |
| 			return -1;
 | |
| 		}
 | |
| 
 | |
| 		// update the map with a given value
 | |
| 		if (hawk_rtx_setmapvalfld(r->rtx, val, idx.ptr, idx.len, v) == HAWK_NULL)
 | |
| 		{
 | |
| 			r->hawk->retrieveError(r);
 | |
| 			return -1;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setIndexedInt (const Index& idx, hawk_int_t v)
 | |
| {
 | |
| 	if (run == HAWK_NULL) return -1;
 | |
| 	return this->setIndexedInt (run, idx, v);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setIndexedInt (Run* r, const Index& idx, hawk_int_t v)
 | |
| {
 | |
| 	hawk_val_t* tmp = hawk_rtx_makeintval (r->rtx, v);
 | |
| 	if (tmp == HAWK_NULL)
 | |
| 	{
 | |
| 		r->hawk->retrieveError(r);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	hawk_rtx_refupval(r->rtx, tmp);
 | |
| 	int n = this->setIndexedVal(r, idx, tmp);
 | |
| 	hawk_rtx_refdownval(r->rtx, tmp);
 | |
| 
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setIndexedFlt (const Index& idx, hawk_flt_t v)
 | |
| {
 | |
| 	if (run == HAWK_NULL) return -1;
 | |
| 	return this->setIndexedFlt(run, idx, v);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setIndexedFlt (Run* r, const Index& idx, hawk_flt_t v)
 | |
| {
 | |
| 	hawk_val_t* tmp = hawk_rtx_makefltval(r->rtx, v);
 | |
| 	if (tmp == HAWK_NULL)
 | |
| 	{
 | |
| 		r->hawk->retrieveError(r);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	hawk_rtx_refupval(r->rtx, tmp);
 | |
| 	int n = this->setIndexedVal(r, idx, tmp);
 | |
| 	hawk_rtx_refdownval(r->rtx, tmp);
 | |
| 
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////////
 | |
| 
 | |
| int Hawk::Value::setIndexedStr (const Index& idx, const hawk_uch_t* str, hawk_oow_t len, bool numeric)
 | |
| {
 | |
| 	if (HAWK_UNLIKELY(!this->run)) return -1; // NOTE: this->run isn't available. neither is this->run->hawk. unable to set an error code
 | |
| 	return this->setIndexedStr(this->run, idx, str, len, numeric);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setIndexedStr (Run* r, const Index& idx, const hawk_uch_t* str, hawk_oow_t len, bool numeric)
 | |
| {
 | |
| 	hawk_val_t* tmp;
 | |
| 
 | |
| 	tmp = numeric? hawk_rtx_makenumorstrvalwithuchars(r->rtx, str, len):
 | |
| 	               hawk_rtx_makestrvalwithuchars(r->rtx, str, len);
 | |
| 	if (HAWK_UNLIKELY(!tmp))
 | |
| 	{
 | |
| 		r->hawk->retrieveError(r);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	hawk_rtx_refupval(r->rtx, tmp);
 | |
| 	int n = this->setIndexedVal(r, idx, tmp);
 | |
| 	hawk_rtx_refdownval(r->rtx, tmp);
 | |
| 
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setIndexedStr (const Index& idx, const hawk_uch_t* str, bool numeric)
 | |
| {
 | |
| 	if (run == HAWK_NULL) return -1; // NOTE: this->run isn't available. neither is this->run->hawk. unable to set an error code
 | |
| 	return this->setIndexedStr(run, idx, str, numeric);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setIndexedStr (Run* r, const Index& idx, const hawk_uch_t* str, bool numeric)
 | |
| {
 | |
| 	hawk_val_t* tmp;
 | |
| 	tmp = numeric? hawk_rtx_makenumorstrvalwithuchars(r->rtx, str, hawk_count_ucstr(str)):
 | |
| 	               hawk_rtx_makestrvalwithucstr(r->rtx, str);
 | |
| 	if (HAWK_UNLIKELY(!tmp))
 | |
| 	{
 | |
| 		r->hawk->retrieveError(r);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	hawk_rtx_refupval(r->rtx, tmp);
 | |
| 	int n = this->setIndexedVal(r, idx, tmp);
 | |
| 	hawk_rtx_refdownval(r->rtx, tmp);
 | |
| 
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setIndexedStr (const Index& idx, const hawk_bch_t* str, hawk_oow_t len, bool numeric)
 | |
| {
 | |
| 	if (HAWK_UNLIKELY(!this->run)) return -1; // NOTE: this->run isn't available. neither is this->run->hawk. unable to set an error code
 | |
| 	return this->setIndexedStr(this->run, idx, str, len, numeric);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setIndexedStr (Run* r, const Index& idx, const hawk_bch_t* str, hawk_oow_t len, bool numeric)
 | |
| {
 | |
| 	hawk_val_t* tmp;
 | |
| 
 | |
| 	tmp = numeric? hawk_rtx_makenumorstrvalwithbchars(r->rtx, str, len):
 | |
| 	               hawk_rtx_makestrvalwithbchars(r->rtx, str, len);
 | |
| 	if (HAWK_UNLIKELY(!tmp))
 | |
| 	{
 | |
| 		r->hawk->retrieveError(r);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	hawk_rtx_refupval(r->rtx, tmp);
 | |
| 	int n = this->setIndexedVal(r, idx, tmp);
 | |
| 	hawk_rtx_refdownval(r->rtx, tmp);
 | |
| 
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setIndexedStr (const Index& idx, const hawk_bch_t* str, bool numeric)
 | |
| {
 | |
| 	if (HAWK_UNLIKELY(!this->run)) return -1; // NOTE: this->run isn't available. neither is this->run->hawk. unable to set an error code
 | |
| 	return this->setIndexedStr(run, idx, str, numeric);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setIndexedStr (Run* r, const Index& idx, const hawk_bch_t* str, bool numeric)
 | |
| {
 | |
| 	hawk_val_t* tmp;
 | |
| 
 | |
| 	tmp = numeric? hawk_rtx_makenumorstrvalwithbchars(r->rtx, str, hawk_count_bcstr(str)):
 | |
| 	               hawk_rtx_makestrvalwithbcstr(r->rtx, str);
 | |
| 	if (HAWK_UNLIKELY(!tmp))
 | |
| 	{
 | |
| 		r->hawk->retrieveError(r);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	hawk_rtx_refupval(r->rtx, tmp);
 | |
| 	int n = this->setIndexedVal(r, idx, tmp);
 | |
| 	hawk_rtx_refdownval(r->rtx, tmp);
 | |
| 
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////////
 | |
| 
 | |
| int Hawk::Value::setIndexedMbs (const Index& idx, const hawk_bch_t* str, hawk_oow_t len)
 | |
| {
 | |
| 	if (HAWK_UNLIKELY(!this->run)) return -1; // NOTE: this->run isn't available. neither is this->run->hawk. unable to set an error code
 | |
| 	return this->setIndexedMbs(this->run, idx, str, len);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setIndexedMbs (Run* r, const Index& idx, const hawk_bch_t* str, hawk_oow_t len)
 | |
| {
 | |
| 	hawk_val_t* tmp;
 | |
| 
 | |
| 	hawk_bcs_t oocs;
 | |
| 	oocs.ptr = (hawk_bch_t*)str;
 | |
| 	oocs.len = len;
 | |
| 
 | |
| 	tmp = hawk_rtx_makembsvalwithbcs(r->rtx, &oocs);
 | |
| 	if (HAWK_UNLIKELY(!tmp))
 | |
| 	{
 | |
| 		r->hawk->retrieveError(r);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	hawk_rtx_refupval(r->rtx, tmp);
 | |
| 	int n = this->setIndexedVal(r, idx, tmp);
 | |
| 	hawk_rtx_refdownval(r->rtx, tmp);
 | |
| 
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setIndexedMbs (const Index& idx, const hawk_bch_t* str)
 | |
| {
 | |
| 	if (HAWK_UNLIKELY(!this->run)) return -1; // NOTE: this->run isn't available. neither is this->run->hawk. unable to set an error code
 | |
| 	return this->setIndexedMbs(run, idx, str);
 | |
| }
 | |
| 
 | |
| int Hawk::Value::setIndexedMbs (Run* r, const Index& idx, const hawk_bch_t* str)
 | |
| {
 | |
| 	hawk_val_t* tmp;
 | |
| 	tmp = hawk_rtx_makembsvalwithbchars(r->rtx, str, hawk_count_bcstr(str));
 | |
| 	if (HAWK_UNLIKELY(!tmp))
 | |
| 	{
 | |
| 		r->hawk->retrieveError(r);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	hawk_rtx_refupval(r->rtx, tmp);
 | |
| 	int n = this->setIndexedVal(r, idx, tmp);
 | |
| 	hawk_rtx_refdownval(r->rtx, tmp);
 | |
| 
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| 
 | |
| bool Hawk::Value::isIndexed () const
 | |
| {
 | |
| 	HAWK_ASSERT(val != HAWK_NULL);
 | |
| 	return HAWK_RTX_GETVALTYPE(this->run->rtx, val) == HAWK_VAL_MAP;
 | |
| }
 | |
| 
 | |
| int Hawk::Value::getIndexed (const Index& idx, Value* v) const
 | |
| {
 | |
| 	HAWK_ASSERT(val != HAWK_NULL);
 | |
| 
 | |
| 	// not a map. v is just nil. not an error
 | |
| 	if (HAWK_RTX_GETVALTYPE(this->run->rtx, val) != HAWK_VAL_MAP)
 | |
| 	{
 | |
| 		v->clear ();
 | |
| 		return 0;
 | |
| 	}
 | |
| 
 | |
| 	// get the value from the map.
 | |
| 	hawk_val_t* fv = hawk_rtx_getmapvalfld(this->run->rtx, val, (hawk_ooch_t*)idx.ptr, idx.len);
 | |
| 
 | |
| 	// the key is not found. it is not an error. v is just nil
 | |
| 	if (fv == HAWK_NULL)
 | |
| 	{
 | |
| 		v->clear ();
 | |
| 		return 0;
 | |
| 	}
 | |
| 
 | |
| 	// if v.set fails, it should return an error
 | |
| 	return v->setVal(this->run, fv);
 | |
| }
 | |
| 
 | |
| Hawk::Value::IndexIterator Hawk::Value::getFirstIndex (Index* idx) const
 | |
| {
 | |
| 	HAWK_ASSERT(this->val != HAWK_NULL);
 | |
| 
 | |
| 	if (HAWK_RTX_GETVALTYPE(this->run->rtx, this->val) != HAWK_VAL_MAP) return IndexIterator::END;
 | |
| 
 | |
| 	HAWK_ASSERT(this->run != HAWK_NULL);
 | |
| 
 | |
| 	Hawk::Value::IndexIterator itr;
 | |
| 	hawk_val_map_itr_t* iptr;
 | |
| 
 | |
| 	iptr = hawk_rtx_getfirstmapvalitr(this->run->rtx, this->val, &itr);
 | |
| 	if (iptr == HAWK_NULL) return IndexIterator::END; // no more key
 | |
| 
 | |
| 	idx->set (HAWK_VAL_MAP_ITR_KEY(iptr));
 | |
| 
 | |
| 	return itr;
 | |
| }
 | |
| 
 | |
| Hawk::Value::IndexIterator Hawk::Value::getNextIndex (Index* idx, const IndexIterator& curitr) const
 | |
| {
 | |
| 	HAWK_ASSERT(val != HAWK_NULL);
 | |
| 
 | |
| 	if (HAWK_RTX_GETVALTYPE(this->run->rtx, val) != HAWK_VAL_MAP) return IndexIterator::END;
 | |
| 
 | |
| 	HAWK_ASSERT(this->run != HAWK_NULL);
 | |
| 
 | |
| 	Hawk::Value::IndexIterator itr(curitr);
 | |
| 	hawk_val_map_itr_t* iptr;
 | |
| 
 | |
| 	iptr = hawk_rtx_getnextmapvalitr(this->run->rtx, this->val, &itr);
 | |
| 	if (iptr == HAWK_NULL) return IndexIterator::END; // no more key
 | |
| 
 | |
| 	idx->set (HAWK_VAL_MAP_ITR_KEY(iptr));
 | |
| 
 | |
| 	return itr;
 | |
| }
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////
 | |
| // Hawk::Run
 | |
| //////////////////////////////////////////////////////////////////
 | |
| 
 | |
| Hawk::Run::Run (Hawk* hawk): hawk(hawk), rtx (HAWK_NULL)
 | |
| {
 | |
| }
 | |
| 
 | |
| Hawk::Run::Run (Hawk* hawk, hawk_rtx_t* rtx): hawk(hawk), rtx (rtx)
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| }
 | |
| 
 | |
| Hawk::Run::~Run ()
 | |
| {
 | |
| }
 | |
| 
 | |
| void Hawk::Run::halt () const
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| 	hawk_rtx_halt (this->rtx);
 | |
| }
 | |
| 
 | |
| bool Hawk::Run::isHalt () const
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| 	return !!hawk_rtx_ishalt(this->rtx);
 | |
| }
 | |
| 
 | |
| hawk_errnum_t Hawk::Run::getErrorNumber () const
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| 	return hawk_rtx_geterrnum(this->rtx);
 | |
| }
 | |
| 
 | |
| hawk_loc_t Hawk::Run::getErrorLocation () const
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| 	return *hawk_rtx_geterrloc(this->rtx);
 | |
| }
 | |
| 
 | |
| const hawk_ooch_t* Hawk::Run::getErrorMessage () const
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| 	return hawk_rtx_geterrmsg(this->rtx);
 | |
| }
 | |
| 
 | |
| const hawk_uch_t* Hawk::Run::getErrorMessageU () const
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| 	return hawk_rtx_geterrumsg(this->rtx);
 | |
| }
 | |
| 
 | |
| const hawk_bch_t* Hawk::Run::getErrorMessageB () const
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| 	return hawk_rtx_geterrbmsg(this->rtx);
 | |
| }
 | |
| 
 | |
| void Hawk::Run::setError (hawk_errnum_t code, const hawk_loc_t* loc)
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| 	hawk_rtx_seterrnum(this->rtx, loc, code);
 | |
| }
 | |
| 
 | |
| void Hawk::Run::formatError (hawk_errnum_t code, const hawk_loc_t* loc, const hawk_bch_t* fmt, ...)
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| 	va_list ap;
 | |
| 	va_start (ap, fmt);
 | |
| 	hawk_rtx_seterrbvfmt (this->rtx, loc, code, fmt, ap);
 | |
| 	va_end (ap);
 | |
| }
 | |
| 
 | |
| void Hawk::Run::formatError (hawk_errnum_t code, const hawk_loc_t* loc, const hawk_uch_t* fmt, ...)
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| 	va_list ap;
 | |
| 	va_start (ap, fmt);
 | |
| 	hawk_rtx_seterruvfmt (this->rtx, loc, code, fmt, ap);
 | |
| 	va_end (ap);
 | |
| }
 | |
| 
 | |
| int Hawk::Run::setGlobal (int id, hawk_int_t v)
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| 
 | |
| 	hawk_val_t* tmp = hawk_rtx_makeintval(this->rtx, v);
 | |
| 	if (HAWK_UNLIKELY(!tmp)) return -1;
 | |
| 
 | |
| 	hawk_rtx_refupval(this->rtx, tmp);
 | |
| 	int n = hawk_rtx_setgbl(this->rtx, id, tmp);
 | |
| 	hawk_rtx_refdownval(this->rtx, tmp);
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::Run::setGlobal (int id, hawk_flt_t v)
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| 
 | |
| 	hawk_val_t* tmp = hawk_rtx_makefltval (this->rtx, v);
 | |
| 	if (HAWK_UNLIKELY(!tmp)) return -1;
 | |
| 
 | |
| 	hawk_rtx_refupval(this->rtx, tmp);
 | |
| 	int n = hawk_rtx_setgbl(this->rtx, id, tmp);
 | |
| 	hawk_rtx_refdownval(this->rtx, tmp);
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::Run::setGlobal (int id, const hawk_uch_t* ptr, hawk_oow_t len, bool mbs)
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| 
 | |
| 	hawk_val_t* tmp = mbs? hawk_rtx_makembsvalwithuchars(this->rtx, ptr, len):
 | |
| 	                       hawk_rtx_makestrvalwithuchars(this->rtx, ptr, len);
 | |
| 	if (HAWK_UNLIKELY(!tmp)) return -1;
 | |
| 
 | |
| 	hawk_rtx_refupval(this->rtx, tmp);
 | |
| 	int n = hawk_rtx_setgbl(this->rtx, id, tmp);
 | |
| 	hawk_rtx_refdownval(this->rtx, tmp);
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::Run::setGlobal (int id, const hawk_bch_t* ptr, hawk_oow_t len, bool mbs)
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| 
 | |
| 	hawk_val_t* tmp = mbs? hawk_rtx_makembsvalwithbchars(this->rtx, ptr, len):
 | |
| 	                       hawk_rtx_makestrvalwithbchars(this->rtx, ptr, len);
 | |
| 	if (HAWK_UNLIKELY(!tmp)) return -1;
 | |
| 
 | |
| 	hawk_rtx_refupval(this->rtx, tmp);
 | |
| 	int n = hawk_rtx_setgbl(this->rtx, id, tmp);
 | |
| 	hawk_rtx_refdownval(this->rtx, tmp);
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::Run::setGlobal (int id, const hawk_uch_t* ptr, bool mbs)
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| 
 | |
| 	hawk_val_t* tmp = mbs? hawk_rtx_makembsvalwithucstr(this->rtx, ptr):
 | |
| 	                       hawk_rtx_makestrvalwithucstr(this->rtx, ptr);
 | |
| 	if (HAWK_UNLIKELY(!tmp)) return -1;
 | |
| 
 | |
| 	hawk_rtx_refupval(this->rtx, tmp);
 | |
| 	int n = hawk_rtx_setgbl(this->rtx, id, tmp);
 | |
| 	hawk_rtx_refdownval(this->rtx, tmp);
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::Run::setGlobal (int id, const hawk_bch_t* ptr, bool mbs)
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| 
 | |
| 	hawk_val_t* tmp = mbs? hawk_rtx_makembsvalwithbcstr(this->rtx, ptr):
 | |
| 	                       hawk_rtx_makestrvalwithbcstr(this->rtx, ptr);
 | |
| 	if (HAWK_UNLIKELY(!tmp)) return -1;
 | |
| 
 | |
| 	hawk_rtx_refupval(this->rtx, tmp);
 | |
| 	int n = hawk_rtx_setgbl(this->rtx, id, tmp);
 | |
| 	hawk_rtx_refdownval(this->rtx, tmp);
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::Run::setGlobal (int id, const Value& gbl)
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| 	return hawk_rtx_setgbl(this->rtx, id, (hawk_val_t*)gbl);
 | |
| }
 | |
| 
 | |
| int Hawk::Run::getGlobal (int id, Value& g) const
 | |
| {
 | |
| 	HAWK_ASSERT(this->rtx != HAWK_NULL);
 | |
| 	return g.setVal ((Run*)this, hawk_rtx_getgbl (this->rtx, id));
 | |
| }
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////
 | |
| // Hawk
 | |
| //////////////////////////////////////////////////////////////////
 | |
| 
 | |
| Hawk::Hawk (Mmgr* mmgr):
 | |
| 	Mmged(mmgr), hawk(HAWK_NULL),
 | |
| #if defined(HAWK_USE_HTB_FOR_FUNCTION_MAP)
 | |
| 	functionMap(HAWK_NULL),
 | |
| #else
 | |
| 	functionMap(this),
 | |
| #endif
 | |
| 	source_reader(HAWK_NULL), source_writer(HAWK_NULL),
 | |
| 	pipe_handler(HAWK_NULL), file_handler(HAWK_NULL),
 | |
| 	console_handler(HAWK_NULL), runctx(this)
 | |
| 
 | |
| {
 | |
| 	HAWK_MEMSET (&this->errinf, 0, HAWK_SIZEOF(this->errinf));
 | |
| 	this->errinf.num = HAWK_ENOERR;
 | |
| 
 | |
| 	this->_cmgr = hawk_get_cmgr_by_id(HAWK_CMGR_UTF8);
 | |
| }
 | |
| 
 | |
| Hawk::~Hawk()
 | |
| {
 | |
| 	this->close();
 | |
| }
 | |
| 
 | |
| const hawk_ooch_t* Hawk::getErrorString (hawk_errnum_t num) const
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 	HAWK_ASSERT(this->dflerrstr != HAWK_NULL);
 | |
| 	return this->dflerrstr(num);
 | |
| }
 | |
| 
 | |
| const hawk_ooch_t* Hawk::xerrstr (hawk_t* a, hawk_errnum_t num)
 | |
| {
 | |
| 	Hawk* hawk = *(Hawk**)GET_XTN(a);
 | |
| 	return hawk->getErrorString(num);
 | |
| }
 | |
| 
 | |
| hawk_errnum_t Hawk::getErrorNumber () const
 | |
| {
 | |
| 	return this->errinf.num;
 | |
| }
 | |
| 
 | |
| hawk_loc_t Hawk::getErrorLocation () const
 | |
| {
 | |
| 	return this->errinf.loc;
 | |
| }
 | |
| 
 | |
| const hawk_ooch_t* Hawk::getErrorLocationFile () const
 | |
| {
 | |
| 	return this->errinf.loc.file;
 | |
| }
 | |
| 
 | |
| const hawk_uch_t* Hawk::getErrorLocationFileU () const
 | |
| {
 | |
| #if defined(HAWK_OOCH_IS_UCH)
 | |
| 	return this->errinf.loc.file;
 | |
| #else
 | |
| 	if (!this->errinf.loc.file) return HAWK_NULL;
 | |
| 	hawk_oow_t wcslen, mbslen;
 | |
| 	wcslen = HAWK_COUNTOF(this->xerrlocfile);
 | |
| 	hawk_conv_bcstr_to_ucstr_with_cmgr(this->errinf.loc.file, &mbslen, this->xerrlocfile, &wcslen, this->getCmgr(), 1);
 | |
| 	return this->xerrlocfile;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| const hawk_bch_t* Hawk::getErrorLocationFileB () const
 | |
| {
 | |
| #if defined(HAWK_OOCH_IS_UCH)
 | |
| 	if (!this->errinf.loc.file) return HAWK_NULL;
 | |
| 	hawk_oow_t wcslen, mbslen;
 | |
| 	mbslen = HAWK_COUNTOF(this->xerrlocfile);
 | |
| 	hawk_conv_ucstr_to_bcstr_with_cmgr(this->errinf.loc.file, &wcslen, this->xerrlocfile, &mbslen, this->getCmgr());
 | |
| 	return this->xerrlocfile;
 | |
| #else
 | |
| 	return this->errinf.loc.file;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| const hawk_ooch_t* Hawk::getErrorMessage () const
 | |
| {
 | |
| 	return this->errinf.msg;
 | |
| }
 | |
| 
 | |
| const hawk_uch_t* Hawk::getErrorMessageU () const
 | |
| {
 | |
| #if defined(HAWK_OOCH_IS_UCH)
 | |
| 	return this->errinf.msg;
 | |
| #else
 | |
| 	hawk_oow_t wcslen, mbslen;
 | |
| 	wcslen = HAWK_COUNTOF(this->xerrmsg);
 | |
| 	hawk_conv_bcstr_to_ucstr_with_cmgr(this->errinf.msg, &mbslen, this->xerrmsg, &wcslen, this->getCmgr(), 1);
 | |
| 	return this->xerrmsg;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| const hawk_bch_t* Hawk::getErrorMessageB () const
 | |
| {
 | |
| #if defined(HAWK_OOCH_IS_UCH)
 | |
| 	hawk_oow_t wcslen, mbslen;
 | |
| 	mbslen = HAWK_COUNTOF(this->xerrmsg);
 | |
| 	hawk_conv_ucstr_to_bcstr_with_cmgr(this->errinf.msg, &wcslen, this->xerrmsg, &mbslen, this->getCmgr());
 | |
| 	return this->xerrmsg;
 | |
| #else
 | |
| 	return this->errinf.msg;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| void Hawk::setError (hawk_errnum_t code, const hawk_loc_t* loc)
 | |
| {
 | |
| 	if (this->hawk)
 | |
| 	{
 | |
| 		hawk_seterrnum(this->hawk, loc, code);
 | |
| 		this->retrieveError();
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		HAWK_MEMSET(&this->errinf, 0, HAWK_SIZEOF(this->errinf));
 | |
| 		this->errinf.num = code;
 | |
| 		if (loc) this->errinf.loc = *loc;
 | |
| 		hawk_copy_oocstr(this->errinf.msg, HAWK_COUNTOF(this->errinf.msg), hawk_dfl_errstr(code));
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void Hawk::formatError (hawk_errnum_t code, const hawk_loc_t* loc, const hawk_bch_t* fmt, ...)
 | |
| {
 | |
| 	if (this->hawk)
 | |
| 	{
 | |
| 		va_list ap;
 | |
| 		va_start(ap, fmt);
 | |
| 		hawk_seterrbvfmt(this->hawk, loc, code, fmt, ap);
 | |
| 		va_end(ap);
 | |
| 		this->retrieveError();
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		HAWK_MEMSET(&this->errinf, 0, HAWK_SIZEOF(this->errinf));
 | |
| 		this->errinf.num = code;
 | |
| 		if (loc) this->errinf.loc = *loc;
 | |
| 		hawk_copy_oocstr(this->errinf.msg, HAWK_COUNTOF(this->errinf.msg), hawk_dfl_errstr(code));
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void Hawk::formatError (hawk_errnum_t code, const hawk_loc_t* loc, const hawk_uch_t* fmt, ...)
 | |
| {
 | |
| 	if  (this->hawk)
 | |
| 	{
 | |
| 		va_list ap;
 | |
| 		va_start(ap, fmt);
 | |
| 		hawk_seterruvfmt(this->hawk, loc, code, fmt, ap);
 | |
| 		va_end(ap);
 | |
| 		this->retrieveError();
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		HAWK_MEMSET(&this->errinf, 0, HAWK_SIZEOF(this->errinf));
 | |
| 		this->errinf.num = code;
 | |
| 		if (loc) this->errinf.loc = *loc;
 | |
| 		hawk_copy_oocstr(this->errinf.msg, HAWK_COUNTOF(this->errinf.msg), hawk_dfl_errstr(code));
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void Hawk::clearError ()
 | |
| {
 | |
| 	HAWK_MEMSET(&this->errinf, 0, HAWK_SIZEOF(this->errinf));
 | |
| 	this->errinf.num = HAWK_ENOERR;
 | |
| }
 | |
| 
 | |
| void Hawk::retrieveError()
 | |
| {
 | |
| 	if (this->hawk == HAWK_NULL)
 | |
| 	{
 | |
| 		this->clearError();
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		hawk_geterrinf(this->hawk, &this->errinf);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void Hawk::retrieveError(Run* run)
 | |
| {
 | |
| 	HAWK_ASSERT(run != HAWK_NULL);
 | |
| 	if (run->rtx == HAWK_NULL) return;
 | |
| 	hawk_rtx_geterrinf(run->rtx, &this->errinf);
 | |
| }
 | |
| 
 | |
| static void fini_xtn (hawk_t* hawk, void* ctx)
 | |
| {
 | |
| 	xtn_t* xtn = GET_XTN(hawk);
 | |
| 	xtn->hawk->uponClosing();
 | |
| }
 | |
| 
 | |
| static void clear_xtn (hawk_t* hawk, void* ctx)
 | |
| {
 | |
| 	xtn_t* xtn = GET_XTN(hawk);
 | |
| 	xtn->hawk->uponClearing();
 | |
| }
 | |
| 
 | |
| int Hawk::open ()
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk == HAWK_NULL);
 | |
| #if defined(HAWK_USE_HTB_FOR_FUNCTION_MAP)
 | |
| 	HAWK_ASSERT(this->functionMap == HAWK_NULL);
 | |
| #endif
 | |
| 
 | |
| 	hawk_prm_t prm;
 | |
| 
 | |
| 	HAWK_MEMSET (&prm, 0, HAWK_SIZEOF(prm));
 | |
| 	prm.math.pow  = &Hawk::pow;
 | |
| 	prm.math.mod  = &Hawk::mod;
 | |
| 	prm.modopen   = &Hawk::modopen;
 | |
| 	prm.modclose  = &Hawk::modclose;
 | |
| 	prm.modgetsym = &Hawk::modgetsym;
 | |
| 
 | |
| 	this->hawk = hawk_open(this->getMmgr(), HAWK_SIZEOF(xtn_t), this->getCmgr(), &prm, &this->errinf);
 | |
| 	if (HAWK_UNLIKELY(!this->hawk)) return -1;
 | |
| 
 | |
| 	this->hawk->_instsize += HAWK_SIZEOF(xtn_t);
 | |
| 
 | |
| 	// associate this Hawk object with the underlying hawk object
 | |
| 	xtn_t* xtn = (xtn_t*)GET_XTN(this->hawk);
 | |
| 	xtn->hawk = this;
 | |
| 	xtn->ecb.close = fini_xtn;
 | |
| 	xtn->ecb.clear = clear_xtn;
 | |
| 
 | |
| 	this->dflerrstr = hawk_geterrstr(this->hawk);
 | |
| // TODO: revive this too when hawk_seterrstr is revived()
 | |
| //	hawk_seterrstr (this->hawk, Hawk::xerrstr);
 | |
| 
 | |
| #if defined(HAWK_USE_HTB_FOR_FUNCTION_MAP)
 | |
| 	this->functionMap = hawk_htb_open(
 | |
| 		hawk_getgem(this->hawk), HAWK_SIZEOF(this), 512, 70,
 | |
| 		HAWK_SIZEOF(hawk_ooch_t), 1
 | |
| 	);
 | |
| 	if (this->functionMap == HAWK_NULL)
 | |
| 	{
 | |
| 		hawk_close(this->hawk);
 | |
| 		this->hawk = HAWK_NULL;
 | |
| 
 | |
| 		this->setError(HAWK_ENOMEM);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	*(Hawk**)hawk_htb_getxtn(this->functionMap) = this;
 | |
| 
 | |
| 	static hawk_htb_style_t style =
 | |
| 	{
 | |
| 		{
 | |
| 			HAWK_HTB_COPIER_DEFAULT, // keep the key pointer only
 | |
| 			HAWK_HTB_COPIER_INLINE   // copy the value into the pair
 | |
| 		},
 | |
| 		{
 | |
| 			HAWK_HTB_FREEER_DEFAULT, // free nothing
 | |
| 			HAWK_HTB_FREEER_DEFAULT  // free nothing
 | |
| 		},
 | |
| 		HAWK_HTB_COMPER_DEFAULT,
 | |
| 		HAWK_HTB_KEEPER_DEFAULT,
 | |
| 		HAWK_HTB_SIZER_DEFAULT,
 | |
| 		HAWK_HTB_HASHER_DEFAULT
 | |
| 	};
 | |
| 	hawk_htb_setstyle (this->functionMap, &style);
 | |
| 
 | |
| #endif
 | |
| 
 | |
| 	// push the call back after everything else is ok.
 | |
| 	hawk_pushecb (this->hawk, &xtn->ecb);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| void Hawk::close ()
 | |
| {
 | |
| 	this->fini_runctx();
 | |
| 	this->clearArguments();
 | |
| 
 | |
| #if defined(HAWK_USE_HTB_FOR_FUNCTION_MAP)
 | |
| 	if (this->functionMap)
 | |
| 	{
 | |
| 		hawk_htb_close(this->functionMap);
 | |
| 		this->functionMap = HAWK_NULL;
 | |
| 	}
 | |
| #else
 | |
| 	this->functionMap.clear();
 | |
| #endif
 | |
| 
 | |
| 	if (this->hawk)
 | |
| 	{
 | |
| 		hawk_close(this->hawk);
 | |
| 		this->hawk = HAWK_NULL;
 | |
| 	}
 | |
| 
 | |
| 	this->clearError();
 | |
| }
 | |
| 
 | |
| hawk_cmgr_t* Hawk::getCmgr () const
 | |
| {
 | |
| 	return this->hawk? hawk_getcmgr(this->hawk): this->_cmgr;
 | |
| }
 | |
| 
 | |
| void Hawk::setCmgr (hawk_cmgr_t* cmgr)
 | |
| {
 | |
| 	if (this->hawk) hawk_setcmgr(this->hawk, cmgr);
 | |
| 	this->_cmgr = cmgr;
 | |
| }
 | |
| 
 | |
| void Hawk::uponClosing ()
 | |
| {
 | |
| 	// nothing to do
 | |
| }
 | |
| 
 | |
| void Hawk::uponClearing ()
 | |
| {
 | |
| 	// nothing to do
 | |
| }
 | |
| 
 | |
| Hawk::Run* Hawk::parse (Source& in, Source& out)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 
 | |
| 	if (&in == &Source::NONE)
 | |
| 	{
 | |
| 		this->setError(HAWK_EINVAL);
 | |
| 		return HAWK_NULL;
 | |
| 	}
 | |
| 
 | |
| 	this->fini_runctx();
 | |
| 
 | |
| 	source_reader = ∈
 | |
| 	source_writer = (&out == &Source::NONE)? HAWK_NULL: &out;
 | |
| 
 | |
| 	hawk_sio_cbs_t sio;
 | |
| 	sio.in = Hawk::readSource;
 | |
| 	sio.out = (source_writer == HAWK_NULL)? HAWK_NULL: Hawk::writeSource;
 | |
| 
 | |
| 	int n = hawk_parse(this->hawk, &sio);
 | |
| 	if (n <= -1)
 | |
| 	{
 | |
| 		this->retrieveError();
 | |
| 		return HAWK_NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (this->init_runctx() <= -1) return HAWK_NULL;
 | |
| 	return &this->runctx;
 | |
| }
 | |
| 
 | |
| Hawk::Run* Hawk::resetRunContext ()
 | |
| {
 | |
| 	if (this->runctx.rtx)
 | |
| 	{
 | |
| 		this->fini_runctx();
 | |
| 		if (this->init_runctx() <= -1) return HAWK_NULL;
 | |
| 		return &this->runctx;
 | |
| 	}
 | |
| 	else return HAWK_NULL;
 | |
| }
 | |
| 
 | |
| int Hawk::loop (Value* ret)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 	HAWK_ASSERT(this->runctx.rtx != HAWK_NULL);
 | |
| 
 | |
| 	hawk_val_t* rv = hawk_rtx_loop (this->runctx.rtx);
 | |
| 	if (rv == HAWK_NULL)
 | |
| 	{
 | |
| 		this->retrieveError(&this->runctx);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	ret->setVal(&this->runctx, rv);
 | |
| 	hawk_rtx_refdownval(this->runctx.rtx, rv);
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int Hawk::call (const hawk_bch_t* name, Value* ret, const Value* args, hawk_oow_t nargs)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 	HAWK_ASSERT(this->runctx.rtx != HAWK_NULL);
 | |
| 
 | |
| 	hawk_val_t* buf[16];
 | |
| 	hawk_val_t** ptr = HAWK_NULL;
 | |
| 
 | |
| 	if (args != HAWK_NULL)
 | |
| 	{
 | |
| 		if (nargs <= HAWK_COUNTOF(buf)) ptr = buf;
 | |
| 		else
 | |
| 		{
 | |
| 			ptr = (hawk_val_t**)hawk_allocmem(this->hawk, HAWK_SIZEOF(hawk_val_t*) * nargs);
 | |
| 			if (ptr == HAWK_NULL)
 | |
| 			{
 | |
| 				this->runctx.setError (HAWK_ENOMEM);
 | |
| 				this->retrieveError(&this->runctx);
 | |
| 				return -1;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		for (hawk_oow_t i = 0; i < nargs; i++) ptr[i] = (hawk_val_t*)args[i];
 | |
| 	}
 | |
| 
 | |
| 	hawk_val_t* rv = hawk_rtx_callwithbcstr(this->runctx.rtx, name, ptr, nargs);
 | |
| 
 | |
| 	if (ptr != HAWK_NULL && ptr != buf) hawk_freemem(this->hawk, ptr);
 | |
| 
 | |
| 	if (rv == HAWK_NULL)
 | |
| 	{
 | |
| 		this->retrieveError(&this->runctx);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	ret->setVal(&this->runctx, rv);
 | |
| 
 | |
| 	hawk_rtx_refdownval(this->runctx.rtx, rv);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int Hawk::call (const hawk_uch_t* name, Value* ret, const Value* args, hawk_oow_t nargs)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 	HAWK_ASSERT(this->runctx.rtx != HAWK_NULL);
 | |
| 
 | |
| 	hawk_val_t* buf[16];
 | |
| 	hawk_val_t** ptr = HAWK_NULL;
 | |
| 
 | |
| 	if (args != HAWK_NULL)
 | |
| 	{
 | |
| 		if (nargs <= HAWK_COUNTOF(buf)) ptr = buf;
 | |
| 		else
 | |
| 		{
 | |
| 			ptr = (hawk_val_t**)hawk_allocmem(this->hawk, HAWK_SIZEOF(hawk_val_t*) * nargs);
 | |
| 			if (ptr == HAWK_NULL)
 | |
| 			{
 | |
| 				this->runctx.setError(HAWK_ENOMEM);
 | |
| 				this->retrieveError(&this->runctx);
 | |
| 				return -1;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		for (hawk_oow_t i = 0; i < nargs; i++) ptr[i] = (hawk_val_t*)args[i];
 | |
| 	}
 | |
| 
 | |
| 	hawk_val_t* rv = hawk_rtx_callwithucstr(this->runctx.rtx, name, ptr, nargs);
 | |
| 
 | |
| 	if (ptr != HAWK_NULL && ptr != buf) hawk_freemem(this->hawk, ptr);
 | |
| 
 | |
| 	if (rv == HAWK_NULL)
 | |
| 	{
 | |
| 		this->retrieveError(&this->runctx);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	ret->setVal(&this->runctx, rv);
 | |
| 
 | |
| 	hawk_rtx_refdownval(this->runctx.rtx, rv);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int Hawk::exec (Value* ret, const Value* args, hawk_oow_t nargs)
 | |
| {
 | |
| 	int n = (this->runctx.rtx->hawk->parse.pragma.entry[0] != '\0')?
 | |
| 		this->call(this->runctx.rtx->hawk->parse.pragma.entry, ret, args, nargs): this->loop(ret);
 | |
| 
 | |
| #if defined(HAWK_ENABLE_GC)
 | |
|         /* i assume this function is a usual hawk program starter.
 | |
|          * call garbage collection after a whole program finishes */
 | |
|         hawk_rtx_gc(this->runctx.rtx, HAWK_RTX_GC_GEN_FULL);
 | |
| #endif
 | |
| 
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| void Hawk::halt ()
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 	hawk_haltall (this->hawk);
 | |
| }
 | |
| 
 | |
| int Hawk::init_runctx ()
 | |
| {
 | |
| 	if (this->runctx.rtx) return 0;
 | |
| 
 | |
| 	hawk_rio_cbs_t rio;
 | |
| 
 | |
| 	rio.pipe    = pipeHandler;
 | |
| 	rio.file    = fileHandler;
 | |
| 	rio.console = consoleHandler;
 | |
| 
 | |
| 	hawk_rtx_t* rtx = hawk_rtx_open(this->hawk, HAWK_SIZEOF(rxtn_t), &rio);
 | |
| 	if (HAWK_UNLIKELY(!rtx))
 | |
| 	{
 | |
| 		this->retrieveError();
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	rtx->_instsize += HAWK_SIZEOF(rxtn_t);
 | |
| 	this->runctx.rtx = rtx;
 | |
| 
 | |
| 	rxtn_t* rxtn = GET_RXTN(rtx);
 | |
| 	rxtn->run = &this->runctx;
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| void Hawk::fini_runctx ()
 | |
| {
 | |
| 	if (this->runctx.rtx)
 | |
| 	{
 | |
| 		hawk_rtx_close(this->runctx.rtx);
 | |
| 		this->runctx.rtx = HAWK_NULL;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| int Hawk::getTrait () const
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 	int val;
 | |
| 	hawk_getopt(this->hawk, HAWK_OPT_TRAIT, &val);
 | |
| 	return val;
 | |
| }
 | |
| 
 | |
| void Hawk::setTrait (int trait)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 	hawk_setopt (this->hawk, HAWK_OPT_TRAIT, &trait);
 | |
| }
 | |
| 
 | |
| hawk_oow_t Hawk::getMaxDepth (depth_t id) const
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 
 | |
| 	hawk_oow_t depth;
 | |
| 	hawk_getopt(this->hawk, (hawk_opt_t)id, &depth);
 | |
| 	return depth;
 | |
| }
 | |
| 
 | |
| void Hawk::setMaxDepth (depth_t id, hawk_oow_t depth)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 	hawk_setopt (this->hawk, (hawk_opt_t)id, &depth);
 | |
| }
 | |
| 
 | |
| int Hawk::setIncludeDirs (const hawk_uch_t* dirs)
 | |
| {
 | |
| #if defined(HAWK_OOCH_IS_UCH)
 | |
| 	return hawk_setopt(this->hawk, HAWK_OPT_INCLUDEDIRS, dirs);
 | |
| #else
 | |
| 	hawk_ooch_t* tmp;
 | |
| 	tmp = hawk_duputobcstr(hawk, dirs, HAWK_NULL);
 | |
| 	if (HAWK_UNLIKELY(!tmp)) return -1;
 | |
| 
 | |
| 	int n = hawk_setopt(hawk, HAWK_OPT_INCLUDEDIRS, tmp);
 | |
| 	hawk_freemem(hawk, tmp);
 | |
| 	return n;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| int Hawk::setIncludeDirs (const hawk_bch_t* dirs)
 | |
| {
 | |
| #if defined(HAWK_OOCH_IS_UCH)
 | |
| 	hawk_ooch_t* tmp;
 | |
| 	tmp = hawk_dupbtoucstr(hawk, dirs, HAWK_NULL, 1);
 | |
| 	if (HAWK_UNLIKELY(!tmp)) return -1;
 | |
| 
 | |
| 	int n = hawk_setopt(hawk, HAWK_OPT_INCLUDEDIRS, tmp);
 | |
| 	hawk_freemem(hawk, tmp);
 | |
| 	return n;
 | |
| #else
 | |
| 	return hawk_setopt(this->hawk, HAWK_OPT_INCLUDEDIRS, dirs);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| int Hawk::dispatch_function (Run* run, const hawk_fnc_info_t* fi)
 | |
| {
 | |
| 	bool has_ref_arg = false;
 | |
| 
 | |
| #if defined(HAWK_USE_HTB_FOR_FUNCTION_MAP)
 | |
| 	hawk_htb_pair_t* pair;
 | |
| 	pair = hawk_htb_search(this->functionMap, fi->name.ptr, fi->name.len);
 | |
| 	if (pair == HAWK_NULL)
 | |
| 	{
 | |
| 		run->formatError (HAWK_EFUNNF, HAWK_NULL, HAWK_T("function '%.*js' not defined"), &fi->name.len, &fi->name.ptr);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	FunctionHandler handler;
 | |
| 	handler = *(FunctionHandler*)HAWK_HTB_VPTR(pair);
 | |
| #else
 | |
| 	FunctionMap::Pair* pair = this->functionMap.search(Cstr(fi->name.ptr, fi->name.len));
 | |
| 	if (pair == HAWK_NULL)
 | |
| 	{
 | |
| 		run->formatError (HAWK_EFUNNF, HAWK_NULL, HAWK_T("function '%.*js' not defined"), &fi->name.len, &fi->name.ptr);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	FunctionHandler handler;
 | |
| 	handler = pair->value;
 | |
| #endif
 | |
| 
 | |
| 	hawk_oow_t i, nargs = hawk_rtx_getnargs(run->rtx);
 | |
| 
 | |
| 	Value buf[16];
 | |
| 	Value* args;
 | |
| 	if (nargs <= HAWK_COUNTOF(buf)) args = buf;
 | |
| 	else
 | |
| 	{
 | |
| 	#if defined(AWK_VALUE_USE_IN_CLASS_PLACEMENT_NEW)
 | |
| 		args = new(run) Value[nargs];
 | |
| 		if (args == HAWK_NULL)
 | |
| 		{
 | |
| 			run->setError(HAWK_ENOMEM);
 | |
| 			return -1;
 | |
| 		}
 | |
| 	#else
 | |
| 		try
 | |
| 		{
 | |
| 			//args = (Value*)::operator new (HAWK_SIZEOF(Value) * nargs, this->getMmgr());
 | |
| 			args = (Value*)this->getMmgr()->allocate(HAWK_SIZEOF(Value) * nargs);
 | |
| 		}
 | |
| 		catch (...) { args = HAWK_NULL; }
 | |
| 		if (args == HAWK_NULL)
 | |
| 		{
 | |
| 			run->setError(HAWK_ENOMEM);
 | |
| 			return -1;
 | |
| 		}
 | |
| 		for (i = 0; i < nargs; i++)
 | |
| 		{
 | |
| 			// call the default constructor on the space allocated above.
 | |
| 			// no exception handling is implemented here as i know
 | |
| 			// that Value::Value() doesn't throw an exception
 | |
| 			new((HAWK::Mmgr*)HAWK_NULL, (void*)&args[i]) Value ();
 | |
| 		}
 | |
| 	#endif
 | |
| 	}
 | |
| 
 | |
| 	for (i = 0; i < nargs; i++)
 | |
| 	{
 | |
| 		int xx;
 | |
| 		hawk_val_t* v = hawk_rtx_getarg (run->rtx, i);
 | |
| 
 | |
| 		if (HAWK_RTX_GETVALTYPE (run->rtx, v) == HAWK_VAL_REF)
 | |
| 		{
 | |
| 			hawk_val_ref_t* ref = (hawk_val_ref_t*)v;
 | |
| 
 | |
| 			switch (ref->id)
 | |
| 			{
 | |
| 				case hawk_val_ref_t::HAWK_VAL_REF_POS:
 | |
| 				{
 | |
| 					hawk_oow_t idx = (hawk_oow_t)ref->adr;
 | |
| 
 | |
| 					if (idx == 0)
 | |
| 					{
 | |
| 						xx = args[i].setStr(run, HAWK_OOECS_PTR(&run->rtx->inrec.line), HAWK_OOECS_LEN(&run->rtx->inrec.line));
 | |
| 					}
 | |
| 					else if (idx <= run->rtx->inrec.nflds)
 | |
| 					{
 | |
| 						xx = args[i].setStr (run,
 | |
| 							run->rtx->inrec.flds[idx-1].ptr,
 | |
| 							run->rtx->inrec.flds[idx-1].len);
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						xx = args[i].setStr (run, HAWK_T(""), (hawk_oow_t)0);
 | |
| 					}
 | |
| 					break;
 | |
| 				}
 | |
| 
 | |
| 				case hawk_val_ref_t::HAWK_VAL_REF_GBL:
 | |
| 				{
 | |
| 					hawk_oow_t idx = (hawk_oow_t)ref->adr;
 | |
| 					hawk_val_t* val = (hawk_val_t*)HAWK_RTX_STACK_GBL(run->rtx, idx);
 | |
| 					xx = args[i].setVal (run, val);
 | |
| 					break;
 | |
| 				}
 | |
| 
 | |
| 				default:
 | |
| 					xx = args[i].setVal (run, *(ref->adr));
 | |
| 					break;
 | |
| 			}
 | |
| 			has_ref_arg = true;
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			xx = args[i].setVal (run, v);
 | |
| 		}
 | |
| 
 | |
| 		if (xx <= -1)
 | |
| 		{
 | |
| 			run->setError(HAWK_ENOMEM);
 | |
| 			if (args != buf) delete[] args;
 | |
| 			return -1;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	Value ret (run);
 | |
| 
 | |
| 	int n;
 | |
| 
 | |
| 	try { n = (this->*handler) (*run, ret, args, nargs, fi); }
 | |
| 	catch (...) { n = -1; }
 | |
| 
 | |
| 	if (n >= 0 && has_ref_arg)
 | |
| 	{
 | |
| 		for (i = 0; i < nargs; i++)
 | |
| 		{
 | |
| 			// Do NOT change the run field from function handler
 | |
| 			HAWK_ASSERT(args[i].run == run);
 | |
| 
 | |
| 			hawk_val_t* v = hawk_rtx_getarg(run->rtx, i);
 | |
| 			if (HAWK_RTX_GETVALTYPE(run->rtx, v) == HAWK_VAL_REF)
 | |
| 			{
 | |
| 				if (hawk_rtx_setrefval(run->rtx, (hawk_val_ref_t*)v, args[i].toVal()) <= -1)
 | |
| 				{
 | |
| 					n = -1;
 | |
| 					break;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if (args != buf)
 | |
| 	{
 | |
| 	#if defined(AWK_VALUE_USE_IN_CLASS_PLACEMENT_NEW)
 | |
| 		delete[] args;
 | |
| 	#else
 | |
| 		for (i = nargs; i > 0; )
 | |
| 		{
 | |
| 			--i;
 | |
| 			args[i].Value::~Value ();
 | |
| 		}
 | |
| 
 | |
| 		//::operator delete (args, this->getMmgr());
 | |
| 		this->getMmgr()->dispose (args);
 | |
| 	#endif
 | |
| 	}
 | |
| 
 | |
| 	if (n <= -1)
 | |
| 	{
 | |
| 		/* this is really the handler error. the underlying engine
 | |
| 		 * will take care of the error code. */
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	hawk_rtx_setretval (run->rtx, ret.toVal());
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int Hawk::xstrs_t::add (hawk_t* hawk, const hawk_uch_t* arg, hawk_oow_t len)
 | |
| {
 | |
| 	if (this->len >= this->capa)
 | |
| 	{
 | |
| 		hawk_oocs_t* ptr;
 | |
| 		hawk_oow_t capa = this->capa;
 | |
| 
 | |
| 		capa += 64;
 | |
| 		ptr = (hawk_oocs_t*)hawk_reallocmem(hawk, this->ptr, HAWK_SIZEOF(hawk_oocs_t)*(capa + 1));
 | |
| 		if (HAWK_UNLIKELY(!ptr)) return -1;
 | |
| 
 | |
| 		this->ptr = ptr;
 | |
| 		this->capa = capa;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| #if defined(HAWK_OOCH_IS_UCH)
 | |
| 	this->ptr[this->len].len = len;
 | |
| 	this->ptr[this->len].ptr = hawk_dupuchars(hawk, arg, len);
 | |
| #else
 | |
| 	this->ptr[this->len].ptr = hawk_duputobchars(hawk, arg, len, &this->ptr[this->len].len);
 | |
| #endif
 | |
| 	if (this->ptr[this->len].ptr == HAWK_NULL) return -1;
 | |
| 
 | |
| 	this->len++;
 | |
| 	this->ptr[this->len].len = 0;
 | |
| 	this->ptr[this->len].ptr = HAWK_NULL;
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int Hawk::xstrs_t::add (hawk_t* hawk, const hawk_bch_t* arg, hawk_oow_t len)
 | |
| {
 | |
| 	if (this->len >= this->capa)
 | |
| 	{
 | |
| 		hawk_oocs_t* ptr;
 | |
| 		hawk_oow_t capa = this->capa;
 | |
| 
 | |
| 		capa += 64;
 | |
| 		ptr = (hawk_oocs_t*)hawk_reallocmem(hawk, this->ptr, HAWK_SIZEOF(hawk_oocs_t)*(capa + 1));
 | |
| 		if (HAWK_UNLIKELY(!ptr)) return -1;
 | |
| 
 | |
| 		this->ptr = ptr;
 | |
| 		this->capa = capa;
 | |
| 	}
 | |
| 
 | |
| #if defined(HAWK_OOCH_IS_UCH)
 | |
| 	this->ptr[this->len].ptr = hawk_dupbtouchars(hawk, arg, len, &this->ptr[this->len].len, 0);
 | |
| #else
 | |
| 	this->ptr[this->len].len = len;
 | |
| 	this->ptr[this->len].ptr = hawk_dupbchars(hawk, arg, len);
 | |
| #endif
 | |
| 	if (this->ptr[this->len].ptr == HAWK_NULL) return -1;
 | |
| 
 | |
| 	this->len++;
 | |
| 	this->ptr[this->len].len = 0;
 | |
| 	this->ptr[this->len].ptr = HAWK_NULL;
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| void Hawk::xstrs_t::clear (hawk_t* hawk)
 | |
| {
 | |
| 	if (this->ptr != HAWK_NULL)
 | |
| 	{
 | |
| 		while (this->len > 0) hawk_freemem(hawk, this->ptr[--this->len].ptr);
 | |
| 
 | |
| 		hawk_freemem(hawk, this->ptr);
 | |
| 		this->ptr = HAWK_NULL;
 | |
| 		this->capa = 0;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| int Hawk::addArgument (const hawk_uch_t* arg, hawk_oow_t len)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 	int n = this->runarg.add(this->hawk, arg, len);
 | |
| 	if (n <= -1) this->setError(HAWK_ENOMEM);
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::addArgument (const hawk_uch_t* arg)
 | |
| {
 | |
| 	return this->addArgument(arg, hawk_count_ucstr(arg));
 | |
| }
 | |
| 
 | |
| int Hawk::addArgument (const hawk_bch_t* arg, hawk_oow_t len)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 	int n = this->runarg.add(this->hawk, arg, len);
 | |
| 	if (n <= -1) this->setError(HAWK_ENOMEM);
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::addArgument (const hawk_bch_t* arg)
 | |
| {
 | |
| 	return this->addArgument(arg, hawk_count_bcstr(arg));
 | |
| }
 | |
| 
 | |
| void Hawk::clearArguments ()
 | |
| {
 | |
| 	this->runarg.clear (this->hawk);
 | |
| }
 | |
| 
 | |
| int Hawk::addGlobal(const hawk_bch_t* name)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 	int n = hawk_addgblwithbcstr(this->hawk, name);
 | |
| 	if (n <= -1) this->retrieveError();
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::addGlobal(const hawk_uch_t* name)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 	int n = hawk_addgblwithucstr(this->hawk, name);
 | |
| 	if (n <= -1) this->retrieveError();
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::deleteGlobal (const hawk_bch_t* name)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 	int n = hawk_delgblwithbcstr(this->hawk, name);
 | |
| 	if (n <= -1) this->retrieveError();
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::deleteGlobal (const hawk_uch_t* name)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 	int n = hawk_delgblwithucstr(this->hawk, name);
 | |
| 	if (n <= -1) this->retrieveError();
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| 
 | |
| int Hawk::findGlobal (const hawk_bch_t* name, bool inc_builtins)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 	int n = hawk_findgblwithbcstr(this->hawk, name, inc_builtins);
 | |
| 	if (n <= -1) this->retrieveError();
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::findGlobal (const hawk_uch_t* name, bool inc_builtins)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 	int n = hawk_findgblwithucstr(this->hawk, name, inc_builtins);
 | |
| 	if (n <= -1) this->retrieveError();
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::setGlobal (int id, const Value& v)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 	HAWK_ASSERT(this->runctx.rtx != HAWK_NULL);
 | |
| 
 | |
| 	if (v.run != &this->runctx)
 | |
| 	{
 | |
| 		this->setError(HAWK_EINVAL);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	int n = this->runctx.setGlobal(id, v);
 | |
| 	if (n <= -1) this->retrieveError();
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::getGlobal (int id, Value& v)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 	HAWK_ASSERT(runctx.rtx != HAWK_NULL);
 | |
| 
 | |
| 	int n = runctx.getGlobal (id, v);
 | |
| 	if (n <= -1) this->retrieveError();
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| int Hawk::addFunction (
 | |
| 	const hawk_bch_t* name, hawk_oow_t minArgs, hawk_oow_t maxArgs,
 | |
| 	const hawk_bch_t* argSpec, FunctionHandler handler, int validOpts)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 
 | |
| 	hawk_fnc_mspec_t spec;
 | |
| 
 | |
| 	HAWK_MEMSET (&spec, 0, HAWK_SIZEOF(spec));
 | |
| 	spec.arg.min = minArgs;
 | |
| 	spec.arg.max = maxArgs;
 | |
| 	spec.arg.spec = argSpec;
 | |
| 	spec.impl = this->functionHandler;
 | |
| 	spec.trait = validOpts;
 | |
| 
 | |
| 	hawk_fnc_t* fnc = hawk_addfncwithbcstr(this->hawk, name, &spec);
 | |
| 	if (fnc == HAWK_NULL)
 | |
| 	{
 | |
| 		this->retrieveError();
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| #if defined(HAWK_USE_HTB_FOR_FUNCTION_MAP)
 | |
| 	// handler is a pointer to a member function.
 | |
| 	// sizeof(handler) is likely to be greater than sizeof(void*)
 | |
| 	// copy the handler pointer into the table.
 | |
| 	//
 | |
| 	// the function name exists in the underlying function table.
 | |
| 	// use the pointer to the name to maintain the hash table.
 | |
| 	hawk_htb_pair_t* pair = hawk_htb_upsert(this->functionMap, (hawk_ooch_t*)fnc->name.ptr, fnc->name.len, &handler, HAWK_SIZEOF(handler));
 | |
| 	if (!pair)
 | |
| 	{
 | |
| 		hawk_delfncwithbcstr (this->hawk, name);
 | |
| 		this->retrieveError();
 | |
| 		return -1;
 | |
| 	}
 | |
| #else
 | |
| 	FunctionMap::Pair* pair;
 | |
| 	try { pair = this->functionMap.upsert(Cstr(fnc->name.ptr, fnc->name.len), handler); }
 | |
| 	catch (...) { pair = HAWK_NULL; }
 | |
| 	if (!pair)
 | |
| 	{
 | |
| 		hawk_delfncwithbcstr (this->hawk, name);
 | |
| 		this->setError(HAWK_ENOMEM);
 | |
| 		return -1;
 | |
| 	}
 | |
| #endif
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int Hawk::addFunction (
 | |
| 	const hawk_uch_t* name, hawk_oow_t minArgs, hawk_oow_t maxArgs,
 | |
| 	const hawk_uch_t* argSpec, FunctionHandler handler, int validOpts)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 
 | |
| 	hawk_fnc_wspec_t spec;
 | |
| 
 | |
| 	HAWK_MEMSET (&spec, 0, HAWK_SIZEOF(spec));
 | |
| 	spec.arg.min = minArgs;
 | |
| 	spec.arg.max = maxArgs;
 | |
| 	spec.arg.spec = argSpec;
 | |
| 	spec.impl = this->functionHandler;
 | |
| 	spec.trait = validOpts;
 | |
| 
 | |
| 	hawk_fnc_t* fnc = hawk_addfncwithucstr(this->hawk, name, &spec);
 | |
| 	if (HAWK_UNLIKELY(!fnc))
 | |
| 	{
 | |
| 		this->retrieveError();
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| #if defined(HAWK_USE_HTB_FOR_FUNCTION_MAP)
 | |
| 	// handler is a pointer to a member function.
 | |
| 	// sizeof(handler) is likely to be greater than sizeof(void*)
 | |
| 	// copy the handler pointer into the table.
 | |
| 	//
 | |
| 	// the function name exists in the underlying function table.
 | |
| 	// use the pointer to the name to maintain the hash table.
 | |
| 	hawk_htb_pair_t* pair = hawk_htb_upsert(this->functionMap, (hawk_ooch_t*)fnc->name.ptr, fnc->name.len, &handler, HAWK_SIZEOF(handler));
 | |
| 	if (HAWK_UNLIKELY(!pair))
 | |
| 	{
 | |
| 		hawk_delfncwithucstr (this->hawk, name);
 | |
| 		this->retrieveError();
 | |
| 		return -1;
 | |
| 	}
 | |
| #else
 | |
| 	FunctionMap::Pair* pair;
 | |
| 	try { pair = this->functionMap.upsert(Cstr(fnc->name.ptr, fnc->name.len), handler); }
 | |
| 	catch (...) { pair = HAWK_NULL; }
 | |
| 	if (HAWK_UNLIKELY(!pair))
 | |
| 	{
 | |
| 		hawk_delfncwithucstr (this->hawk, name);
 | |
| 		this->setError(HAWK_ENOMEM);
 | |
| 		return -1;
 | |
| 	}
 | |
| #endif
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int Hawk::deleteFunction (const hawk_ooch_t* name)
 | |
| {
 | |
| 	HAWK_ASSERT(this->hawk != HAWK_NULL);
 | |
| 
 | |
| 	int n = hawk_delfnc(this->hawk, name);
 | |
| 	if (n == 0)
 | |
| 	{
 | |
| #if defined(HAWK_USE_HTB_FOR_FUNCTION_MAP)
 | |
| 		hawk_htb_delete (this->functionMap, name, hawk_count_oocstr(name));
 | |
| #else
 | |
| 		this->functionMap.remove (Cstr(name));
 | |
| #endif
 | |
| 	}
 | |
| 	else this->retrieveError();
 | |
| 
 | |
| 	return n;
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::readSource (hawk_t* hawk, hawk_sio_cmd_t cmd, hawk_sio_arg_t* arg, hawk_ooch_t* data, hawk_oow_t count)
 | |
| {
 | |
| 	xtn_t* xtn = GET_XTN(hawk);
 | |
| 	Source::Data sdat(xtn->hawk, Source::READ, arg);
 | |
| 
 | |
| 	switch (cmd)
 | |
| 	{
 | |
| 		case HAWK_SIO_CMD_OPEN:
 | |
| 			return xtn->hawk->source_reader->open(sdat);
 | |
| 		case HAWK_SIO_CMD_CLOSE:
 | |
| 			return xtn->hawk->source_reader->close(sdat);
 | |
| 		case HAWK_SIO_CMD_READ:
 | |
| 			return xtn->hawk->source_reader->read(sdat, data, count);
 | |
| 		default:
 | |
| 			hawk_seterrnum(hawk, HAWK_NULL, HAWK_EINTERN);
 | |
| 			return -1;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::writeSource (hawk_t* hawk, hawk_sio_cmd_t cmd, hawk_sio_arg_t* arg, hawk_ooch_t* data, hawk_oow_t count)
 | |
| {
 | |
| 	xtn_t* xtn = GET_XTN(hawk);
 | |
| 	Source::Data sdat (xtn->hawk, Source::WRITE, arg);
 | |
| 
 | |
| 	switch (cmd)
 | |
| 	{
 | |
| 		case HAWK_SIO_CMD_OPEN:
 | |
| 			return xtn->hawk->source_writer->open (sdat);
 | |
| 		case HAWK_SIO_CMD_CLOSE:
 | |
| 			return xtn->hawk->source_writer->close(sdat);
 | |
| 		case HAWK_SIO_CMD_WRITE:
 | |
| 			return xtn->hawk->source_writer->write (sdat, data, count);
 | |
| 		default:
 | |
| 			hawk_seterrnum(hawk, HAWK_NULL, HAWK_EINTERN);
 | |
| 			return -1;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::pipeHandler (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_rio_arg_t* riod, void* data, hawk_oow_t count)
 | |
| {
 | |
| 	rxtn_t* rxtn = GET_RXTN(rtx);
 | |
| 	Hawk* hawk = rxtn->run->hawk;
 | |
| 
 | |
| 	HAWK_ASSERT((riod->type & 0xFF) == HAWK_RIO_PIPE);
 | |
| 
 | |
| 	Pipe pipe (rxtn->run, riod);
 | |
| 
 | |
| 	try
 | |
| 	{
 | |
| 		if (hawk->pipe_handler)
 | |
| 		{
 | |
| 			switch (cmd)
 | |
| 			{
 | |
| 				case HAWK_RIO_CMD_OPEN:
 | |
| 					return hawk->pipe_handler->open(pipe);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_CLOSE:
 | |
| 					return hawk->pipe_handler->close(pipe);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_READ:
 | |
| 					return hawk->pipe_handler->read(pipe, (hawk_ooch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_READ_BYTES:
 | |
| 					return hawk->pipe_handler->readBytes(pipe, (hawk_bch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_WRITE:
 | |
| 					return hawk->pipe_handler->write(pipe, (const hawk_ooch_t*)data, count);
 | |
| 				case HAWK_RIO_CMD_WRITE_BYTES:
 | |
| 					return hawk->pipe_handler->writeBytes(pipe, (const hawk_bch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_FLUSH:
 | |
| 					return hawk->pipe_handler->flush(pipe);
 | |
| 
 | |
| 				default:
 | |
| 					hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
 | |
| 					return -1;
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			switch (cmd)
 | |
| 			{
 | |
| 				case HAWK_RIO_CMD_OPEN:
 | |
| 					return hawk->openPipe(pipe);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_CLOSE:
 | |
| 					return hawk->closePipe(pipe);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_READ:
 | |
| 					return hawk->readPipe(pipe, (hawk_ooch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_READ_BYTES:
 | |
| 					return hawk->readPipeBytes(pipe, (hawk_bch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_WRITE:
 | |
| 					return hawk->writePipe(pipe, (const hawk_ooch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_WRITE_BYTES:
 | |
| 					return hawk->writePipeBytes(pipe, (const hawk_bch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_FLUSH:
 | |
| 					return hawk->flushPipe(pipe);
 | |
| 
 | |
| 				default:
 | |
| 					hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
 | |
| 					return -1;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	catch (...)
 | |
| 	{
 | |
| 		return -1;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::fileHandler (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_rio_arg_t* riod, void* data, hawk_oow_t count)
 | |
| {
 | |
| 	rxtn_t* rxtn = GET_RXTN(rtx);
 | |
| 	Hawk* hawk = rxtn->run->hawk;
 | |
| 
 | |
| 	HAWK_ASSERT((riod->type & 0xFF) == HAWK_RIO_FILE);
 | |
| 
 | |
| 	File file (rxtn->run, riod);
 | |
| 
 | |
| 	try
 | |
| 	{
 | |
| 		if (hawk->file_handler)
 | |
| 		{
 | |
| 			switch (cmd)
 | |
| 			{
 | |
| 				case HAWK_RIO_CMD_OPEN:
 | |
| 					return hawk->file_handler->open(file);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_CLOSE:
 | |
| 					return hawk->file_handler->close(file);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_READ:
 | |
| 					return hawk->file_handler->read(file, (hawk_ooch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_READ_BYTES:
 | |
| 					return hawk->file_handler->readBytes(file, (hawk_bch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_WRITE:
 | |
| 					return hawk->file_handler->write(file, (const hawk_ooch_t*)data, count);
 | |
| 				case HAWK_RIO_CMD_WRITE_BYTES:
 | |
| 					return hawk->file_handler->writeBytes(file, (const hawk_bch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_FLUSH:
 | |
| 					return hawk->file_handler->flush(file);
 | |
| 
 | |
| 				default:
 | |
| 					hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
 | |
| 					return -1;
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			switch (cmd)
 | |
| 			{
 | |
| 				case HAWK_RIO_CMD_OPEN:
 | |
| 					return hawk->openFile(file);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_CLOSE:
 | |
| 					return hawk->closeFile(file);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_READ:
 | |
| 					return hawk->readFile(file, (hawk_ooch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_READ_BYTES:
 | |
| 					return hawk->readFileBytes(file, (hawk_bch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_WRITE:
 | |
| 					return hawk->writeFile(file, (const hawk_ooch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_WRITE_BYTES:
 | |
| 					return hawk->writeFileBytes(file, (const hawk_bch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_FLUSH:
 | |
| 					return hawk->flushFile(file);
 | |
| 
 | |
| 				default:
 | |
| 					hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
 | |
| 					return -1;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	catch (...)
 | |
| 	{
 | |
| 		return -1;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::consoleHandler (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_rio_arg_t* riod, void* data, hawk_oow_t count)
 | |
| {
 | |
| 	rxtn_t* rxtn = GET_RXTN(rtx);
 | |
| 	Hawk* hawk = rxtn->run->hawk;
 | |
| 
 | |
| 	HAWK_ASSERT((riod->type & 0xFF) == HAWK_RIO_CONSOLE);
 | |
| 
 | |
| 	Console console(rxtn->run, riod);
 | |
| 
 | |
| 	try
 | |
| 	{
 | |
| 		if (hawk->console_handler)
 | |
| 		{
 | |
| 			switch (cmd)
 | |
| 			{
 | |
| 				case HAWK_RIO_CMD_OPEN:
 | |
| 					return hawk->console_handler->open(console);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_CLOSE:
 | |
| 					return hawk->console_handler->close(console);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_READ:
 | |
| 					return hawk->console_handler->read(console, (hawk_ooch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_READ_BYTES:
 | |
| 					return hawk->console_handler->readBytes(console, (hawk_bch_t*)data, count);
 | |
| 				case HAWK_RIO_CMD_WRITE:
 | |
| 					return hawk->console_handler->write(console, (const hawk_ooch_t*)data, count);
 | |
| 				case HAWK_RIO_CMD_WRITE_BYTES:
 | |
| 					return hawk->console_handler->writeBytes(console, (const hawk_bch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_FLUSH:
 | |
| 					return hawk->console_handler->flush(console);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_NEXT:
 | |
| 					return hawk->console_handler->next(console);
 | |
| 
 | |
| 				default:
 | |
| 					hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
 | |
| 					return -1;
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			switch (cmd)
 | |
| 			{
 | |
| 				case HAWK_RIO_CMD_OPEN:
 | |
| 					return hawk->openConsole(console);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_CLOSE:
 | |
| 					return hawk->closeConsole(console);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_READ:
 | |
| 					return hawk->readConsole(console, (hawk_ooch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_READ_BYTES:
 | |
| 					return hawk->readConsoleBytes(console, (hawk_bch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_WRITE:
 | |
| 					return hawk->writeConsole(console, (const hawk_ooch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_WRITE_BYTES:
 | |
| 					return hawk->writeConsoleBytes(console, (const hawk_bch_t*)data, count);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_FLUSH:
 | |
| 					return hawk->flushConsole(console);
 | |
| 
 | |
| 				case HAWK_RIO_CMD_NEXT:
 | |
| 					return hawk->nextConsole(console);
 | |
| 
 | |
| 				default:
 | |
| 					hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
 | |
| 					return -1;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	catch (...)
 | |
| 	{
 | |
| 		return -1;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| int Hawk::openPipe (Pipe& io)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| int Hawk::closePipe (Pipe& io)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::readPipe (Pipe& io, hawk_ooch_t* buf, hawk_oow_t len)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::readPipeBytes (Pipe& io, hawk_bch_t* buf, hawk_oow_t len)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::writePipe (Pipe& io, const hawk_ooch_t* buf, hawk_oow_t len)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::writePipeBytes (Pipe& io, const hawk_bch_t* buf, hawk_oow_t len)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| int Hawk::flushPipe (Pipe& io)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| int Hawk::openFile  (File& io)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| int Hawk::closeFile (File& io)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::readFile (File& io, hawk_ooch_t* buf, hawk_oow_t len)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::readFileBytes (File& io, hawk_bch_t* buf, hawk_oow_t len)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::writeFile (File& io, const hawk_ooch_t* buf, hawk_oow_t len)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::writeFileBytes (File& io, const hawk_bch_t* buf, hawk_oow_t len)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| int Hawk::flushFile (File& io)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| int Hawk::openConsole  (Console& io)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| int Hawk::closeConsole (Console& io)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::readConsole (Console& io, hawk_ooch_t* buf, hawk_oow_t len)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::readConsoleBytes (Console& io, hawk_bch_t* buf, hawk_oow_t len)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::writeConsole (Console& io, const hawk_ooch_t* buf, hawk_oow_t len)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| hawk_ooi_t Hawk::writeConsoleBytes (Console& io, const hawk_bch_t* buf, hawk_oow_t len)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| int Hawk::flushConsole (Console& io)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| int Hawk::nextConsole (Console& io)
 | |
| {
 | |
| 	((Run*)io)->setError(HAWK_ENOIMPL);
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| int Hawk::functionHandler (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
 | |
| {
 | |
| 	rxtn_t* rxtn = GET_RXTN(rtx);
 | |
| 	return rxtn->run->hawk->dispatch_function(rxtn->run, fi);
 | |
| }
 | |
| 
 | |
| hawk_flt_t Hawk::pow (hawk_t* hawk, hawk_flt_t x, hawk_flt_t y)
 | |
| {
 | |
| 	xtn_t* xtn = GET_XTN(hawk);
 | |
| 	return xtn->hawk->pow(x, y);
 | |
| }
 | |
| 
 | |
| hawk_flt_t Hawk::mod (hawk_t* hawk, hawk_flt_t x, hawk_flt_t y)
 | |
| {
 | |
| 	xtn_t* xtn = GET_XTN(hawk);
 | |
| 	return xtn->hawk->mod(x, y);
 | |
| }
 | |
| 
 | |
| void* Hawk::modopen (hawk_t* hawk, const hawk_mod_spec_t* spec)
 | |
| {
 | |
| 	xtn_t* xtn = GET_XTN(hawk);
 | |
| 	return xtn->hawk->modopen(spec);
 | |
| }
 | |
| 
 | |
| void Hawk::modclose (hawk_t* hawk, void* handle)
 | |
| {
 | |
| 	xtn_t* xtn = GET_XTN(hawk);
 | |
| 	xtn->hawk->modclose(handle);
 | |
| }
 | |
| 
 | |
| void* Hawk::modgetsym (hawk_t* hawk, void* handle, const hawk_ooch_t* name)
 | |
| {
 | |
| 	xtn_t* xtn = GET_XTN(hawk);
 | |
| 	return xtn->hawk->modgetsym(handle, name);
 | |
| }
 | |
| /////////////////////////////////
 | |
| HAWK_END_NAMESPACE(HAWK)
 | |
| /////////////////////////////////
 | |
| 
 | |
| 
 | |
| 
 | |
| void* operator new (hawk_oow_t size, HAWK::Mmgr* mmgr) /*HAWK_CXX_THREXCEPT1(HAWK::Mmgr::MemoryError)*/
 | |
| {
 | |
| 	return mmgr->allocate(size);
 | |
| }
 | |
| 
 | |
| #if defined(HAWK_CXX_NO_OPERATOR_DELETE_OVERLOADING)
 | |
| void hawk_operator_delete (void* ptr, HAWK::Mmgr* mmgr)
 | |
| #else
 | |
| void operator delete (void* ptr, HAWK::Mmgr* mmgr)
 | |
| #endif
 | |
| {
 | |
| 	mmgr->dispose (ptr);
 | |
| }
 | |
| 
 | |
| void* operator new (hawk_oow_t size, HAWK::Mmgr* mmgr, void* existing_ptr) /*HAWK_CXX_THREXCEPT1(HAWK::Mmgr::MemoryError)*/
 | |
| {
 | |
| 	// mmgr unused. i put it in the parameter list to make this function
 | |
| 	// less conflicting with the stock ::operator new() that doesn't allocate.
 | |
| 	return existing_ptr;
 | |
| }
 | |
| 
 | |
| #if 0
 | |
| void* operator new[] (hawk_oow_t size, HAWK::Mmgr* mmgr)
 | |
| {
 | |
| 	return mmgr->allocate(size);
 | |
| }
 | |
| 
 | |
| void operator delete[] (void* ptr, HAWK::Mmgr* mmgr)
 | |
| {
 | |
| 	mmgr->dispose (ptr);
 | |
| }
 | |
| #endif
 |