Jump to content
  • Advertisement


  • Content count

  • Joined

  • Last visited

Community Reputation

175 Neutral

About Miss

  • Rank

Personal Information


  • Twitter
  • Github

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. There's this code in scriptdictionary: (there's one for int and int64 too) else { // The stored type is an object // TODO: Check if the object has a conversion operator to a primitive value *(double*)value = 0; } return true; However, as it's not implemented and doesn't work, why doesn't it return false here? I changed the code to return false here so that we can detect wrong types added to this in our own code.
  2. Miss

    Refcounting in opCast

    Thanks to both of you!
  3. Miss

    Refcounting in opCast

    Thank you!
  4. Miss

    Refcounting in opCast

    It's an asCALL_CDECL_OBJFIRST, implementation here: https://pastebin.com/ybuVSTHj
  5. Miss

    Refcounting in opCast

    No, it's actually a custom class "MwBuffer". The interface is documented here: https://openplanet.nl/docs/class/MwBuffer The code for opIndex looks like this: static void ScriptBufferIndexer(asIScriptGeneric* gen) { CFastBufferBase* self = (CFastBufferBase*)gen->GetObject(); int dwIndex = gen->GetArgDWord(0); if (dwIndex >= self->m_Count) { asGetActiveContext()->SetException("Index out of range in buffer"); return; } int returnTypeId = gen->GetReturnTypeId(); asUINT typeSize = 4; if (!(returnTypeId & asTYPEID_OBJHANDLE)) { typeSize = GetTypeSize(gen->GetEngine(), gen->GetReturnTypeId()); } void* pObj = (char*)self->m_elements + typeSize * dwIndex; gen->SetReturnAddress(pObj); }
  6. Miss

    Refcounting in opCast

    I have an function declaration of "void opCast(?&out)" on a class with asOBJ_REF, and I'm running into an interesting problem. In 1 very specific case, (I can't seem to reproduce it in a clean test script), there seems to be either an AddRef too many or a Release too little. I can fix it by making a small change to my script. The following causes there to be 5 AddRef's, and 5 Releases, which is the expected behavior: auto a = g_scene.Mobils[0]; auto b = cast<CControlBase>(a); if (b !is null) { // ... } else { // ... } But the following produces 5 AddRef's and 4 Releases: auto b = cast<CControlBase>(g_scene.Mobils[0]); if (b !is null) { // ... } else { // ... } I checked if the typeId happens to be different in the opCast function (thought maybe const could be at play or so) but it seems like that's the same in both situations. I do an AddRef myself in the opCast function when returning the casted handle.
  7. Thank you, I'll experiment with this.
  8. Hmm, the problem with the #pragma approach is that if you have multiple modules, registering a function will be available to each module rather than only 1 module. Is there anything that can be done about that?
  9. Miss

    MSVC optimization bug?

    Okay, so Microsoft reported back to me (very quickly!), saying they've filed this bug and that they're working on it. As a workaround, there's 2 possibilities, either using #pragma optimize("", off) on CallGlobalFunction, or - which I think makes more sense since this bug might cause problems elsewhere in Angelscript - is to use a new undocumented (and completely unsupported) compiler flag /d2SSAOptimizerCFG- which "turns off all of our new control-flow-graph (CFG) based optimizations for the compilation, of which the erroneous optimization is a part". It's not recommended to use this compiler flag though, as it's completely unsupported and might disappear in the future, but if anyone is looking for a critical fix for this problem for the time being, it's probably a nice temporary solution. PS: Sorry for the triple post, but I figured it's fine since these are sequential updates..
  10. Miss

    MSVC optimization bug?

    Okay, I've narrowed it down a bit. This is caused by the latest Visual Studio 15.7.1 update, and this is isolated reproduction code: https://pastebin.com/nGW11NAx It will run on a debug build, but crash on a release build (it jumps to 0x1337 at the end of main() because the stack isn't cleaned up). I've sent a bugreport to Microsoft regarding this issue.
  11. Miss

    MSVC optimization bug?

    So did you reproduce it as well? Edit: Here's the reproduce steps that work for me. https://gist.github.com/codecat/9128e290b7f3fc74374a3035ff79e9af
  12. Miss

    Exposing a Point class to Angelscript

    I mean instead of doing: Point &opAssign(const int, const int) You should do this instead: Point &opAssign(const Point &in)
  13. Miss

    Exposing a Point class to Angelscript

    Yes, you're going about this the wrong way. Your opAssign() method needs to be passed a "const Point &in" instead of 2 integers, since that's what you're setting it to in your script.
  14. Miss

    MSVC optimization bug?

    Sorry, you're right, it is indeed cleaning the stack there, but at that point it's already too late. I should've added the code that is being returned to as well in my post. Here's the disassembly right after CallGlobalFunction, where it's using esi as thisptr (popped from the stack before the stack is cleaned up): 03EC65B1 E8 CA 73 00 00 call asCScriptEngine::CallGlobalFunction (03ECD980h) preMessage.isSet = false; 03EC65B6 8B 45 08 mov eax,dword ptr [section] 03EC65B9 C6 86 BC 0B 00 00 00 mov byte ptr [esi+0BBCh],0 Basically, I think msvc is confusing the stdcall code with the cdecl code in the optimization. If there's an "add esp, 8" above "pop esi", everything would be fine. For reference, at the time of "pop esi", this is what the stack looks like: $ param1 $+04 param2 $+08 esi (thisptr)
  15. Miss

    MSVC optimization bug?

    Not sure if this is an Angelscript bug or somehow an MSVC bug. I'm compiling Angelscript 2.23.0 on 32 bit in release build using platform toolset v141 and SDK 8.1, 10.0.x.0 (I've tried 8.1, 10.0.16299.0, and 10.0.17134.0) Though it's quite strange, because this only started happening on 1 project after the most recent Visual Studio 2017 update. (It seems to be fine in another project, which is using the 8.1 SDK, but that project is also a custom build from GENie, this project is built from the msvc2015 folder that comes with Angelscript itself.) The problem I'm seeing comes from the script engine message callback. I'm registering it like this, as a CDECL call: int r = 0; m_engine->SetMessageCallback(asFUNCTION(ScriptMessageCallback), nullptr, asCALL_CDECL); assert(r >= 0); And the actual function is empty: (actually commented out just to test this problem) static void ScriptMessageCallback(const asSMessageInfo *msg, void *param) { } Which results in a single "ret" instruction in memory. This makes sense, it's a cdecl call, so the caller does the cleanup. So, this function is eventually called on some script error. The actual call to the function is in "asCScriptEngine::CallGlobalFunction". In the debug version of Angelscript, the assembly is fine: 03F22B9F 8B 45 0C mov eax,dword ptr [param2] 03F22BA2 50 push eax 03F22BA3 8B 4D 08 mov ecx,dword ptr [param1] 03F22BA6 51 push ecx 03F22BA7 FF 55 F0 call dword ptr [ebp-10h] 03F22BAA 83 C4 08 add esp,8 In the release build it works a little different, it sets up the call and calls the function, but it doesn't clean up the stack: 0400C461 56 push esi 0400C462 8B 30 mov esi,dword ptr [eax] 0400C464 83 FA 02 cmp edx,2 0400C467 74 5F je asCScriptEngine::CallGlobalFunction+88h (0400C4C8h) ... 0400C4C8 FF 75 0C push dword ptr [param2] 0400C4CB FF 75 08 push dword ptr [param1] 0400C4CE FF D6 call esi 0400C4D0 8B 4D F4 mov ecx,dword ptr [ebp-0Ch] 0400C4D3 64 89 0D 00 00 00 00 mov dword ptr fs:[0],ecx 0400C4DA 5E pop esi 0400C4DB 8B E5 mov esp,ebp 0400C4DD 5D pop ebp 0400C4DE C2 10 00 ret 10h Note that "esi" on the first instruction above is the thisptr, and is how the caller eventually picks up thisptr again. Since the stack is not cleaned up (before esi is restored at "pop esi"), esi actually ends up being param1. Even if I explicitly write the function pointer as __cdecl, it doesn't clean up the stack in time: (results in the same assembly) typedef void (__cdecl *func_t)(void *, void *); func_t f = (func_t)(i->func); f(param1, param2); For reference, here's the CallGlobalFunction C++ code directly from Angelscript: void asCScriptEngine::CallGlobalFunction(void *param1, void *param2, asSSystemFunctionInterface *i, asCScriptFunction *s) const { if( i->callConv == ICC_CDECL ) { void (*f)(void *, void *) = (void (*)(void *, void *))(i->func); f(param1, param2); } else if( i->callConv == ICC_STDCALL ) { typedef void (STDCALL *func_t)(void *, void *); func_t f = (func_t)(i->func); f(param1, param2); } else { // We must guarantee the order of the arguments which is why we copy them to this // array. Otherwise the compiler may put them anywhere it likes, or even keep them // in the registers which causes problem. void *params[2] = {param1, param2}; asCGeneric gen(const_cast<asCScriptEngine*>(this), s, 0, (asDWORD*)&params); void (*f)(asIScriptGeneric *) = (void (*)(asIScriptGeneric *))(i->func); f(&gen); } } What's going on here? Am I missing something? Do I need to report this as an optimization bug to Microsoft? Do I need to make this a stdcall for some reason..?
  • 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!