wren-lang / wren

The Wren Programming Language. Wren is a small, fast, class-based concurrent scripting language.
http://wren.io
MIT License
6.86k stars 550 forks source link

Can't Interpret more code after calling functions with virtual machine #640

Open Skyway666 opened 5 years ago

Skyway666 commented 5 years ago

Hi again!

I was trying to iterate all my script files, compile them and then call the constructor of each class to get an instance of it.

With more than one script, the code would crash, and after some debugging I realized that the new() fuction was being called on "Null", in the second script I was processing.

Essentially the code was something like this:

std::string dummy_code = App->fs.GetFileString("Assets/dummy.wren");
std::string console_test_code = App->fs.GetFileString("Assets/Scripts/console_test.wren");

wrenInterpret(vm, "dummy", dummy_code.c_str());
wrenEnsureSlots(vm, 1);
wrenGetVariable(vm, "dummy", "dummy", 0);
wrenCall(vm, base_signatures.at("new()"));
wrenGetSlotHandle(vm, 0);

wrenInterpret(vm, "console_test", console_test_code.c_str());
wrenEnsureSlots(vm, 1);
wrenGetVariable(vm, "console_test", "console_test", 0);
wrenCall(vm, base_signatures.at("new()"));
wrenGetSlotHandle(vm, 0);

I guessed that it was because I was interpreting more code when I already used the vm to call code, I tried this out, and it worked

std::string dummy_code = App->fs.GetFileString("Assets/dummy.wren");
std::string console_test_code = App->fs.GetFileString("Assets/Scripts/console_test.wren");

wrenInterpret(vm, "dummy", dummy_code.c_str());
wrenInterpret(vm, "console_test", console_test_code.c_str());

wrenEnsureSlots(vm, 1);
wrenGetVariable(vm, "dummy", "dummy", 0);
wrenCall(vm, base_signatures.at("new()"));
wrenGetSlotHandle(vm, 0);

wrenEnsureSlots(vm, 1);
wrenGetVariable(vm, "console_test", "console_test", 0);
wrenCall(vm, base_signatures.at("new()"));
wrenGetSlotHandle(vm, 0);

Since there is no explanation about such constraints when using wrenInterpret() in the documentation, I wanted to make sure this was not a bug.

Also, it'd be nice to know if there is a way around it, since it is much more confortable for me to do it this way, although if there isn't, it is perfectly fine as well, I'm just curious.

mhermier commented 5 years ago

You are probably hitting the callframe stack corruption bug. The short term solution is to increase the default stack frame untill it is correctly fixed.

I have a patch, but don't know how to submit it. It is available in 2 parts in my fork, because they are 2 issues in fact around the same part of code.

Skyway666 commented 5 years ago

Is increasing the default stack frame a big deal? I don't really know what you mean by that, I am only a API user right now and don't know how it works internally :(

mhermier commented 5 years ago

In src/vm/wren_value.c the is a INITIAL_CALL_FRAME defined to 4, change it to something bigger,like 16 or 32 (there is no power of 2 reuirement, but it replicate internal stack grow behavior)

Skyway666 commented 5 years ago

I tried it, sadly it doesn't seem to fix the problem

mhermier commented 5 years ago

The proper fix is in https://github.com/wren-lang/wren/pull/641 from my experiment it is correct, but I'm not satified with the resulting code. The fact that [STORE/LOAD]_FRAME is unbalanced make it look unfinished.

Skyway666 commented 5 years ago

For the moment I just interpret all the scripts first and then call them or do whatever, but if the error shows up again, I hope that the branch has been merged so I can download the files again.

Thank you very much!

munificent commented 5 years ago

Hi, can you try to repro this with the latest Wren? I fixed a nasty bug where the API stack can get mangled that I think might be what you're running into. I'm not sure if my fix affects your case, but there's a good chance it does.

Skyway666 commented 5 years ago

Hi!

Luckily I managed to finish my project without any more issues by having all the scripts being interpreted at the beggining:

https://skyway666.github.io/Kuroko-Engine/

This was the final result of the project, which got me a really good grade for my subject.

Anyways, I'll be updating the Wren version, since we are starting a huge project in which we have to develop a videgame with an engine of our own, and Wren will be used as the scripting language to manage all the other high level system (particles, animations, physiques, UI...).

I hope I don't have to, but probably I'll be asking for some help in the future. My main concern is that Wren does not support saving the bytecode generated after the interpreter fase, which might slow down too much the loading of our game.

I saw there was already a thread talking about this, has there been any update?

munificent commented 5 years ago

I saw there was already a thread talking about this, has there been any update?

I did conveniently add a comment on #625 giving some background, but no, there hasn't been any action and probably won't be any time soon (if ever). It's a big, difficult change.

You might be surprised by how fast the compiler is, and it may not be as much of a hindrance as you fear. But, of course, it's always important to be cognizant of this stuff and measure it for yourself since you know your needs best. It wouldn't hurt to write a script that generates a big pile of synthetic Wren code and runs it all through the compiler to see how fast it loads.

Skyway666 commented 5 years ago

Thanks for the advice, wren is awesome!

ruby0x1 commented 5 years ago

p.s I have fairly substantial projects using wren (editors etc) and i've never noticed any load time for scripts.