0

I am working on a tool dedicated to compression for demoscene, initiated for js1k and targeted to prods in the 1k-4k categories. The current difficulty I am facing is to have it work and produce the exact same results in both browser and Node.js environments.

One of its feature requires knowing all methods and properties of 2D, GL and Audio contexts. It also needs the values for GL constants. No method is ever invoked though, so the actual implementation is not needed.

EDIT - an example to give a better understanding of what is going on

The original uncompressed code given to the packer looks like this (after stripping lines not relevant here, such as those adding colors to n)

c=a.getContext("2d");
e=c.getImageData(0,0,150,150);
c.fillStyle=n=c.createRadialGradient(225,75,25,225,75,60);
c.fillRect(150,0,150,150);

The packer computes the best hash, in this case i[0]+i[6]. It then replaces the methods in the code, and prepends a loop to perform the hashing (the output is standalone, thus it contains the decompression routine). Otherwise at runtime, the js interpreter would have no way to understand that c.cR() is actually context.createRadialGradient(). Here is the resulting code :

for(i in c=a.getContext("2d"))c[i[0]+i[6]]=c[i];
e=c.gg(0,0,150,150);
c.fillStyle=n=c.cR(225,75,25,225,75,60);
c.fc(150,0,150,150);

In case of a collision (several methods resulting in the same hashed string), the replacement is not performed.

Inside the browser, one can simply create an instance of the appropriate context and iterate on its methods/properties. However, Node.js does not provide this possibility. I need another way to obtain that information.

The answers to similar questions (2d canvas or WebAudio) suggested the use of Canvas module or Node WebAudio API. However, these modules are not a perfect mirror of their browser counterparts, having either additional methods, or a subset thereof. This will in some cases cause the hashing algorithm to produce a different output.

Unfortunately, this rules out the solution, as the same result is needed in both environments. What other options are possible ? Thanks in advance.

Community
  • 1
  • 1
Siorki
  • 183
  • 8
  • 1
    why does it matter if the paths your compressor finds are standard or not? as long as they are consistent, it should be fine. your compressor should not use a dictionary, as web properties change all the time... – dandavis Jun 23 '15 at 21:50
  • @dandavis Edited to add a sample. The compressed code, along with the added unpacking routine, is intended to be run in the browser. So if the hashing results are not consistent, one could pack a demo under node.js, and produce code that will not run properly in the browser (a collision that did not happen under node.js for instance). – Siorki Jun 24 '15 at 22:32
  • that won't work as-coded. pretend they add a new property called "3dalpha" to the context; anything that came after that would have an index off by 1, and old scripts would break. you need to ship both the substitutions and the full replacements, which means that unless `createRadialGradient` is used more than once, it's not worth replacing. – dandavis Jun 25 '15 at 01:37
  • The demos only need to be below size limit and work in current browser. They are not required to be future-proof, so browser API changes at a later time are not much of a concern. Furthermore, the algorithm does not rely on numerical indexes of properties (which differ amongst browsers anyway), so the addition of a new one may only break old scripts if the hash creates a collision. The tool already works well inside the browser, see the [online version](http://siorki.github.io/regPack.html) – Siorki Jun 27 '15 at 22:03

0 Answers0