Followers 0

# AngelScript 1.10.0 FINAL (2004/11/02)

## 45 posts in this topic

This is the largest update ever made in one release, during the AngelScript history. A very shortened list of updates that were made is:
• Further optimized the VM with perhaps 1.5x average performance improvement
• Quite a few bug fixes
• A new boolean operator, xor, was added
• The library interface was improved, especially functions that returned strings
• ExecuteStep() now works as before (if the correct compile time flags are set)
• ExecuteString() has gotten a much needed overhaul. It's now possible to call it recursively, and also from multiple threads at the same time.
• The much awaited native support for arrays have finally been implemented. Now script writers can enjoy the full power of arrays in their functions. Application writers can easily register the exact array objects that they need for their functions, which makes the interaction very easy.
• Basic support for multithreading has been added, though it can be disabled at compile time for those who need the extra performance. Those are the most important points. You can read the complete list on the AngelScript site. Enjoy!
• 0

##### Share on other sites
Aaaargh! All these updates, and No time to implement!
0

##### Share on other sites
No worries [wink]
0

##### Share on other sites
I finally got some time to mess with AngelScript again, and it seems that the threading is causing crashes all over. None of the tests ran for me, they all crashed at ENTERCRITICALSECTION(criticalSection);

The crashes went away when I declared NO_THREADS in the project. I believe multi-threading is still not working fully yet, but they are on by default in MSVC project found in angelscript\projects\msvc6. Also the "compiling and linking with the library" link at the top of http://www.angelcode.com/angelscript/ is broken.

Not griping here, I LOVE angelscript. Just pointing out the problems I ran into just loading it up after a long break.

Forgot to mention I am using MSVC 7 with MSVC 6 libraries if that had anything to do with it.

[Edited by - lxnyce on November 4, 2004 10:21:25 AM]
0

##### Share on other sites
The problem is most likely because you're using MSVC7. The library works just fine in all my tests with multithreading turned on.

Still I will set the NO_THREADS flag as on by default, since multithreading is not yet stable.

Thanks for pointing out the broken link as well.

Regards,
Andreas
0

##### Share on other sites
andreas
take a look at http://softwire.sourceforge.net, it might help with the performance issues uve havin
0

##### Share on other sites
1. Congratulations! What's next on the agenda? :)

2. So, just to be clear:

int a[5](6);

would be the proper syntax in C++ to create an array of five floats initialized to the value 6. What is the syntax in angelscript?

3. I'm glad that you added the output message to Build(), but now I get an "Invalid Configuration" and an asINVALID_CONFIGURATION with no idea as to *why* it is invalid.
0

##### Share on other sites
ceasar4:

I'm aware of SoftWire, but AngelScript hasn't come so far as to compile directly to native code yet. Once it does I will most likely use SoftWire though.

Thanks anyway.

Aggrav8d:

1. Thanks. What's next is AS2, with the slightly changed syntax. AS1 will also be improved with a few things, like initialization lists, -> operator overload, better compile speed, etc.

2. AS still don't support automatic initialization of arrays, so in this case you'll have to write a loop to initialize each of the elements.

int[] a(5);
for( int n = 0; n < 5; n++ ) a[n] = 6;

3. AS doesn't store the function call that failed during configuration. You'll have to verify each of the return codes. I recommend doing it like this:

r = engine->RegisterObjectType(...); assert( r >= 0 );
r = engine->RegisterObjectMethod(...); assert( r >= 0 );
r = engine->RegisterObjectMethod(...); assert( r >= 0 );
r = engine->RegisterGlobalFunction(...); assert( r >= 0 );

This doesn't polute the code with lots of if statements, and it will let you easily find the problem in debug mode. In release mode the return codes aren't verified but they won't fail if they don't fail in debug mode (unless I made a mistake somewhere).
0

##### Share on other sites
I manage to hit the assert(false) at the end of Dereference() without getting any kind of error message or code. What should I be looking for?

Digging a little further I see that it is trying to do a conversion but the type->dataType.GetSizeInMemoryDWords() is equal to 16 (!!)

[Edited by - Aggrav8d on November 5, 2004 1:44:23 PM]
0

##### Share on other sites
You have probably stumbled upon a bug. I'm guessing it is related to registered types and the way asCDataType changed for 1.10.0. Is it possible for you to give me a sample code that reproduces the assert failure?

0

##### Share on other sites
Hmm...I can't really chop my code up to provide a simple example, but I can describe the situation. I have an array of pointers to a class with properties and methods. In a loop i call a method that returns new instances

MyClass *[] c(5);int i;for(i=0;i<5;++i) {  c[i]=RegisteredAllocatorForMyClass();  c[i]->RegisteredDoStuff(45.0f,1.0f);}

And I get two problems:
the first, execution dies inside the for loop (but where, i'm not sure yet)
the second, if I change to MyClass [] and get rid of the allocation then I get No matching signatures to 'RegisteredDoStuff(const float, const float)'. I registered as non-const. If I change the registartion and internal methods to const I still get the error.

Also note that if I allocate like this

MyClass *ptr=RegisteredAllocatorForMyClass();

It does allocate (but I still get the No Matching signatures problem). That's all I've been able to figure out so far.
0

##### Share on other sites
Ok, that information might be enough for me to find the problem. I'll give it a try and let you know.

But before that I'd like to know if you noticed the post by Licu about the pointer related bug in AS 1.10? If you didn't then this may actually be what is causing your problems.

You'll find the bug fix for the -> operator in that thread.
0

##### Share on other sites
I added the fix for the -> operator and now I get an assert about
instr->StackSize == StackSize
0

##### Share on other sites
There seems to be a problem with arrays of pointers. I've written a test case using your example and it gives errors it shouldn't.

I'm looking into this right now, but I might not be able to fix it until Sunday.

0

##### Share on other sites
Well that throws my schedule off a couple of days, but I'll find things to work on in the meantime. I wish you godspeed with whatever you're doing :)
0

##### Share on other sites
The problem I had found was related to me using integer to index the arrays. Once I change the type of n to uint it worked fine. (NOTE: I will improve the implicit casting rules for the next version)

void Test()                                {                                            class1*[] c(5);                            uint i;                                    for( i = 0; i < 5; ++i )                   {                                            c[i] = class1Factory();                    c[i]->function();                        }                                        }

This compiles and executes without problem (except that the compiler reports c as uninitialized, which is a bug but not a critical one).

The assert(instr->StackSize == StackSize) is probably related to the first problem you mentioned. It seems the compiler is trying to dereference a registered object even though it shouldn't.

This might be related to how you have registered your type. Can you show me how you registered the type in question? The one that was being dereferenced?
0

##### Share on other sites
I meant to type uint. Sorry.

  asEngine->RegisterObjectType("ObjectInstance", sizeof(ObjectInstance), asOBJ_CLASS);  asEngine->RegisterGlobalFunction("ObjectInstance *CreateObjectInstance(ObjectType *type)",asFUNCTION(::CreateObjectInstance),asCALL_CDECL);  asEngine->RegisterGlobalFunction("void ReleaseObjectInstance(ObjectInstance *)",asFUNCTION(::ReleaseObjectInstance),asCALL_CDECL);  asEngine->RegisterObjectMethod("ObjectInstance","GfxTexture *GetTexture()",asMETHOD(ObjectInstance, GetTexture), asCALL_THISCALL);  asEngine->RegisterObjectMethod("ObjectInstance","void SetTexture(GfxTexture *)",asMETHOD(ObjectInstance, SetTexture), asCALL_THISCALL);  asEngine->RegisterObjectMethod("ObjectInstance","GfxMesh *GetMesh()",asMETHOD(ObjectInstance, GetMesh), asCALL_THISCALL);  asEngine->RegisterObjectMethod("ObjectInstance","void SetMesh(GfxMesh *)",asMETHOD(ObjectInstance, SetMesh), asCALL_THISCALL);  asEngine->RegisterObjectMethod("ObjectInstance","bool ComesBefore(ObjectInstance *)",asMETHOD(ObjectInstance, ComesBefore), asCALL_THISCALL);  asEngine->RegisterObjectMethod("ObjectInstance","ObjectType *GetType()",asMETHOD(ObjectInstance, GetType), asCALL_THISCALL);  asEngine->RegisterObjectMethod("ObjectInstance","void SetPosition(float,float)",asMETHOD(ObjectInstance, SetPosition), asCALL_THISCALL);  asEngine->RegisterObjectMethod("ObjectInstance","void GetPosition(float&,float&)",asMETHOD(ObjectInstance, GetPosition), asCALL_THISCALL);  asEngine->RegisterObjectMethod("ObjectInstance","void SetVelocity(float,float)",asMETHOD(ObjectInstance, SetVelocity), asCALL_THISCALL);  asEngine->RegisterObjectMethod("ObjectInstance","void SetAngle(float)",asMETHOD(ObjectInstance, SetAngle), asCALL_THISCALL);  asEngine->RegisterObjectMethod("ObjectInstance","void SetAngularVelocity(float)",asMETHOD(ObjectInstance, SetAngularVelocity), asCALL_THISCALL);  asEngine->RegisterObjectMethod("ObjectInstance","void AssignPhysics(ObjectPhysicsDescription &opd)",asMETHOD(ObjectInstance, AssignPhysics),asCALL_THISCALL);  asEngine->RegisterObjectMethod("ObjectInstance","void SetName(string &)",asMETHOD(ObjectInstance, SetName), asCALL_THISCALL);  asEngine->RegisterObjectMethod("ObjectInstance","void SetStack(int pos,float v)",asMETHOD(ObjectInstance, SetStack), asCALL_THISCALL);  asEngine->RegisterObjectMethod("ObjectInstance","float GetStack(int pos)",asMETHOD(ObjectInstance, GetStack), asCALL_THISCALL);  asEngine->RegisterObjectMethod("ObjectInstance","void SetImmaterial(bool state)",asMETHOD(ObjectInstance, SetImmaterial), asCALL_THISCALL);  asEngine->RegisterObjectMethod("ObjectInstance","bool GetImmaterial()",asMETHOD(ObjectInstance, GetImmaterial), asCALL_THISCALL);
0

##### Share on other sites
Hmm, I can't see anything wrong with the way you registered the object.

I think I'll need to know what script function it is that is causing the assert failure. Would it be possible for you to find this? Simply comment out the script functions one by one until you find the one that fails compiling.

In the meanwhile I will look through the library code for possible causes.

0

##### Share on other sites
ObjectInstance *[] instanceArray(5);uint i=0;instanceArray[i]=ObtainObjectInstance(type);

is causing the problem.
0

##### Share on other sites
Unfortunately I don't seem to be able to reproduce the problem. Everything seems to work fine for me.

I will continue to search but without being able to reproduce the problem myself it is highly unlikely I'll find it.
0

##### Share on other sites
I see a something strange. If I do this:

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

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

  uint i;  for(i=0;i<1;++i) {    brickbase[i]=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]
0

##### Share on other sites
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[i] = CreateObjectInstance(tbase);            \n""    c[i]->function();                              \n""    c[i]->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.
0

##### Share on other sites
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[i] = CreateObjectInstance(tbase);            \n""    c[i]->function();                              \n""    c[i]->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!
0

##### Share on other sites
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.
0

##### Share on other sites
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 messagec:\angelcode\sdk\angelscript\source\as_context_x86.cpp(131) : error C2248: 'length' : cannot access protected member declared in class 'asCArray' 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.

0

## Create an account

Register a new account