====== JavaScript ======
Synchronet's JavaScript runtime is shared by every server-side script: terminal-server logon/logoff, services scripts, timed events, external programs, server-side JavaScript (SSJS) on the web server, and standalone runs from [[util:jsexec]].

Each Synchronet server (Terminal, Mail, FTP, Web, Services) can have its own JavaScript runtime tuning, or inherit a global default.  These settings are exposed in three places:

  * **SCFG**: //Servers › Global Settings › JavaScript Settings// (the global default), and the same //JavaScript Settings...// menu under each individual server's configuration (per-server override).
  * **Synchronet for Windows** [[monitor:sbbsctrl|Control Panel]] (File › Properties › JavaScript tab):

{{:config:sbbsctrl_js_settings.png?300}}

  * **The [[.ini files]]** ([[sbbs.ini]], [[services.ini]], [[jsexec.ini]]) for direct editing or scripted deployment.

Per-server values override the global default.  Changes take effect after the affected server is **recycled** (or Synchronet is restarted).

===== Settings =====

^ Key                   ^ SCFG label (//JavaScript Settings//) ^ Default Value  ^ Description ^
|''JavaScriptMaxBytes'' | //Heap Size// | ''16M''           | Maximum bytes the JavaScript runtime may allocate for one script invocation before a forced garbage collection |
|''JavaScriptTimeLimit'' | //Time Limit// | ''864000''        | Maximum number of operation callbacks before a script is forcibly terminated (infinite-loop guard); ''0'' = disabled |
|''JavaScriptGcInterval'' | //GC Interval// | ''100''          | Operation callbacks between periodic garbage-collection attempts; ''0'' = disabled (heap-size forced GC still runs) |
|''JavaScriptYieldInterval'' | //Yield Interval// | ''10000''     | Operation callbacks between voluntary CPU yields; ''0'' = disabled |
|''JavaScriptLoadPath''     | //Load Path// | ''load''   | Additional directories (comma-separated) searched by JavaScript ''load()'' when a script imports a library |
|''JavaScriptOptions''      | (not in SCFG) | ''COMPILE_N_GO'' | See [[#Options]] below |

==== "Operation callbacks" ====
Three of the settings above (//Time Limit//, //GC Interval//, //Yield Interval//) are measured in **operation callbacks**, not in wall-clock time.  An operation callback is a hook the SpiderMonkey JavaScript engine fires after every //N// branch operations (loops, function calls, etc.).  How many wall-clock seconds a given count corresponds to therefore depends on the script's workload: a tight loop fires callbacks much faster than an I/O-bound script.

Earlier versions of this page (and a comment in ''sbbs.ini'') described these as "ticks (100ms)" — that is **incorrect**; they are not wall-clock ticks.

===== Notes =====

=== JavaScriptMaxBytes ===
Default: ''16M''

Maximum heap size per script invocation before SpiderMonkey forces a garbage collection.  Raise this if scripts run out of memory; lower it if many concurrent scripts run together and the total memory footprint matters more than the per-script ceiling.

Accepts a byte count with optional ''K''/''M''/''G'' suffix (e.g. ''160M'').

=== JavaScriptTimeLimit ===
Default: ''864000''

Maximum number of operation callbacks (see [[#Operation callbacks]] above) before a JavaScript script is forcibly terminated (//infinite-loop detection//).

Set to ''0'' for unlimited (disables infinite-loop detection — **required** for long-running service scripts that legitimately never return).

Note: This key replaces the old ''JavaScriptBranchLimit'' key, which is no longer used (as of Synchronet v3.16).

=== JavaScriptGcInterval ===
Default: ''100''

Operation callbacks between periodic garbage-collection attempts.  Lower values = more frequent GC = lower peak memory but more CPU overhead.

Set to ''0'' to disable periodic GC.  Heap-size-driven forced GC (when ''JavaScriptMaxBytes'' is reached) still runs.

=== JavaScriptYieldInterval ===
Default: ''10000''

Operation callbacks between voluntary CPU yields.  Letting the JS runtime yield gives other threads in the same Synchronet process a chance to run while a long script executes.

Set to ''0'' to disable voluntary yielding.

=== JavaScriptLoadPath ===
Default: ''load''

Comma-separated additional directories searched by the JavaScript ''load()'' function (relative to ''[[dir:exec]]'' and ''[[dir:mods]]'').

These supplement the built-in ''load'' directory, which is always searched.


===== Options =====
The optional ''JavaScriptOptions'' bit-field key controls SpiderMonkey compiler/runtime flags.  Multiple flags may be combined by bit-wise ORing them together with the ''%%|%%'' symbol.

^ Option               ^ Description ^
| ''STRICT''           | Warn on dubious practice (similar to ''%%"use strict"%%'') |
| ''WERROR''           | Convert warnings to fatal errors |
| ''VAROBJFIX''        | Use the last object of scope chain as the ECMA 'variables object' |
| ''COMPILE_N_GO''     | Compile-time scope chain resolution of ''const''s |
| ''RELIMIT''          | Disallow excessively recursive regular expressions |
| ''ANONFUNFIX''       | Disallow ''function () {}'' in statement context per ECMA-262 Edition 3 |
| ''JIT''              | Enable TraceMonkey just-in-time compiler |
| ''METHODJIT''        | Enable JägerMonkey just-in-time compiler |
| ''PROFILING''        | Use profiler to choose between TraceMonkey and JägerMonkey at run-time |
| ''METHODJIT_ALWAYS'' | Always use the JägerMonkey JIT compiler (don't tune at run-time) |

The default JavaScript option flags (when the key is not specified) are:
  COMPILE_N_GO

''JIT'' (TraceMonkey) was previously enabled by default but is now **off** to avoid a class of cold-property-read bugs in SpiderMonkey 1.8.5's trace recorder.  It can still be re-enabled explicitly via ''JavaScriptOptions = JIT %%|%% COMPILE_N_GO'' if desired; expect occasional ''undefined'' results for properties read for the first time inside a hot loop.

===== See Also =====
  * [[:config:|config index]]


{{tag>configuration javascript general_config ini}}
