window.markdeepOptions={tocStyle:"medium"} Misc

Contents

Miscellaneous
  1.1  Options
  1.2  Introspection
  1.3  Web Servers
    1.3.1  Chroot Setup
  1.4  Syntax
    1.4.1  Expressions
    1.4.2  Terminals
    1.4.3  Keywords
  1.5  Language Comparisons
  1.6  License
    1.6.1  Libwebsockets
    1.6.2  Others
  1.7  Design and Origin
  1.8  ECMA Compatibilty
  1.9  Goals
  1.10  Shortcomings
  1.11  Rational

Javascript Shell Interpreter
 DOWNLOAD / DEVELOP / DEPLOY

Types Builtin Reference  Index  Fossil  Demos Log Test Debug Misc

   

Miscellaneous

   

Options

Options are parameters handled by builtin commands. These get passed in an object:

var db = new Sqlite('/tmp/testsql.db',{maxStmts:1000, readonly:true});

Usually there is a conf() method providing access to options after creation:

Interp.conf(); // Dump all options
Interp.conf('strict'); // Get one option
Interp.conf({strict:false, maxDepth:99}); // Set one or more options.

Some options may be readOnly. And an option that is initOnly may only be set at object creation time.

Internally, option parsing is implemented via C Options.

   

Introspection

There are several levels of introspection built-in to Jsi. One is displayed when calling an invalid method:

Array.xxx();
error: 'Array' sub-commands are: concat fill filter forEach indexOf join lastIndexOf map pop push reverse shift sizeOf slice some sort splice unshift. (at or near "xxx")

Another, is querying with the Info command:

Info.platform();
{ crc:7, hasThreads:true, intSize:4, isBigEndian:false, numberSize:8, os:"linux", platform:"unix", pointerSize:8, timeSize:8, wideSize:8 }
Info.cmds();
[ "Array", "Boolean", "File", "FileIO", "Function", "Interp", "Info", "JSON", "Math", "Number", "Object", "RegExp", "Signal", "Sqlite", "String", "Sys", "Websocket", "Zvfs", "assert", "clearInterval", "console", "decodeURI", "encodeURI", "exit", "source", "isFinite", "isNaN", "load", "parseFloat", "parseInt", "puts", "quote", "setInterval", "setTimeout", "format" ]
Info.cmds('Array.*');
[ "concat", "fill", "filter", "forEach", "indexOf", "join", "lastIndexOf", "map", "pop", "push", "reverse", "shift", "sizeOf", "slice", "some", "sort", "splice", "unshift" ]
Info.named();
[ "Socket", "Channel", "MySql", "WebSocket", "Sqlite", "Interp" ]
var ii = new Interp();
Info.named('Interp');
[ "#Interp_1" ]

and so on.

   

Web Servers

Although Jsi can serve web content directly, on the Internet it is more common to use “nginx” as a reverse proxy via localhost:

location /App00/Ledger { proxy_pass http://localhost:8800; include proxy_params; }

And jsish might be invoked as:

jsish -a jsi-app.fossil Ledger -port 8800 -urlPrefix /App00/Ledger -noGui true

Or run via chroot/su.

   

Chroot Setup

Given it's small size, jsish is well suited for chroot deployments. On the jsish.org site the user jsiusr00 was created with directory contents:

ls -RF jsiusr00
jsiusr00: bin/ dev/ etc/ ledgerjs.db tmp/ usr/ jsiusr00/bin: fossil* jsish* jsiusr00/dev: null random urandom jsiusr00/etc: hosts resolv.conf jsiusr00/tmp: jsiusr00/usr: jsi-app.fossil jsi-app.sqlar jsi-app.zip ledgerjs.db

To scale this up while saving space, multiple users “jsiusrNN” are created with readonly files hard-linked to “jsiusr00". Finally “chattr +i” is used make them immutable. Thus incremental size for each additional user is really only the data file “ledgerjs.db”.

du -s jsiusr*
12468 jsiusr00 980 jsiusr01 960 jsiusr02 960 jsiusr03 ... 1224 jsiusr10 960 jsiuser11 ... 960 jsiuser19

All previous directories have no shell, so with the addition of quotas and ulimits we end up with a deployment that is simple but secure.

The slight bump in “jsiusr10" is due to the addition of “sh”, to allow execing fossil in a chroot.

   

Syntax

The following syntax is implemented by Jsi (see Reference for commands):

continue [IDENT] ;
break [IDENT] ;
debugger ;
delete IDENT ;
do { STMTS; } while( EXPR ) ;
for ([var] IDENT = EXPR; EXPR; EXPR) { STMTS; }
for ([var] IDENT in EXPR) { STMTS; }
for ([var] IDENT of EXPR) { STMTS; }
function [IDENT] ([IDENT, IDENT, ...]) { STMTS; }
function [IDENT] ([IDENT:*TYPE*[=*PRIMATIVE], IDENT*:*TYPE*[=PRIMATIVE], ...]):TYPE { STMTS; }
if (EXPR) { STMTS; } [ else { STMTS; } ]
IDENT instanceof IDENT ;
[new] FUNC( ARGS ) ;
return [EXPR] ;
switch (EXPR) { case EXPR: STMTS; [break;] case EXPR: STMTS; [break;]  ... [default EXPR;] }
throw EXPR ;
try { EXPR; } catch(IDENT) { STMTS; } [finally { STMTS; }]
typeof EXPR ;
var IDENT [ = EXPR ] [, ...] ;
with ( EXPR ) { STMTS; }

   

Expressions

Expressions take the usual form:

IDENT*.*IDENT
IDENT*[*EXPR]
IDENT*(*ARGS)
(EXPR)
EXPR ? STMTS :  STMTS
STMTS , STMTS [, ...]
EXPR OP EXPR

where OP is one of the binary operators +, -, *, /, etc.

   

Terminals

Name Description
ARGS Zero or more comma-seperated arguments
EXPR An expression (see below)
FUNC A function value
IDENT Is an valid identifier
PRIMITIVE A primitive value acceptable as an argument type.
STMTS Is zero or more statements
TYPE A type value acceptable as defaults

   

Keywords

Keywords can be displayed using Info.keywords():

  "...", "any", "arguments", "array", "boolean", "break", "case", "catch",
  "continue", "debugger", "default", "delete", "do", "else", "false",
  "finally", "for", "function", "if", "in", "instanceof", "new", "null",
  "number", "object", "of", "regexp", "return", "string", "switch",
  "this", "throw", "true", "try", "typeof", "undefined", "userobj", "var",
  "void", "while", "with"
   

Language Comparisons

Following is a feature comparison of various languages with Jsi.

Feature Jsi NodeJs Tcl Lua Perl Python
Standard ES 5.2+ ES 6+
Implemention C/C++ C++ C C/C++ C C
C++ Compatible Y Y
Embeddable Y N Y Y Y Y
C API Y N Y Y Y Y
Non-Script API Y
Standalone Y Y Y
Type Checking Y
Sub-Interps Y
Introspection Y
Error Navigation Y
Logging Y
Builtin Debugger Y Y Y
Debugger GUI Y
Web Ready Y
Modular Apps Y
Shrink Wrap Y Y
Applications Y
Self Configure Y

These comparisons are of software out-of-the-box.

As of version 5.3.4, Lua also supports native C++.

   

License

Jsi source is covered by the following MIT license:

The MIT License (MIT)

Copyright (c) 2013 Peter MacDonald

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
   

Libwebsockets

Jsi links agains Libwebockets, which is covered by LGPL with an extra clause allowing static linking.

Libwebsockets and included programs are provided under the terms of the GNU
Library General Public License (LGPL) 2.1, with the following exceptions:

1) Static linking of programs with the libwebsockets library does not
constitute a derivative work and does not require the author to provide
source code for the program, use the shared libwebsockets libraries, or
link their program against a user-supplied version of libwebsockets.

If you link the program to a modified version of libwebsockets, then the
changes to libwebsockets must be provided under the terms of the LGPL in
sections 1, 2, and 4.

2) You do not have to provide a copy of the libwebsockets license with
programs that are linked to the libwebsockets library, nor do you have to
identify the libwebsockets license in your program or documentation as
required by section 6 of the LGPL.

However, programs must still identify their use of libwebsockets. The
following example statement can be included in user documentation to
satisfy this requirement:

"[program] is based in part on the work of the libwebsockets  project
(http://libwebsockets.org)"

                  GNU LESSER GENERAL PUBLIC LICENSE
                       Version 2.1, February 1999
...

This seems to to say that as long as libwebsockets is not modified, all that is required is an acknowledgement in your user documentation.

   

Others

Other software including sqlite, miniz, jsmn, regex from musl, etc are either public domain, BSD or MIT compatible.

   

Design and Origin

Jsi is a Javascript interpreter written in C. Additional functionality, implemented with scripts is bundled as “jsish”.

Jsi is a byte-code oriented interpreter originally designed for interfacing-with, and embedding into C.

This makes it very different from Node-js which is a compiler written in C++, and which is not designed to be embedded.

Jsi is C-centric whereas Node is JS-centric. Meaning that with Jsi, the locus of control can resides in C-code.

Although Jsi was originally was based off source from quad-wheel, it is now internally modelled after Tcl.

   

ECMA Compatibilty

Jsi implements version 5.1 of the Ecma-script 262 standard, with the following deviations:

Extensions include:

   

Goals

Following are principle goals Jsi:

And while compiling as C++ is supported, it is mostly used for integrity checking.

C-integration is the main priority in Jsi, not speed of script execution.

   

Shortcomings

Following is a partial list of things that are either incomplete or unimplemented:

   

Rational

var startOfMarkDeep=true; window.alreadyProcessedMarkdeep||(document.body.style.visibility='visible'); document.title=location.pathname.match(/\/([\w]+)1;

formatted by Markdeep 1.03