7

I'm trying to run a program built with GHCJS using node.js. However, I get the following error:

SyntaxError: Too many variables declared (only 131071 allowed)
    at Module._compile (module.js:439:25)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:906:3
  1. Is it possible to increase the number of allowed variables in node?
  2. Is there a better utility for running JS files which would allow for more variables
  3. Are there optimization tools which could automatically reduce the number of variables?

Note that this is machine generated JS, so I have no desire to go through by hand and reduce the number of variables.

Any ideas are welcome.

tibbe
  • 8,809
  • 7
  • 36
  • 64
jmite
  • 8,171
  • 6
  • 40
  • 81
  • 5
    That's actually a limitation of the javascript engine v8, it cant handle more than 131071 var definitions, so you can't increase it. – mfreitas Aug 16 '14 at 22:09
  • 2 and 3: That depends, what are you *actually* doing here? Is this an error when you simply `require()` that module in, or is this caused by you then adding your code on top of that? Because that many variables is really, **really** a lot and the only worthwhile optimization would likely be a rewrite of your own code to something more sane. – Mike 'Pomax' Kamermans Aug 17 '14 at 03:37
  • 3
    @Mike'Pomax'Kamermans Well, it's tagged with GHCJS, which is a haskell -> JS compiler. So, it's generated code that he doesn't have much control over. – Carl Aug 17 '14 at 07:23
  • 1
    Just to update, I was able to get the size down to 4 MB using the closure-compiler, so that should help. – jmite Aug 17 '14 at 22:27

1 Answers1

5

Must be a pretty big program :)

I have run into the variables limit on very old node versions (32k) but not yet into the new raised limit. The problem is similar to the Windows DLL symbols limit causing problems with dynamic linking, and possibly just as annoying.

GHCJS emits all generated code as top-level functions and variables for efficiency and simplicity (closures are handled by the STG implementation, so nested functions are not necessary here).

The limit only applies to local (function) scopes. Unfortunately, node.js uses a module system, and loads all code implicitly into a local scope.

Fortunately JavaScript gives us a way to still declare global names from a local scope, you just need to remove the var keyword! I think you should be able to run the script if you replace all var h$ at the beginning of a line with h$.

Alternatively you can try running the script with the SpiderMonkey JS shell or in a browser, but these give you a more limited environment (no filesystem access, cannot start or interact with other processes).

If the variable limit remains a problem for you, please open a ticket at https://github.com/ghcjs/ghcjs/issues so we can try to find a more permanent solution (probably by adjusting the link-time transformation step to divide the generated code into multiple modules).

luite
  • 66
  • 1