gambas-source-code/main/gbx/gbx_exec_pop.c

340 lines
6.6 KiB
C
Raw Normal View History

/***************************************************************************
exec_pop.c
(c) 2000-2007 Benoit Minisini <gambas@users.sourceforge.net>
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
the Free Software Foundation; either version 1, or (at your option)
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
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***************************************************************************/
#include "gb_common.h"
#include "gb_limit.h"
#include "gbx_exec.h"
#include "gbx_string.h"
#include "gbx_object.h"
#include "gbx_array.h"
#include "gbx_c_array.h"
#include "gbx_c_collection.h"
******** Merged /branches/64bits r918:1003 into /trunk [CONFIGURATION] * NEW: 64 bits port. [EXAMPLES] * BUG: Fixed the AnalogWatch example. [WIKI CGI SCRIPT] * NEW: Some little cosmetic changes. [INTERPRETER] * NEW: The extern function implementation has been redesigned and is now based on libffi, so that it works on 64 bits system. Because of a flaw in the compiler design, projects that use the Pointer datatype must be recompiled to be used on a 64 bits system. This flaw will be fixed in Gambas 3. * OPT: Put some tables into read-only memory. About 1000 bytes are saved for each running interpreter, except the first one. * BUG: Does not crash anymore if a component cannot be loaded. * NEW: Spanish translation updated. * NEW: A new interpreter API for returning a pointer. [COMPILER] * BUG: Correctly compiles LONG constants inside code. [GB.DEBUG] * BUG: Compiles and links the gb.debug components with the thread libraries. [GB.DB.SQLITE3] * BUG: Getting the primary index of a table without primary index is safe now. [GB.GTK] * BUG: Modified the GLib priority of watched descriptors, as the main loop could enter in a loop in which user interface events were not managed. * BUG: Message boxes use application title without crashing now. [GB.OPENGL] * BUG: Disable dead code. [GB.QT.EXT] * BUG: TextEdit.TextWidth and TextEdit.TextHeight were not declared as read-only properties. [GB.XML.XSLT] * BUG: XSLT class is now declared as being not creatable. git-svn-id: svn://localhost/gambas/trunk@1006 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2008-01-17 22:39:26 +01:00
void EXEC_pop_unknown(void)
{
static void *jump[6] = {
/* 0 */ &&_POP_GENERIC,
/* 1 */ &&_POP_VARIABLE,
/* 2 */ &&_POP_STATIC_VARIABLE,
/* 3 */ &&_POP_PROPERTY,
/* 4 */ &&_POP_VARIABLE_AUTO,
/* 5 */ &&_POP_PROPERTY_AUTO
};
const char *name;
******** Merged /branches/64bits r918:1003 into /trunk [CONFIGURATION] * NEW: 64 bits port. [EXAMPLES] * BUG: Fixed the AnalogWatch example. [WIKI CGI SCRIPT] * NEW: Some little cosmetic changes. [INTERPRETER] * NEW: The extern function implementation has been redesigned and is now based on libffi, so that it works on 64 bits system. Because of a flaw in the compiler design, projects that use the Pointer datatype must be recompiled to be used on a 64 bits system. This flaw will be fixed in Gambas 3. * OPT: Put some tables into read-only memory. About 1000 bytes are saved for each running interpreter, except the first one. * BUG: Does not crash anymore if a component cannot be loaded. * NEW: Spanish translation updated. * NEW: A new interpreter API for returning a pointer. [COMPILER] * BUG: Correctly compiles LONG constants inside code. [GB.DEBUG] * BUG: Compiles and links the gb.debug components with the thread libraries. [GB.DB.SQLITE3] * BUG: Getting the primary index of a table without primary index is safe now. [GB.GTK] * BUG: Modified the GLib priority of watched descriptors, as the main loop could enter in a loop in which user interface events were not managed. * BUG: Message boxes use application title without crashing now. [GB.OPENGL] * BUG: Disable dead code. [GB.QT.EXT] * BUG: TextEdit.TextWidth and TextEdit.TextHeight were not declared as read-only properties. [GB.XML.XSLT] * BUG: XSLT class is now declared as being not creatable. git-svn-id: svn://localhost/gambas/trunk@1006 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2008-01-17 22:39:26 +01:00
int index;
CLASS_DESC *desc;
CLASS *class;
OBJECT *object;
char *addr;
boolean defined;
VALUE *val;
EXEC_object(&SP[-1], &class, &object, &defined);
/*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];
if (defined && object && !VALUE_is_super(val))
index = CLASS_find_symbol(val->_object.class, name);
else
index = CLASS_find_symbol(class, name);
if (index == NO_SYMBOL)
{
if (defined && object && !VALUE_is_super(val))
class = val->_object.class;
THROW(E_NSYMBOL, name, class->name);
}
desc = class->table[index].desc;
switch (CLASS_DESC_get_type(desc))
{
case CD_CONSTANT:
THROW(E_NPROPERTY, class->name, name);
case CD_VARIABLE:
if (object == NULL)
{
if (!class->auto_create)
THROW(E_DYNAMIC, class->name, name);
object = EXEC_auto_create(class, TRUE);
*PC |= 4;
}
else
{
if (defined) *PC |= 1;
}
if (defined)
PC[1] = index;
goto _POP_VARIABLE_2;
case CD_STATIC_VARIABLE:
if (object != NULL)
THROW(E_STATIC, class->name, name);
if (defined) *PC |= 2;
if (defined)
PC[1] = index;
goto _POP_STATIC_VARIABLE_2;
case CD_PROPERTY:
if (object == NULL)
{
if (!class->auto_create)
THROW(E_DYNAMIC, class->name, name);
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:
if (object != NULL)
THROW(E_STATIC, class->name, name);
if (defined) *PC |= 3;
if (defined)
PC[1] = index;
goto _POP_PROPERTY_2;
case CD_PROPERTY_READ:
case CD_STATIC_PROPERTY_READ:
THROW(E_NWRITE, class->name, name);
case CD_METHOD:
case CD_STATIC_METHOD:
THROW(E_NPROPERTY, class->name, name);
default:
THROW(E_NSYMBOL, name, class->name);
}
_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:
addr = (char *)class->stat + desc->variable.offset;
VALUE_write(&SP[-2], (void *)addr, desc->variable.type);
goto _FIN;
_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)
{
if (EXEC_call_native(desc->property.write, object, 0, &SP[-2]))
PROPAGATE();
}
else
{
*SP = SP[-2];
BORROW(SP);
SP++;
EXEC.class = desc->property.class;
EXEC.object = object;
EXEC.drop = FALSE;
EXEC.nparam = 1;
EXEC.native = FALSE;
******** Merged /branches/64bits r918:1003 into /trunk [CONFIGURATION] * NEW: 64 bits port. [EXAMPLES] * BUG: Fixed the AnalogWatch example. [WIKI CGI SCRIPT] * NEW: Some little cosmetic changes. [INTERPRETER] * NEW: The extern function implementation has been redesigned and is now based on libffi, so that it works on 64 bits system. Because of a flaw in the compiler design, projects that use the Pointer datatype must be recompiled to be used on a 64 bits system. This flaw will be fixed in Gambas 3. * OPT: Put some tables into read-only memory. About 1000 bytes are saved for each running interpreter, except the first one. * BUG: Does not crash anymore if a component cannot be loaded. * NEW: Spanish translation updated. * NEW: A new interpreter API for returning a pointer. [COMPILER] * BUG: Correctly compiles LONG constants inside code. [GB.DEBUG] * BUG: Compiles and links the gb.debug components with the thread libraries. [GB.DB.SQLITE3] * BUG: Getting the primary index of a table without primary index is safe now. [GB.GTK] * BUG: Modified the GLib priority of watched descriptors, as the main loop could enter in a loop in which user interface events were not managed. * BUG: Message boxes use application title without crashing now. [GB.OPENGL] * BUG: Disable dead code. [GB.QT.EXT] * BUG: TextEdit.TextWidth and TextEdit.TextHeight were not declared as read-only properties. [GB.XML.XSLT] * BUG: XSLT class is now declared as being not creatable. git-svn-id: svn://localhost/gambas/trunk@1006 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2008-01-17 22:39:26 +01:00
EXEC.index = (int)(intptr_t)desc->property.write;
EXEC_function();
}
_FIN:
RELEASE(&SP[-2]);
OBJECT_UNREF(&object, "EXEC_pop_unknown");
SP -= 2;
PC++;
}
void EXEC_pop_array(ushort code)
{
static const void *jump[] = { &&__POP_GENERIC, &&__POP_STATIC_ARRAY, &&__POP_QUICK_ARRAY, &&__POP_ARRAY };
CLASS *class;
OBJECT *object;
GET_NPARAM(np);
******** Merged /branches/64bits r918:1003 into /trunk [CONFIGURATION] * NEW: 64 bits port. [EXAMPLES] * BUG: Fixed the AnalogWatch example. [WIKI CGI SCRIPT] * NEW: Some little cosmetic changes. [INTERPRETER] * NEW: The extern function implementation has been redesigned and is now based on libffi, so that it works on 64 bits system. Because of a flaw in the compiler design, projects that use the Pointer datatype must be recompiled to be used on a 64 bits system. This flaw will be fixed in Gambas 3. * OPT: Put some tables into read-only memory. About 1000 bytes are saved for each running interpreter, except the first one. * BUG: Does not crash anymore if a component cannot be loaded. * NEW: Spanish translation updated. * NEW: A new interpreter API for returning a pointer. [COMPILER] * BUG: Correctly compiles LONG constants inside code. [GB.DEBUG] * BUG: Compiles and links the gb.debug components with the thread libraries. [GB.DB.SQLITE3] * BUG: Getting the primary index of a table without primary index is safe now. [GB.GTK] * BUG: Modified the GLib priority of watched descriptors, as the main loop could enter in a loop in which user interface events were not managed. * BUG: Message boxes use application title without crashing now. [GB.OPENGL] * BUG: Disable dead code. [GB.QT.EXT] * BUG: TextEdit.TextWidth and TextEdit.TextHeight were not declared as read-only properties. [GB.XML.XSLT] * BUG: XSLT class is now declared as being not creatable. git-svn-id: svn://localhost/gambas/trunk@1006 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2008-01-17 22:39:26 +01:00
int dim[MAX_ARRAY_DIM];
int i;
void *data;
boolean defined;
VALUE *val;
VALUE swap;
ARRAY_DESC *desc;
val = &SP[-np];
goto *jump[(code & 0xC0) >> 6];
__POP_GENERIC:
if (val->type == T_ARRAY)
{
*PC |= 1 << 6;
goto __POP_STATIC_ARRAY;
}
EXEC_object(val, &class, &object, &defined);
if (defined && class->array_put)
{
*PC |= 2 << 6;
goto __POP_QUICK_ARRAY_2;
}
*PC |= 3 << 6;
goto __POP_ARRAY_2;
__POP_STATIC_ARRAY:
np--;
for (i = 1; i <= np; i++)
{
VALUE_conv(&val[i], T_INTEGER);
dim[i - 1] = val[i]._integer.value;
}
SP -= np + 1;
desc = (ARRAY_DESC *)SP->_array.class->load->array[SP->_array.index];
data = ARRAY_get_address(desc, SP->_array.addr, np, dim);
VALUE_write(SP - 1, data, CLASS_ctype_to_type(SP->_array.class, desc->type));
POP();
return;
__POP_QUICK_ARRAY:
EXEC_object(val, &class, &object, &defined);
__POP_QUICK_ARRAY_2:
swap = val[0];
val[0] = val[-1];
val[-1] = swap;
VALUE_conv(&val[0], ((CARRAY *)object)->type);
for (i = 1; i < np; i++)
VALUE_conv(&val[i], T_INTEGER);
EXEC.nparvar = np - 2;
if (EXEC_call_native(class->array_put->exec, object, class->array_put->type, val))
PROPAGATE();
SP = val + 1;
POP();
POP();
//OBJECT_UNREF(&object, "EXEC_push_array");
return;
__POP_ARRAY:
EXEC_object(val, &class, &object, &defined);
__POP_ARRAY_2:
/* remplace l'objet par la valeur <20>ins<6E>er */
swap = val[0];
val[0] = val[-1];
val[-1] = swap;
/*printf("<< EXEC_pop_array: np = %d SP = %d\n", np, SP - (VALUE *)STACK_base);
save_SP = SP - np;*/
if (EXEC_special(SPEC_PUT, class, object, np, TRUE))
THROW(E_NARRAY, class->name);
/*printf(">> EXEC_pop_array: SP = %d\n", SP - (VALUE *)STACK_base);
if (SP != save_SP)
printf("**** SP should be %d\n", save_SP - (VALUE *)STACK_base);*/
POP(); /* on lib<69>e l'objet */
}