AngelScript 1.10.0 FINAL (2004/11/02)

Started by
44 comments, last by jetro 19 years, 5 months ago
I see a something strange. If I do this:

  uint i=0;  brickbase=CreateObjectInstance(tbase);

There is no problem. However, if I do this:

  uint i;  for(i=0;i<1;++i) {    brickbase=CreateObjectInstance(tbase);  }

I get the stacksize problem. In both cases they are preceeded by

ObjectType *tball, *tspinnera, *tbase, *tbrick1, *tpaddle;ObjectInstance *[] brickbase(4);  tbase=CreateObjectType("base");

I also get a number of problems with Dereference when I try to pass the value of an element of an array of pointers to a registered method, such as

//myType *[] myArray(2);MethodThatTakesAPointer(myArray[0]);// this also asserts in DereferenceSomeInstance->ClassMethodThatTakesAPointer(myArray[1]);// and this, on the first line.myType *t=myArray[0];MethodThatTakesAPointer(t);

I have applied the fix for the pointer dereferencing that you mentioned earlier.

[Edited by - Aggrav8d on November 6, 2004 5:37:00 PM]
Dan Royer, OwnerMarginally Clever Games
Advertisement
I can run the following test without any problems:

#include "utils.h"namespace TestPointer{#define TESTNAME "TestPointer"class ObjectInstance {public:	int val;};class ObjectType{public:};static void ObjectFunction(ObjectInstance *obj){}ObjectInstance obj;static ObjectInstance *CreateObjectInstance(ObjectType *type){	return &obj;}ObjectType type;static ObjectType *CreateObjectType(std::string &str){	return &type;}static void FunctionOnObject(ObjectInstance *obj){}static const char *script = "void Test()                                        \n""{                                                  \n""  ObjectInstance*[] c(5);                          \n""  ObjectType *tbase = CreateObjectType(\"base\");  \n""  uint i;                                          \n""  for( i = 0; i < 5; ++i )                         \n""  {                                                \n""    c = CreateObjectInstance(tbase);            \n""    c->function();                              \n""    c->val = 0;                                 \n""  }                                                \n""  ObjectInstance *obj = c[0];                      \n""  FunctionOnObject(c[0]);                          \n""}                                                  \n";bool Test(){	bool fail = false;	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);	RegisterStdString(engine);	int r;	r = engine->RegisterObjectType("ObjectInstance", sizeof(ObjectInstance), asOBJ_CLASS); assert(r>=0);	r = engine->RegisterObjectProperty("ObjectInstance", "int val", offsetof(ObjectInstance, val)); assert(r>=0);	r = engine->RegisterObjectMethod("ObjectInstance", "void function()", asFUNCTION(ObjectFunction), asCALL_CDECL_OBJFIRST); assert(r>=0);	r = engine->RegisterObjectType("ObjectType", sizeof(ObjectType), asOBJ_CLASS); assert(r>=0);	r = engine->RegisterGlobalFunction("ObjectType *CreateObjectType(string &)", asFUNCTION(CreateObjectType), asCALL_CDECL); assert(r>=0);	r = engine->RegisterGlobalFunction("ObjectInstance *CreateObjectInstance(ObjectType *type)", asFUNCTION(CreateObjectInstance), asCALL_CDECL); assert(r>=0);		r = engine->RegisterGlobalFunction("void FunctionOnObject(ObjectInstance *)", asFUNCTION(FunctionOnObject), asCALL_CDECL); assert(r>=0);	// Register an object.	ObjectInstance obj;	r = engine->RegisterGlobalProperty("ObjectInstance obj", &obj); assert(r>=0);	// Register a pointer to object.	ObjectInstance *pnt = &obj;	r = engine->RegisterGlobalProperty("ObjectInstance *ptr", &pnt); assert(r>=0);	COutStream out;	// Function call executed fine when using an object.	r = engine->ExecuteString(0, "obj.function(); obj.val = 23;", &out);	if( r < 0 )	{		printf("%s: ExecuteString() failed %d\n", TESTNAME, r);		fail = true;	}	if( obj.val != 23 )	{		printf("%s: failed\n", TESTNAME, r);		fail = true;	}	r = engine->ExecuteString(0, "ptr->function(); ptr->val = 13;", &out);	if( r < 0 )	{		printf("%s: ExecuteString() failed %d\n", TESTNAME, r);		fail = true;	}	if( obj.val != 13 )	{		printf("%s: failed\n", TESTNAME, r);		fail = true;	}	engine->AddScriptSection(0, TESTNAME, script, strlen(script));	r = engine->Build(0, &out);	if( r < 0 )	{		printf("%s: failed\n", TESTNAME, r);		fail = true;	}	r = engine->ExecuteString(0, "Test()");	if( r < 0 )	{		printf("%s: failed\n", TESTNAME, r);		fail = true;	}	engine->Release();	return fail;}}


Please give the latest 1.10.1 WIP 1 a try and see if the problems remain.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

I did the following with your test and it failed.

#include "utils.h"namespace TestPointer{#define TESTNAME "TestPointer"class ObjectInstance {public:	int val;  int val2;  int val3;  void Method() {    val=val2=val3=0;  }};class ObjectType{public:};static void ObjectFunction(ObjectInstance *obj){}ObjectInstance obj;static ObjectInstance *CreateObjectInstance(ObjectType *type){	return &obj;}ObjectType type;static ObjectType *CreateObjectType(std::string &str){	return &type;}static void FunctionOnObject(ObjectInstance *obj){}static const char *script = "void Test()                                        \n""{                                                  \n""  ObjectInstance*[] c(5);                          \n""  ObjectType *tbase = CreateObjectType(\"base\");  \n""  uint i;                                          \n""  for( i = 0; i < 5; ++i )                         \n""  {                                                \n""    c = CreateObjectInstance(tbase);            \n""    c->function();                              \n""    c->val = 0;                                 \n""  }                                                \n""  ObjectInstance *obj = c[0];                      \n""  FunctionOnObject(c[0]);                          \n""}                                                  \n";bool Test(){	bool fail = false;	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);	RegisterStdString(engine);	int r;	r = engine->RegisterObjectType("ObjectInstance", sizeof(ObjectInstance), asOBJ_CLASS); assert(r>=0);	r = engine->RegisterObjectProperty("ObjectInstance", "int val", offsetof(ObjectInstance, val)); assert(r>=0);	r = engine->RegisterObjectProperty("ObjectInstance", "int val2", offsetof(ObjectInstance, val)); assert(r>=0);	r = engine->RegisterObjectProperty("ObjectInstance", "int val3", offsetof(ObjectInstance, val)); assert(r>=0);	r = engine->RegisterObjectMethod("ObjectInstance", "void function()", asFUNCTION(ObjectFunction), asCALL_CDECL_OBJFIRST); assert(r>=0);	r = engine->RegisterObjectMethod("ObjectInstance", "void Method()", asMETHOD(ObjectInstance,Method), asCALL_THISCALL); assert(r>=0);	r = engine->RegisterObjectType("ObjectType", sizeof(ObjectType), asOBJ_CLASS); assert(r>=0);	r = engine->RegisterGlobalFunction("ObjectType *CreateObjectType(string &)", asFUNCTION(CreateObjectType), asCALL_CDECL); assert(r>=0);	r = engine->RegisterGlobalFunction("ObjectInstance *CreateObjectInstance(ObjectType *type)", asFUNCTION(CreateObjectInstance), asCALL_CDECL); assert(r>=0);		r = engine->RegisterGlobalFunction("void FunctionOnObject(ObjectInstance *)", asFUNCTION(FunctionOnObject), asCALL_CDECL); assert(r>=0);	// Register an object.	ObjectInstance obj;	r = engine->RegisterGlobalProperty("ObjectInstance obj", &obj); assert(r>=0);	// Register a pointer to object.	ObjectInstance *pnt = &obj;	r = engine->RegisterGlobalProperty("ObjectInstance *ptr", &pnt); assert(r>=0);	COutStream out;	// Function call executed fine when using an object.	r = engine->ExecuteString(0, "obj.function(); obj.val = 23;", &out);	if( r < 0 )	{		printf("%s: ExecuteString() failed %d\n", TESTNAME, r);		fail = true;	}	if( obj.val != 23 )	{		printf("%s: failed\n", TESTNAME, r);		fail = true;	}	r = engine->ExecuteString(0, "ptr->function(); ptr->val = 13;", &out);	if( r < 0 )	{		printf("%s: ExecuteString() failed %d\n", TESTNAME, r);		fail = true;	}	if( obj.val != 13 )	{		printf("%s: failed\n", TESTNAME, r);		fail = true;	}	engine->AddScriptSection(0, TESTNAME, script, strlen(script));	r = engine->Build(0, &out);	if( r < 0 )	{		printf("%s: failed\n", TESTNAME, r);		fail = true;	}	r = engine->ExecuteString(0, "Test()");	if( r < 0 )	{		printf("%s: failed\n", TESTNAME, r);		fail = true;	}	engine->Release();	return fail;}}


Note that this is not with the latest WIP. When I try to compile the library there, the WIN32 Debug with ASM VM build fails with the message

c:\angelcode\sdk\angelscript\source\as_context_x86.cpp(131) : error C2248: 'length' : cannot access protected member declared in class 'asCArray<int>'        c:\angelcode\sdk\angelscript\source\as_array.h(61) : see declaration of 'length'

I comment out that one line, compile the necessary projects, and run with the version of TestPointer listed here and it dies with the error message

Assertion failed: false, file c:\angelcode\sdk\angelscript\source\as_compiler.cpp, line 1921

... is there any way to get "check here to include your profile signature" to stay selected all the time? That bugs the hell out of me!
Dan Royer, OwnerMarginally Clever Games
In addition to the already solved pointer problems, I'm having problems with casting things to double with AS 1.10.0:

I managed to reduce the case down to simple test like this, after which I print out value of ft or t2 (using bstrFormat).
float ft = float(0.03);double t = double(ft);float t2 = float(t);

At this point, printing out ft gives out 0.03 and printing
out t2 gives out -3.68935e+019, although they should be equal.
--Jetro Lauha - tonic - http://jet.ro
Aggrav8d:

Quote:
Note that this is not with the latest WIP. When I try to compile the library there, the WIN32 Debug with ASM VM build fails with the message


c:\angelcode\sdk\angelscript\source\as_context_x86.cpp(131) : error C2248: 'length' : cannot access protected member declared in class 'asCArray<int>'
c:\angelcode\sdk\angelscript\source\as_array.h(61) : see declaration of 'length'


Sorry about that, I thought I had commented out that line already, but I remember now that that was at work after I sent the code home for development during the weekend. I've fixed the download already.

With the changes you made to the test case I too get the assert failure. It should now be quite easy to find the problem.

jetro:

I will look into this problem as well. It might be a problem with the VM. There are unfortunately too many of the bytecodes that haven't been thouroughly tested yet.




AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

To fix the assert failure in Dereference() you need to replace the code for asCDataType::GetSubType() (in as_datatype.cpp) with the following:

asCDataType asCDataType::GetSubType(asCScriptEngine *engine){	asCDataType dt(*this);	if( dt.arrayDimensions ) 		dt.arrayDimensions--;	else if( dt.pointerLevel ) 		dt.pointerLevel--;	if( dt.arrayDimensions > 0 )		dt.objectType = engine->GetArrayType(dt);	else if( dt.pointerLevel > 0 )		dt.objectType = 0;	else		dt.objectType = dt.extendedType;	return dt;}


---

I'm still looking in to the conversion to double problem.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

The fix for the floating conversion problem is to change the VM code for the following two bytecodes:

as_context.cpp line 1282:
	case BC_fTOd:		*(double*)--l_sp = double(*(float*)(l_sp));		l_bc += BCS_fTOd;		break;


as_context.cpp line 1267:
	case BC_dTOf:		*(float*)++l_sp = float(*(double*)(l_sp));		l_bc += BCS_dTOf;		break;


Note, this problem most likely exist for other conversions to and from double as well. I will write tests for all conversions right now (something that I should have done a long time ago).

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Just an additional note: I think I had the double conversion thing working just ok with previous version(s) - not sure if I tested it last time with 1.8.x or 1.9.x. I was using it with wrapping std sin, cos, etc. and just noticed with the latest update that my test code for them wasn't working anymore.
--Jetro Lauha - tonic - http://jet.ro
I know, the conversion bug was introduced with the optimization of the C++ VM. I failed to fully understand when the ++ and --operators are evaluated:

I was doing:

*sp = *sp++; // Doesn't update sp until after the assignment

instead of:

*++sp = *sp; // Updates sp after the right hand expression has been evaluated, but before the assignment



AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

I verified that your fixes for as_context.cpp fix the float<=>double conversions.

However, when I first noticed the problem, I was actually using code which casts a time value of type uint to double, and that one still didn't work. Which is not a surprise since the VM code related to that was still untouched :). That is, I have "uint mTime;" and "double(mTime)" didn't work, but adding additional typecast to float helped: "double(float(mTime))".

Looking at your fix, I made the equivalent changes to BC_dTOi, BC_dTOui, BC_iTOd and BC_uiTOd:
	case BC_dTOi:		*++l_sp = int(*(double*)(l_sp));		l_bc += BCS_dTOui;		break;	case BC_dTOui:		*++l_sp = asDWORD(*(double*)(l_sp));		l_bc += BCS_dTOui;		break;// ...	case BC_iTOd:		*(double*)--l_sp = double(int(*l_sp));		l_bc += BCS_iTOd;		break;	case BC_uiTOd:		*(double*)--l_sp = double(*l_sp);		l_bc += BCS_uiTOd;		break;

This seems to have fixed the problem and now the original script code seems to work again.
--Jetro Lauha - tonic - http://jet.ro

This topic is closed to new replies.

Advertisement