priw8 / ecljs Goto Github PK
View Code? Open in Web Editor NEWECL interpreter in js
ECL interpreter in js
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:
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.
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.