2007-12-30 17:41:49 +01:00
|
|
|
/***************************************************************************
|
|
|
|
|
2009-08-17 12:41:51 +02:00
|
|
|
gbx_exec_pop.c
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-12-31 03:39:20 +01:00
|
|
|
(c) 2000-2012 Benoît Minisini <gambas@users.sourceforge.net>
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
2009-08-17 12:41:51 +02:00
|
|
|
the Free Software Foundation; either version 2, or (at your option)
|
2007-12-30 17:41:49 +01:00
|
|
|
any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
2011-06-03 02:51:09 +02:00
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
2011-12-31 03:39:20 +01:00
|
|
|
MA 02110-1301, USA.
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#include "gb_common.h"
|
|
|
|
#include "gb_limit.h"
|
|
|
|
#include "gbx_exec.h"
|
|
|
|
|
|
|
|
#include "gbx_string.h"
|
|
|
|
#include "gbx_object.h"
|
2008-01-24 02:36:20 +01:00
|
|
|
#include "gbx_c_array.h"
|
2007-12-30 17:41:49 +01:00
|
|
|
#include "gbx_c_collection.h"
|
2008-01-24 11:42:42 +01:00
|
|
|
#include "gbx_api.h"
|
2010-05-25 13:19:00 +02:00
|
|
|
#include "gbx_struct.h"
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
|
2008-01-17 22:39:26 +01:00
|
|
|
void EXEC_pop_unknown(void)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2010-05-25 13:19:00 +02:00
|
|
|
static void *jump[] = {
|
2007-12-30 17:41:49 +01:00
|
|
|
/* 0 */ &&_POP_GENERIC,
|
|
|
|
/* 1 */ &&_POP_VARIABLE,
|
|
|
|
/* 2 */ &&_POP_STATIC_VARIABLE,
|
|
|
|
/* 3 */ &&_POP_PROPERTY,
|
|
|
|
/* 4 */ &&_POP_VARIABLE_AUTO,
|
2010-05-25 13:19:00 +02:00
|
|
|
/* 5 */ &&_POP_PROPERTY_AUTO,
|
|
|
|
/* 6 */ &&_POP_STRUCT_FIELD
|
2007-12-30 17:41:49 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
const char *name;
|
2008-01-17 22:39:26 +01:00
|
|
|
int index;
|
2007-12-30 17:41:49 +01:00
|
|
|
CLASS_DESC *desc;
|
|
|
|
CLASS *class;
|
|
|
|
OBJECT *object;
|
|
|
|
char *addr;
|
2009-07-08 21:57:50 +02:00
|
|
|
bool defined;
|
2007-12-30 17:41:49 +01:00
|
|
|
VALUE *val;
|
|
|
|
|
2010-05-28 08:24:14 +02:00
|
|
|
defined = EXEC_object(&SP[-1], &class, &object);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
/*printf("> exec_pop_unknown: SP = %p -> %p\n", SP, SP->_string.addr);*/
|
|
|
|
|
|
|
|
goto *jump[*PC & 0xF];
|
|
|
|
|
|
|
|
|
|
|
|
_POP_GENERIC:
|
|
|
|
|
|
|
|
name = CP->load->unknown[PC[1]];
|
|
|
|
|
|
|
|
// The first time we access a symbol, we must not be virtual to find it
|
|
|
|
val = &SP[-1];
|
2010-05-19 22:18:23 +02:00
|
|
|
if (LIKELY(defined && object && !VALUE_is_super(val)))
|
2007-12-30 17:41:49 +01:00
|
|
|
index = CLASS_find_symbol(val->_object.class, name);
|
|
|
|
else
|
|
|
|
index = CLASS_find_symbol(class, name);
|
|
|
|
|
2010-05-19 22:18:23 +02:00
|
|
|
if (UNLIKELY(index == NO_SYMBOL))
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2009-08-05 18:14:08 +02:00
|
|
|
if (class->special[SPEC_UNKNOWN] == NO_SYMBOL)
|
|
|
|
{
|
|
|
|
if (defined && object && !VALUE_is_super(val))
|
|
|
|
class = val->_object.class;
|
2012-10-19 23:00:35 +02:00
|
|
|
THROW(E_NSYMBOL, CLASS_get_name(class), name);
|
2009-08-05 18:14:08 +02:00
|
|
|
}
|
|
|
|
goto _POP_UNKNOWN_PROPERTY;
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
desc = class->table[index].desc;
|
|
|
|
|
|
|
|
switch (CLASS_DESC_get_type(desc))
|
|
|
|
{
|
|
|
|
case CD_CONSTANT:
|
|
|
|
|
2012-10-19 23:00:35 +02:00
|
|
|
THROW(E_NPROPERTY, CLASS_get_name(class), name);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
case CD_VARIABLE:
|
|
|
|
|
|
|
|
if (object == NULL)
|
|
|
|
{
|
2010-05-19 22:18:23 +02:00
|
|
|
if (UNLIKELY(!class->auto_create))
|
2012-10-19 23:00:35 +02:00
|
|
|
THROW(E_DYNAMIC, CLASS_get_name(class), name);
|
2007-12-30 17:41:49 +01:00
|
|
|
object = EXEC_auto_create(class, TRUE);
|
|
|
|
*PC |= 4;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (defined) *PC |= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (defined)
|
|
|
|
PC[1] = index;
|
|
|
|
|
|
|
|
goto _POP_VARIABLE_2;
|
|
|
|
|
2010-05-25 13:19:00 +02:00
|
|
|
case CD_STRUCT_FIELD:
|
|
|
|
|
|
|
|
if (object == NULL)
|
2012-10-19 23:00:35 +02:00
|
|
|
THROW(E_DYNAMIC, CLASS_get_name(class), name);
|
2010-05-25 13:19:00 +02:00
|
|
|
|
|
|
|
if (defined)
|
|
|
|
{
|
|
|
|
*PC |= 6;
|
|
|
|
PC[1] = index;
|
|
|
|
}
|
|
|
|
|
2010-07-08 00:06:05 +02:00
|
|
|
if (desc->variable.ctype.id == TC_STRUCT || desc->variable.ctype.id == TC_ARRAY)
|
2012-10-19 23:00:35 +02:00
|
|
|
THROW(E_NWRITE, CLASS_get_name(class), name);
|
2010-07-08 00:06:05 +02:00
|
|
|
|
2010-05-25 13:19:00 +02:00
|
|
|
goto _POP_STRUCT_FIELD_2;
|
|
|
|
|
2007-12-30 17:41:49 +01:00
|
|
|
case CD_STATIC_VARIABLE:
|
|
|
|
|
2011-12-28 17:12:18 +01:00
|
|
|
if (object)
|
2012-10-19 23:00:35 +02:00
|
|
|
THROW(E_STATIC, CLASS_get_name(class), name);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
if (defined) *PC |= 2;
|
|
|
|
|
|
|
|
if (defined)
|
|
|
|
PC[1] = index;
|
|
|
|
|
|
|
|
goto _POP_STATIC_VARIABLE_2;
|
|
|
|
|
|
|
|
case CD_PROPERTY:
|
|
|
|
|
|
|
|
if (object == NULL)
|
|
|
|
{
|
2010-05-19 22:18:23 +02:00
|
|
|
if (UNLIKELY(!class->auto_create))
|
2012-10-19 23:00:35 +02:00
|
|
|
THROW(E_DYNAMIC, CLASS_get_name(class), name);
|
2007-12-30 17:41:49 +01:00
|
|
|
object = EXEC_auto_create(class, TRUE);
|
|
|
|
*PC |= 5;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (defined) *PC |= 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (defined)
|
|
|
|
PC[1] = index;
|
|
|
|
|
|
|
|
goto _POP_PROPERTY_2;
|
|
|
|
|
|
|
|
case CD_STATIC_PROPERTY:
|
|
|
|
|
2011-12-28 17:12:18 +01:00
|
|
|
if (object)
|
2012-10-19 23:00:35 +02:00
|
|
|
THROW(E_STATIC, CLASS_get_name(class), name);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
if (defined) *PC |= 3;
|
|
|
|
|
|
|
|
if (defined)
|
|
|
|
PC[1] = index;
|
|
|
|
|
|
|
|
goto _POP_PROPERTY_2;
|
|
|
|
|
|
|
|
case CD_PROPERTY_READ:
|
|
|
|
case CD_STATIC_PROPERTY_READ:
|
|
|
|
|
2012-10-19 23:00:35 +02:00
|
|
|
THROW(E_NWRITE, CLASS_get_name(class), name);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
case CD_METHOD:
|
|
|
|
case CD_STATIC_METHOD:
|
|
|
|
|
2012-10-19 23:00:35 +02:00
|
|
|
THROW(E_NPROPERTY, CLASS_get_name(class), name);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
default:
|
|
|
|
|
2012-10-19 23:00:35 +02:00
|
|
|
THROW(E_NSYMBOL, CLASS_get_name(class), name);
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_POP_VARIABLE_AUTO:
|
|
|
|
|
|
|
|
object = EXEC_auto_create(class, TRUE);
|
|
|
|
|
|
|
|
_POP_VARIABLE:
|
|
|
|
|
|
|
|
desc = class->table[PC[1]].desc;
|
|
|
|
|
|
|
|
_POP_VARIABLE_2:
|
|
|
|
|
|
|
|
addr = (char *)object + desc->variable.offset;
|
|
|
|
VALUE_write(&SP[-2], (void *)addr, desc->variable.type);
|
|
|
|
goto _FIN;
|
|
|
|
|
|
|
|
|
|
|
|
_POP_STATIC_VARIABLE:
|
|
|
|
|
|
|
|
desc = class->table[PC[1]].desc;
|
|
|
|
|
|
|
|
_POP_STATIC_VARIABLE_2:
|
|
|
|
|
2009-06-17 16:13:50 +02:00
|
|
|
addr = (char *)desc->variable.class->stat + desc->variable.offset;
|
2007-12-30 17:41:49 +01:00
|
|
|
VALUE_write(&SP[-2], (void *)addr, desc->variable.type);
|
|
|
|
goto _FIN;
|
|
|
|
|
|
|
|
|
2010-05-25 13:19:00 +02:00
|
|
|
_POP_STRUCT_FIELD:
|
|
|
|
|
|
|
|
desc = class->table[PC[1]].desc;
|
|
|
|
|
|
|
|
_POP_STRUCT_FIELD_2:
|
|
|
|
|
|
|
|
if (((CSTRUCT *)object)->ref)
|
2010-05-27 00:01:28 +02:00
|
|
|
addr = (char *)((CSTATICSTRUCT *)object)->addr + desc->variable.offset;
|
2010-05-25 13:19:00 +02:00
|
|
|
else
|
2010-05-27 00:01:28 +02:00
|
|
|
addr = (char *)object + sizeof(CSTRUCT) + desc->variable.offset;
|
2010-05-25 13:19:00 +02:00
|
|
|
|
2010-07-08 00:06:05 +02:00
|
|
|
VALUE_write(&SP[-2], (void *)addr, desc->variable.type);
|
2010-05-25 13:19:00 +02:00
|
|
|
goto _FIN;
|
|
|
|
|
|
|
|
|
2007-12-30 17:41:49 +01:00
|
|
|
_POP_PROPERTY_AUTO:
|
|
|
|
|
|
|
|
object = EXEC_auto_create(class, TRUE);
|
|
|
|
|
|
|
|
_POP_PROPERTY:
|
|
|
|
|
|
|
|
desc = class->table[PC[1]].desc;
|
|
|
|
|
|
|
|
_POP_PROPERTY_2:
|
|
|
|
|
|
|
|
VALUE_conv(&SP[-2], desc->property.type);
|
|
|
|
|
|
|
|
if (desc->property.native)
|
|
|
|
{
|
2010-05-19 22:18:23 +02:00
|
|
|
if (UNLIKELY(EXEC_call_native(desc->property.write, object, 0, &SP[-2])))
|
2007-12-30 17:41:49 +01:00
|
|
|
PROPAGATE();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*SP = SP[-2];
|
2009-08-05 18:14:08 +02:00
|
|
|
PUSH();
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
EXEC.class = desc->property.class;
|
|
|
|
EXEC.object = object;
|
|
|
|
EXEC.nparam = 1;
|
|
|
|
EXEC.native = FALSE;
|
2008-01-17 22:39:26 +01:00
|
|
|
EXEC.index = (int)(intptr_t)desc->property.write;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
EXEC_function();
|
|
|
|
}
|
2009-08-05 18:14:08 +02:00
|
|
|
|
|
|
|
goto _FIN;
|
|
|
|
|
|
|
|
_POP_UNKNOWN_PROPERTY:
|
|
|
|
|
2012-07-03 19:41:36 +02:00
|
|
|
if (class->special[SPEC_PROPERTY] == NO_SYMBOL)
|
|
|
|
goto _NOT_A_PROPERTY;
|
|
|
|
|
2011-07-03 04:46:15 +02:00
|
|
|
EXEC_unknown_name = name;
|
2012-07-04 23:59:16 +02:00
|
|
|
if (EXEC_special(SPEC_PROPERTY, class, class->property_static ? NULL : object, 0, FALSE))
|
|
|
|
goto _NOT_A_PROPERTY;
|
2012-07-03 19:41:36 +02:00
|
|
|
|
2011-07-03 04:46:15 +02:00
|
|
|
VALUE_conv_boolean(&SP[-1]);
|
|
|
|
SP--;
|
|
|
|
if (!SP->_boolean.value)
|
2012-07-03 19:41:36 +02:00
|
|
|
goto _NOT_A_PROPERTY;
|
2011-07-03 04:46:15 +02:00
|
|
|
|
2011-07-15 02:52:29 +02:00
|
|
|
EXEC_unknown_name = name;
|
2009-08-05 18:14:08 +02:00
|
|
|
|
|
|
|
*SP = SP[-2];
|
|
|
|
PUSH();
|
|
|
|
|
2012-07-05 00:06:19 +02:00
|
|
|
EXEC_special(SPEC_UNKNOWN, class, class->unknown_static ? NULL : object, 1, TRUE);
|
2012-07-03 19:41:36 +02:00
|
|
|
goto _FIN;
|
|
|
|
|
|
|
|
_NOT_A_PROPERTY:
|
|
|
|
|
2012-10-19 23:00:35 +02:00
|
|
|
THROW(E_NPROPERTY, CLASS_get_name(class), name);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
_FIN:
|
|
|
|
|
|
|
|
RELEASE(&SP[-2]);
|
2013-03-30 14:51:10 +01:00
|
|
|
OBJECT_UNREF(object);
|
2007-12-30 17:41:49 +01:00
|
|
|
SP -= 2;
|
|
|
|
PC++;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-01-24 02:36:20 +01:00
|
|
|
void EXEC_pop_array(ushort code)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2010-05-19 17:05:45 +02:00
|
|
|
static const void *jump[] = { &&__POP_GENERIC, &&__POP_QUICK_ARRAY, && __POP_QUICK_COLLECTION, &&__POP_ARRAY };
|
2008-01-24 02:36:20 +01:00
|
|
|
|
2007-12-30 17:41:49 +01:00
|
|
|
CLASS *class;
|
|
|
|
OBJECT *object;
|
|
|
|
GET_NPARAM(np);
|
|
|
|
int i;
|
|
|
|
void *data;
|
2009-07-08 21:57:50 +02:00
|
|
|
bool defined;
|
2007-12-30 17:41:49 +01:00
|
|
|
VALUE *val;
|
|
|
|
VALUE swap;
|
2010-05-19 17:05:45 +02:00
|
|
|
int fast;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
val = &SP[-np];
|
2010-06-18 02:14:53 +02:00
|
|
|
goto *jump[((unsigned char)code) >> 6];
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2008-01-24 02:36:20 +01:00
|
|
|
__POP_GENERIC:
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-05-28 08:24:14 +02:00
|
|
|
defined = EXEC_object(val, &class, &object);
|
2008-01-24 02:36:20 +01:00
|
|
|
|
2008-05-10 17:17:07 +02:00
|
|
|
// The first time we access a symbol, we must not be virtual to find it
|
2010-05-19 22:18:23 +02:00
|
|
|
if (LIKELY(defined && object && !VALUE_is_super(val)))
|
2008-05-10 17:17:07 +02:00
|
|
|
{
|
|
|
|
//fprintf(stderr, "%s -> %s\n", class->name, val->_object.class->name);
|
|
|
|
class = val->_object.class;
|
|
|
|
}
|
|
|
|
|
2010-05-19 17:05:45 +02:00
|
|
|
fast = 3;
|
2008-01-24 02:36:20 +01:00
|
|
|
|
2010-05-19 22:18:23 +02:00
|
|
|
if (LIKELY(defined))
|
2008-01-24 02:36:20 +01:00
|
|
|
{
|
2010-05-19 17:05:45 +02:00
|
|
|
if (class->quick_array == CQA_ARRAY)
|
|
|
|
fast = 1;
|
|
|
|
else if (class->quick_array == CQA_COLLECTION)
|
|
|
|
fast = 2;
|
2008-01-24 02:36:20 +01:00
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-05-19 17:05:45 +02:00
|
|
|
*PC |= fast << 6;
|
2008-01-24 02:36:20 +01:00
|
|
|
|
2010-05-19 17:05:45 +02:00
|
|
|
goto __POP_ARRAY_2;
|
|
|
|
|
2008-01-24 02:36:20 +01:00
|
|
|
__POP_QUICK_ARRAY:
|
|
|
|
|
2010-06-18 02:14:53 +02:00
|
|
|
EXEC_object_fast(val, &class, &object);
|
2008-01-24 02:36:20 +01:00
|
|
|
|
2010-05-19 17:05:45 +02:00
|
|
|
TYPE type = ((CARRAY *)object)->type;
|
|
|
|
|
|
|
|
VALUE_copy(&swap, &val[0]);
|
|
|
|
VALUE_copy(&val[0], &val[-1]);
|
|
|
|
VALUE_copy(&val[-1], &swap);
|
|
|
|
|
|
|
|
VALUE_conv(&val[0], type);
|
2010-06-18 02:14:53 +02:00
|
|
|
VALUE_conv_integer(&val[1]);
|
2010-05-19 17:05:45 +02:00
|
|
|
|
2010-05-19 22:18:23 +02:00
|
|
|
if (LIKELY(np == 2))
|
2008-01-24 11:42:42 +01:00
|
|
|
{
|
2010-05-19 17:05:45 +02:00
|
|
|
data = CARRAY_get_data((CARRAY *)object, val[1]._integer.value);
|
2008-01-24 11:42:42 +01:00
|
|
|
}
|
2010-05-19 17:05:45 +02:00
|
|
|
else
|
2008-01-24 11:42:42 +01:00
|
|
|
{
|
2010-06-18 02:14:53 +02:00
|
|
|
for (i = 2; i < np; i++)
|
2010-06-03 01:23:50 +02:00
|
|
|
VALUE_conv_integer(&val[i]);
|
2008-01-24 11:42:42 +01:00
|
|
|
|
2010-05-19 17:05:45 +02:00
|
|
|
data = CARRAY_get_data_multi((CARRAY *)object, (GB_INTEGER *)&val[1], np - 1);
|
2008-01-24 11:42:42 +01:00
|
|
|
}
|
2010-05-19 22:18:23 +02:00
|
|
|
if (UNLIKELY(data == NULL))
|
2010-05-19 17:05:45 +02:00
|
|
|
PROPAGATE();
|
|
|
|
VALUE_write(val, data, type);
|
|
|
|
|
|
|
|
SP = val + 1;
|
|
|
|
RELEASE_MANY(SP, 2);
|
2013-03-30 14:51:10 +01:00
|
|
|
//OBJECT_UNREF(object);
|
2010-05-19 17:05:45 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
__POP_QUICK_COLLECTION:
|
|
|
|
|
2010-06-18 02:14:53 +02:00
|
|
|
EXEC_object_fast(val, &class, &object);
|
2010-05-19 17:05:45 +02:00
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
VALUE_conv_variant(&val[-1]);
|
2010-05-19 17:05:45 +02:00
|
|
|
VALUE_conv_string(&val[1]);
|
|
|
|
|
2010-05-19 22:18:23 +02:00
|
|
|
if (UNLIKELY(GB_CollectionSet((GB_COLLECTION)object, val[1]._string.addr + val[1]._string.start, val[1]._string.len, (GB_VARIANT *)&val[-1])))
|
2010-05-19 17:05:45 +02:00
|
|
|
PROPAGATE();
|
2008-01-24 02:36:20 +01:00
|
|
|
|
2010-05-19 17:05:45 +02:00
|
|
|
RELEASE_MANY(SP, 3);
|
2008-01-24 02:36:20 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
__POP_ARRAY:
|
|
|
|
|
2010-05-28 08:24:14 +02:00
|
|
|
defined = EXEC_object(val, &class, &object);
|
2008-01-24 02:36:20 +01:00
|
|
|
|
|
|
|
__POP_ARRAY_2:
|
|
|
|
|
2008-01-24 11:42:42 +01:00
|
|
|
/* swap object and value to be inserted */
|
2008-01-24 02:36:20 +01:00
|
|
|
|
2008-03-19 15:32:30 +01:00
|
|
|
//swap = val[0];
|
|
|
|
//val[0] = val[-1];
|
|
|
|
//val[-1] = swap;
|
|
|
|
VALUE_copy(&swap, &val[0]);
|
|
|
|
VALUE_copy(&val[0], &val[-1]);
|
|
|
|
VALUE_copy(&val[-1], &swap);
|
2008-01-24 02:36:20 +01:00
|
|
|
|
2010-05-19 22:18:23 +02:00
|
|
|
if (UNLIKELY(EXEC_special(SPEC_PUT, class, object, np, TRUE)))
|
2012-10-19 23:00:35 +02:00
|
|
|
THROW(E_NARRAY, CLASS_get_name(class));
|
2008-01-24 02:36:20 +01:00
|
|
|
|
2008-01-24 11:42:42 +01:00
|
|
|
POP(); /* free the object */
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|