Jump to content
  • Advertisement
Sign in to follow this  
abrken

-= operator for int32 member of an object

This topic is 5094 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, This problem can be reproduced for 1.9.2 release. First the code to reproduce :
//
// Tests calling of a stdcall function from a script with four parameters
// of different types
//
// Test author: Andreas Jönsson
//

#include "utils.h"

#define TESTNAME "TestStdcall4Args"

static bool testVal = false;
static bool called = false;

static int	t1 = 0;
static float	t2 = 0;
static double	t3 = 0;
static char	t4 = 0;

static void __stdcall cfunction(int f1, float f2, double f3, int f4) {
	called = true;

	t1 = f1;
	t2 = f2;
	t3 = f3;
	t4 = f4;
	
	testVal = (f1 == 10) && (f2 == 1.92f) && (f3 == 3.88) && (f4 == 97);
}

class CMyOut : public 	COutStream
{
public :
	virtual void Write(const char *text) {printf("%s\n", text);};
};

class CRect {
public :
	long left, top, bottom, right;
	CRect() : left(0), top(0), bottom(0), right(0) {};
	virtual ~CRect()  {};
};

void CRect_constructor(CRect &o)
{
	new (&o) CRect();
}

void CRect_destructor(CRect &o)
{
	o.~CRect();
}

static void __stdcall MyTrace(long f1) {
	printf("%ld\n", f1);
}

bool TestStdcall4Args()
{
	bool ret = false;
	CMyOut outStr;

	asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	engine->RegisterGlobalFunction("void cfunction(int, float, double, int)", asFUNCTION(cfunction), asCALL_STDCALL);
	engine->RegisterGlobalFunction("void Trace(int32)", asFUNCTION(MyTrace), asCALL_STDCALL);
	engine->RegisterObjectType("CRect", sizeof(CRect), asOBJ_CLASS);
	engine->RegisterObjectBehaviour("CRect", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(CRect_constructor), asCALL_CDECL_OBJLAST);
	engine->RegisterObjectBehaviour("CRect", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(CRect_destructor), asCALL_CDECL_OBJLAST);
	engine->RegisterObjectProperty("CRect", "int32 left", offsetof(CRect, left));
	engine->RegisterObjectProperty("CRect", "int32 top", offsetof(CRect, top));
	engine->RegisterObjectProperty("CRect", "int32 right", offsetof(CRect, right));
	engine->RegisterObjectProperty("CRect", "int32 bottom", offsetof(CRect, bottom));

	engine->ExecuteString(0, "CRect rcTest; rcTest.left = 30; rcTest.left -= 10; Trace(rcTest.left); int i1; i1 = 100; i1 -= 90; cfunction(i1, 1.92f, 3.88, 97)", &outStr, 0);
	
	if (!called) {
		printf("\n%s: cfunction not called from script\n\n", TESTNAME);
		ret = true;
	} else if (!testVal) {
		printf("\n%s: testVal is not of expected value. Got (%d, %f, %f, %c), expected (%d, %f, %f, %c)\n\n", TESTNAME, t1, t2, t3, t4, 10, 1.92f, 3.88, 97);
		ret = true;
	}

	engine->Release();
	engine = NULL;

	return ret;
}



What is being happening is that rcTest.left is not equal to 20 but -20 ! from what I have experienced it seems that the operation made is : x -= v ----> x= (x*-1) + v workaround is made throught : x = x - v; This bug is not reproduced if you change CRect.left to a single int32 value. Strange ?! Regards, AbrKen.

Share this post


Link to post
Share on other sites
Advertisement
This is a bug that I've already fixed in the latest WIP.

What's happening is that the bytecode is optimized as if substraction was associative, i.e (a - b) = (b - a), which of course it isn't.

You can fix this by removing BC_SUBi and BC_SUBf from asCByteCode::MatchPattern() and asCByteCode::OptimizePattern(). Also remove them from asCByteCode::Optimize(), where used in IsCombination(curr, BC_SWAP4, BC_SUBi), and IsCombination(curr, BC_SWAP4, BC_SUBf).

Share this post


Link to post
Share on other sites
Quote:
Original post by WitchLord
This is a bug that I've already fixed in the latest WIP.


Do you mean that going to 1.10.0 WIP2 this problem has been fixed, or should I have to wait your next WIP ?

Share this post


Link to post
Share on other sites
oops, I have missed the line where it speaks about that. Thank's, now I know that the bug has been fixed since 1.10.0 WIP1.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!