Giter Club home page Giter Club logo

ecljs's People

Contributors

priw8 avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

ecljs's Issues

async sub ID handling: how does it actually work?

With the recent reverse-engineering of th17 I did, I found out that the async sub list is actually stored as a linked list. This brings some questions as to how the calls with IDs actually work. Previously, I assumed that they were stored in a fixed-length array, with the index of a particular VM being the ID used to create it. This meant that only 1 VM can have a given ID at a time. However, since they are actually stored in a different way, a few things have to be checked:

  • is there actually any limit to what the ID can be? Considering how the VMs are stored, there probably isn't.
  • does creating a VM with an ID that's alredy occupied by another one cause the other one to be deleted? Or pethaps creation fails? Or, maybe they both run at once? How does killAsync work in this case? What IDs do VMs created without an ID have?

It is very likely that with how it's implemented right now, it doesn't properly reflect what the game actually does, and can lead to its behaviour not being properly replicated.

properly emulating some wacky stack manipulations

It is no secret that with the current implementation of stack in ECLjs, some behaviour will not be properly replicated. In particular, doing some manipulations with the instr.popCnt property and stackAlloc instruction will most definitely NOT do what the game does. For starters, the stackAlloc instruction should be implemented exactly how it works in the game (illustrated by this C-like pseudocode):

eax = getIntArg(0);
edx = vm.stack.sp;
if (edx + eax < 4096) {
   vm.stack.sp += eax;
   eax = vm.stack.bp
   vm.stack.data[vm.stack.sp] = eax;
   vm.stack.sp += 4;  // bytes
   vm.stack.bp = edx;
}
break;

Most notably, the base pointer is pushed after increasing the stack pointer, and as of now ECLjs does it in reverse order. The stack also starts completely empty when the initial sub is called, and in ECLjs it starts with some things the interpreter can properly pop after coming across the ret instruction. Instead of checking these values to determine whether the VM finished execution, it should instead check if the stack is empty or not.

Something that also has to be checked is how the return address is stored by the game. It most likely doesn't have a separate stack for it, but what it does exactly is unknown. Though, properly replicating this in ECLjs would require putting all loaded ECL files in the same ArrayBuffer, in order to avoid having to push the ECLfile object to the stack, and instead just push 1 offset of the position in the ArrayBuffer.

And finally, reading from unaligned stack offsets. This is something the game doesn't do normally, but you can force it to do it by using instr.popCnt or stackAlloc with numbers that aren't multiplies of 4. ECLjs can't do that at all because of how the stack is implemented. Now the question is, how to implement it properly without degrading the performance? Using DataView to handle the stack would certainly make it accurate, but DataView is slower than just reading or writing the numbers stored normally. I'm not sure whether it would actually impact the performance that much though. Another solution is creating an ArrayBuffer for the stack, and then creating Int32Array and Float32Array from it, and then using the DataView only for reading numbers from unaligned offsets, which I think should be faster than using DataView for everything.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.