Advertisement

JIT Compiler Suspend / BlindMindStudios

Started by April 08, 2016 01:40 PM
0 comments, last by GGLucas 8 years, 7 months ago

When using the BlindMindStudio JIT compiler, functions that suspect the active context are called twice. The first time within a JIT block, the second from the AngelScript VM, and with the stack not properly set up for the call.

I suspect this issue is a bug in BlindMindStudio's JIT compiler rather than in AngelScript, but I don't know quite enough yet to be sure.

When a context is suspended from a function called with a JIT block, it appears that the program pointer doesn't properly advance to the "next line." The VM advances from the asBC_JitEntry instruction to the asBC_CALLSYS instruction. If I remove the call to asIScriptContext::Suspend, then the VM doesn't ever process the asBC_CALLSYS instruction.

I have included an example below that demonstrates the problem.


#include <iostream>
#include "angelscript.h"
#include "as_jit.h"
using namespace std;

void Yield(int arg)
{
	cout << "Performing Yield... arg = " << arg << endl;
	asGetActiveContext()->Suspend();
}

int main(int argc, char* argv[])
{
	asIScriptEngine* engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
	asCJITCompiler* jit = new asCJITCompiler(0);
	engine->SetEngineProperty(asEP_INCLUDE_JIT_INSTRUCTIONS, 1);
	engine->SetJITCompiler(jit);

	int r;
	r = engine->RegisterGlobalFunction("void Yield(int)", asFUNCTION(Yield), asCALL_CDECL);
	asIScriptModule* mod = engine->GetModule("module", asGM_ALWAYS_CREATE);

	const char* sz_code = "int main() { Yield(5); return 0; }";

	mod->AddScriptSection("main", sz_code);
	r = mod->Build();

	asIScriptContext* ctx = engine->CreateContext();
	asIScriptFunction* func = mod->GetFunctionByName("main");
	ctx->Prepare(func);
	do
	{
		r = ctx->Execute();
	} while (r == asEXECUTION_SUSPENDED);

	int return_value = ctx->GetReturnDWord();
	ctx->Release();

	engine->Release();
	delete jit;
	return return_value;
}

Thanks for the detailed report and the reproduction case. It was indeed returning control to the VM at the wrong instruction (before the call instead of after) when suspending.

I've pushed a fix into the jit repository. It passes the test case you posted, tell me if you see any other problems with suspending contexts.

This topic is closed to new replies.

Advertisement