how can i compile a script to an executable?

Started by
17 comments, last by brightening-eyes 9 years, 10 months ago
hi everyone, i'm developping a game engine for visually impaired users (firstly myself) i haven't any problem dirring the registration of the script functions and classes! now when i want to compile the script, i dont know how can i say to my engine to load main() and compile it firstly and set it as the entrypoint! and run it? this is my run and compile functions:
void run(const char* script)
{
CScriptBuilder builder;
int r;
r=builder.StartNewModule(engine, "build");
if(rWriteMessage(script, 0, 0, asMSGTYPE_ERROR, "can't run the script");
}
r=builder.AddSectionFromFile(script);
if(rWriteMessage(script, 0, 0, asMSGTYPE_ERROR, "the file can not be loaded");
return ;
}
asIScriptFunction *mainfunc=engine->GetModule("build", asGM_ONLY_IF_EXISTS)->GetFunctionByDecl("void main()");
asIScriptContext *ctx=engine->CreateContext();
if(mainfunc==nullptr)
{
engine->WriteMessage(script, 0, 0, asMSGTYPE_ERROR, "the function void main() has not been declared");
return ;
}
ctx->Prepare(mainfunc);
ctx->Execute();
}

void compile(const char *script, const char *output, bool debug)
{
	engine->SetEngineProperty(asEP_INIT_GLOBAL_VARS_AFTER_BUILD, false);
CScriptBuilder builder;
int r;
r=builder.StartNewModule(engine, "build");
if(rWriteMessage(script, 0, 0, asMSGTYPE_ERROR, "can't compile the script");
}
r=builder.AddSectionFromFile(script);
if(rWriteMessage(script, 0, 0, asMSGTYPE_ERROR, "the file can not be loaded");
return ;
}
r=builder.BuildModule();
if(rGetModule("build", asGM_ONLY_IF_EXISTS);
compilerstream comp;
r=comp.open(output);
if(rWriteMessage(output, 0, 0, asMSGTYPE_ERROR, "the file can not be loaded for compilation");
return ;
}
compiler->finalizePages();
mod->SaveByteCode(&comp, !debug);
}
the problem is, i dont know how to load main() and set it as my executables main function! my mean is, when user run the executable, the game runs and executes main() and this happens when user runs the script from the engine! what should i do? thanks so much!

when you can't see well like me, you can't test your applications and you can't read something

Github

Advertisement

Hi Amir,

glad to see you're still trying.

The code you posted above seems to have been messed a bit by the forum. But it looks like you have pretty much gotten the hang of how to use AngelScript.

Your run function seems to be trying to build the script too. Was that intentional? Or did you mean to have the run function call the compile function to compile the script and then execute it?

Anyway, it seems your question is not on how to compile and execute scripts, but rather how you should go about packaging it all into a executable, so that when the user starts the application it will automatically do everything without having to rely on extra files. Am I right?

I've never done something like this myself, but I think you ought to be able to simply concatenate the script files to end of your compiled executable, and then have the application read the script from the executable file itself. You would also have to add an integer to the end to give the size of the concatenated script files. The application would then open the executable file, go to the end of the file, read the offset, move the pointer back to the start of the script and then read the script from there.

I believe this is pretty much how self-contained installers work.

Regards,

Andreas

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

yep, my mean is, how can i create an executable from my scripts?

and, how can i say to my script to run the main function?

for example:


void main()
{
message("ok", "the script runned!\n");
}

when i want to run this script, it executes void main() and when i've compiled it, it happens again and execute's void main() and run it!

how can i do that? how can i created like a windows executable using ByteCodes?

i think my compile and run functions have some problems!

and some questions:

1. how can i detect the offset of the script!

2. how can i tell my script to load void main() when the script wants to run?

3. how can i turn my script to an executable?

thanks for your help!

when you can't see well like me, you can't test your applications and you can't read something

Github

You'll need to implement a 'packager' (for lack of a better word).

The packager will take the executable that you implemented in C++ and has the logic to register the interface with the script engine, load a script from bytecode and then execute it. Basically it will do the following:

  1. open a new file for output: lets call it "game.exe"
  2. copy the executable implemented in C++ into "game.exe"
  3. size_t offset = size of the file after including the executable
  4. copy the pre-compiled bytecode to file after the executable
  5. write the offset as the last part of the "game.exe"
  6. close the file and set the file permissions as executable

That ought to work. (though I've never tried it myself).

I would like to give you an advice though. Packaging the game into a single executable really ought to be your last concern. Concentrate on making everything else work first.

Take it one step at a time. It will be much easier that way.

To execute the 'main()' function from the script you'll do it the way you've implemented it in your run() function, i.e.

void run()
{
  asIScriptFunction *mainfunc = engine->GetModule("build", asGM_ONLY_IF_EXISTS)->GetFunctionByDecl("void main()");
  if( mainfunc == nullptr )
  {
    engine->WriteMessage(script, 0, 0, asMSGTYPE_ERROR, "the function void main() has not been declared");
    return ;
  }
  asIScriptContext *ctx = engine->CreateContext();
  ctx->Prepare(mainfunc);
  int r = ctx->Execute();
  if( r != asEXECUTION_FINISHED )
  {
    engine->WriteMessage(script, 0, 0, asMSGTYPE_ERROR, "The script terminated unexpectedly");
    // you can use the ctx to obtain more information on the type of error that occurred
  }
  ctx->Release();
}

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

well, now i have to say, windows executables have header on first and a footer on last of it!

now, how can i implement a packager? how can i know what script is loaded for compilation?

i have to copy the functions and classes on the executables!

now how can i do that? how can i use bytecodes for that?

if you saw, some of the applications that use angelscript have a compiler for exe files!

the problem is, how can i get the offset of that? how can i copy my functions and classes on the executable?

i think, i have to develop an assembler for that!

and a question is, what is that JIT compiler?

and a note:

executable files have some sections like .data, .text, .rsrc, .rdata, .bss and some other sections!

now, how can i implement that?

what is your idea?

when you can't see well like me, you can't test your applications and you can't read something

Github

OK. So then your packager needs to be a little more intelligent to update the header and footer of the windows executable too. Still I'm quite sure it will be easy enough once you know the format of the header and footer. I don't know this format, but I'm sure you'll find resources on the internet or even directly from MSDN that will tell you that.

You don't want to compile AngelScript to native machine code. It wasn't meant for that. If you are going to compile directly to native code, then you probably don't want to use AngelScript at all. In this case you'd probably be better of with C++ or C#.

Instead, your packager should be packaging the executable like I mentioned above and use the pre-compiled bytecode that you saved using the asIScriptModule::SaveByteCode. When your application starts up it should load the bytecode into a module using asIScriptModule::LoadByteCode, and then use the asIScriptContext to execute the script function the same way as if it had compiled the script normally.

I'm pretty sure the other applications that use AngelScript and build executables do it like this. It would be madness (though I confess, quite cool) to compile AngelScript into native machine code directly.

JIT stands for 'Just In Time'. It is basically a way of optimizing the bytecode, so that it runs even faster. What it does is that it transforms sequences of bytecode into native machine code. The VM will then run this native machine code instead of the bytecode. The VM is still necessary though, so you don't get rid of the AngelScript engine. With a JIT compiler the performance of the scripts becomes nearly as good as if the same code had been implemented in C++.

Regards,

Andreas

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

so, how can i copy the functions that i've registered in the application?

do i have to turn them into bytecode?

and then copy them into executable?

another thing is, how can i get the offset of the executables? the executable isn't created yet!

i've got a JIT compiler (not for the BlindmindStudios), and i'm working on it! how can i created like a packager? how computer can know AngelScript's language?

i'm sorry for my questions!

when you can't see well like me, you can't test your applications and you can't read something

Github

The functions you register with AngelScript must be in the executable that will in the end run the script.

The executable that will be packaged together with the script must have been built earlier using a normal C++ compiler, e.g. Microsoft's Visual C++. Since it will already exist when you run your packager it is just a matter of determining the size of the executable to determine the offset on where the script bytecode will start.

As for implementing it, now you'll have to do your own investigation. I've explained how I think it can be done, but I really don't have any more details to provide for you since I've never done anything like this myself.

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

thanks for your replys,
i'll think about that!
and i think, the script can be turned into assembly code, then turned into binary code and then, inside the functions, it will be runned!
but, i dont know how can i copy my functions that i've registered with AngelScript into the executable!
because when we are using our application, we dont have any C++ compiler!
and i need another segestion:
what is your idea about developing a JIT compiler with a packager together?
again, thanks for your help!

when you can't see well like me, you can't test your applications and you can't read something

Github

Yes, I suppose the JIT compiler can be made part of the packager, and then have the native code serialized together with the bytecode. It would probably reduce the load time when running the game, but increase the size of the file.

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

This topic is closed to new replies.

Advertisement