Skip to content
Browse files

Fix portablity issues in the script interpeter.

All of the test maps now load.
Most of the real maps won't load, but I did get game/mars_city2 to load.
However it crashes as soon as you steap out of the elevator.
  • Loading branch information...
1 parent e1812c1 commit 2b7e3e70347a8f1075a452f0321c89a624c76ea7 @phire phire committed with Miguel Boton Nov 30, 2011
View
19 neo/game/script/Script_Compiler.cpp
@@ -1128,7 +1128,8 @@ idVarDef *idCompiler::ParseEventCall( idVarDef *object, idVarDef *funcDef ) {
EmitPush( object, object->TypeDef() );
}
- return EmitFunctionParms( OP_EVENTCALL, funcDef, 0, type_object.Size(), NULL );
+ // Before the script is called, an entity number (as an int) is pushed onto the stack
+ return EmitFunctionParms( OP_EVENTCALL, funcDef, 0, sizeof(int), NULL );
}
/*
@@ -2156,8 +2157,9 @@ void idCompiler::ParseFunctionDef( idTypeDef *returnType, const char *name ) {
func->parmSize.SetNum( numParms );
for( i = 0; i < numParms; i++ ) {
parmType = type->GetParmType( i );
- if ( parmType->Inherits( &type_object ) ) {
- func->parmSize[ i ] = type_object.Size();
+ if ( parmType->Inherits( &type_object ) or parmType->Type() == ev_entity) {
+ // objects/enties only have their entity number on the stack, as an int
+ func->parmSize[ i ] = sizeof(int);
} else {
func->parmSize[ i ] = parmType->Size();
}
@@ -2204,6 +2206,17 @@ void idCompiler::ParseFunctionDef( idTypeDef *returnType, const char *name ) {
ParseStatement();
}
+ // Allocate stack variables, now that they should have settled into their final types.
+ for (int i = 0; i < func->stackVars.Num(); i++) {
+ func->stackVars[ i ]->value.stackOffset = func->locals;
+ if ( func->stackVars[ i ]->TypeDef()->Inherits( &type_object ) || func->stackVars[ i ]->Type() == ev_entity) {
+ // objects/enties only have their entity number on the stack, as an int
+ func->locals += sizeof(int);
+ } else {
+ func->locals += func->stackVars[ i ]->TypeDef()->Size();
+ }
+ }
+
// check if we should call the super class destructor
if ( oldscope->TypeDef()->Inherits( &type_object ) && !idStr::Icmp( name, "destroy" ) ) {
idTypeDef *superClass;
View
4 neo/game/script/Script_Interpreter.cpp
@@ -741,7 +741,9 @@ void idInterpreter::CallEvent( const function_t *func, int argsize ) {
}
format = evdef->GetArgFormat();
- for( j = 0, i = 0, pos = type_object.Size(); ( pos < argsize ) || ( format[ i ] != 0 ); i++ ) {
+ // The sizeof(int) is a event entity that is the first (implied?) argument.
+ // It is stored on the stack as an int, not a pointer to one.
+ for( j = 0, i = 0, pos = sizeof(int); ( pos < argsize ) || ( format[ i ] != 0 ); i++ ) {
switch( format[ i ] ) {
case D_EVENT_INTEGER :
var.intPtr = ( int * )&localstack[ start + pos ];
View
16 neo/game/script/Script_Program.cpp
@@ -38,12 +38,12 @@ idTypeDef type_namespace( ev_namespace, &def_namespace, "namespace", sizeof( voi
idTypeDef type_string( ev_string, &def_string, "string", MAX_STRING_LEN, NULL );
idTypeDef type_float( ev_float, &def_float, "float", sizeof( float ), NULL );
idTypeDef type_vector( ev_vector, &def_vector, "vector", sizeof( idVec3 ), NULL );
-idTypeDef type_entity( ev_entity, &def_entity, "entity", sizeof( int ), NULL ); // stored as entity number pointer
+idTypeDef type_entity( ev_entity, &def_entity, "entity", sizeof( int * ), NULL ); // stored as entity number pointer
idTypeDef type_field( ev_field, &def_field, "field", sizeof( void * ), NULL );
idTypeDef type_function( ev_function, &def_function, "function", sizeof( void * ), &type_void );
idTypeDef type_virtualfunction( ev_virtualfunction, &def_virtualfunction, "virtual function", sizeof( int ), NULL );
idTypeDef type_pointer( ev_pointer, &def_pointer, "pointer", sizeof( void * ), NULL );
-idTypeDef type_object( ev_object, &def_object, "object", sizeof( int ), NULL ); // stored as entity number pointer
+idTypeDef type_object( ev_object, &def_object, "object", sizeof( int * ), NULL ); // stored as entity number pointer
idTypeDef type_jumpoffset( ev_jumpoffset, &def_jumpoffset, "<jump>", sizeof( int ), NULL ); // only used for jump opcodes
idTypeDef type_argsize( ev_argsize, &def_argsize, "<argsize>", sizeof( int ), NULL ); // only used for function call and thread opcodes
idTypeDef type_boolean( ev_boolean, &def_boolean, "boolean", sizeof( int ), NULL );
@@ -1303,16 +1303,10 @@ idVarDef *idProgram::AllocDef( idTypeDef *type, const char *name, idVarDef *scop
// stack variable
//
// since we don't know how many local variables there are,
- // we have to have them go backwards on the stack
- def->value.stackOffset = scope->value.functionPtr->locals;
+ // or what types they will end up with, we defer allocating
+ // them on the stack until the entire function has been parsed
def->initialized = idVarDef::stackVariable;
-
- if ( type->Inherits( &type_object ) ) {
- // objects only have their entity number on the stack, not the entire object
- scope->value.functionPtr->locals += type_object.Size();
- } else {
- scope->value.functionPtr->locals += type->Size();
- }
+ scope->value.functionPtr->stackVars.Append(def);
} else {
//
// global variable
View
1 neo/game/script/Script_Program.h
@@ -69,6 +69,7 @@ class function_t {
int locals; // total ints of parms + locals
int filenum; // source file defined in
idList<int> parmSize;
+ idList<idVarDef *> stackVars;
};
typedef union eval_s {

0 comments on commit 2b7e3e7

Please sign in to comment.
Something went wrong with that request. Please try again.