Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

🏖️ The safer and faster ECMA5.1 interpreter written by JavaScript

License

NotificationsYou must be signed in to change notification settings

sablejs/sablejs

Repository files navigation

LOGO

linux ciosx ciwindows ciVersion

🎉 sablejs 2.0 will be opening all the code, pleaseclick to learn more about our milestone and goals.

English |简体中文

The safer and faster ECMA5.1 interpreter written by JavaScript, it can be used:

  1. Sandbox (like Figma Plugin Sandbox, but better and easier to use);
  2. Protect JavaScript source code via AOT compiling to opcode.

sablejs covered ~95%test262 es5-tests cases, it can be safely used in production.

Quick Start

sablejs includes the Compiler and Interpreter independently, so we removed the related dynamic api from the spec (seeLimits 1). In short, you need to compile your JavaScript code with sablejs cli before you run it.

Example

Suppose we have the following code infib.js:

functionfib(n){returnn<2 ?n :fib(n-1)+fib(n-2);}varstart=Date.now();console.log("[INFO] fib: "+fib(30));console.log("[INFO] time consuming: "+(Date.now()-start)+"ms");

Compile It!

> npm i sablejs -g> sablejs -i fib.js -o output# get output file that contains base64 string

sablejs cli includes the following commands:

Usage: sablejs [options]Options:  -v, --vers           output the current version  -i, --input<path>   compile input filepath  -o, --output<path>  compile output filepath  -j  --json           don't do Base64 compress, output simple json result  -s, --slient         don't output log  -h, --help

Run It!

> npm install sablejs --save

or you can import to your html directly

<scriptsrc="https://cdn.jsdelivr.net/npm/sablejs@1.0.8/runtime.js"></script>
Browser
constVM=require("sablejs/runtime")();// import console.log function to vm callconstvm=newVM();constvGlobal=vm.getGlobal();constvConsole=vm.createObject();constvLog=vm.createFunction("log",function(){consttemp=[];for(leti=0;i<arguments.length;i++){temp.push(vm.asString(arguments[i]));}console.log(...temp);returnvm.createUndefined();});vm.setProperty(vConsole,"log",vLog);vm.setProperty(vGlobal,"console",vConsole);(async()=>{constresp=awaitfetch("<output url>");constdata=awaitresp.text();vm.run(data);vm.destroy();})();
Node
constVM=require("sablejs/runtime")();constfs=require("fs");// import console.log function to vm callconstvm=newVM();constvGlobal=vm.getGlobal();constvConsole=vm.createObject();constvLog=vm.createFunction("log",function(){consttemp=[];for(leti=0;i<arguments.length;i++){temp.push(vm.asString(arguments[i]));}console.log(...temp);returnvm.createUndefined();});vm.setProperty(vConsole,"log",vLog);vm.setProperty(vGlobal,"console",vConsole);// please run: sablejs -i fib.js -o outputvm.run(fs.readFileSync("./output").toString());vm.destroy();

APIs

  • VM.prototype.run(source, isSimpleJSON)
    • source: String - the compiled result via sablejs compiler
    • isSimpleJSON: Boolean - if be true, you should use-j to make compiler output simple json result, default false.
    • return: undefined

Initialize the VM and execute the compiled source code.

constVM=require('sablejs/runtime')();constvm=newVM();// source should be base64 string via sablejs compilingvm.run(`<compiled source string>`);
  • VM.prototype.getGlobal()
    • return: Value

Returns theglobal in the VM, which is similar to thewindow in browser and theglobal in Node.js.

constglobal=vm.getGlobal();
  • VM.prototype.createUndefined()
    • return Value

Create anundefined boxed type.

constvUndefined=vm.createUndefined();
  • VM.prototype.createNull()
    • return: Value

Create annull boxed type.

constvNull=vm.createNull();
  • VM.prototype.createBoolean(bool)
    • bool: Boolean
    • return Value

Create anbool boxed type.

constvBoolean=vm.createBoolean(true);
  • VM.prototype.createNumber(num)
    • num: Number
    • return Value

Create annumber boxed type.

constvNumber=vm.createNumber(1024);
  • VM.prototype.createString(str)
    • str: String
    • return Value

Create anstring boxed type.

constvString=vm.createString('Hello World!');
  • VM.prototype.createObject()
    • return Value

Create anobject boxed type.

constvObject=vm.createObject();
  • VM.prototype.createArray(length)
    • length: Number | undefined
    • return Value

Create anarray boxed type.

constvArray1=vm.createArray();// orconstvArray2=vm.createArray(128);
  • VM.prototype.createFunction(name, func)
    • name: String
    • func: Function
    • return Value

Create anfuncntion boxed type. It receives a function name and the specific implementation of the function. Both thefunction parameter andthis are boxed types infunc.

constvFunction=vm.createFunction("trim",function(str){// this is the undefined or new's instannce boxed type// str maybe the string boxed type, we need to check it});
  • VM.prototype.createError(message)
    • message: String | undefined
    • return Value

Create anerror boxed type.

constvError1=vm.createError();// orconstvError2=vm.createError("unknown error");
  • VM.prototype.createRegExp(pattern, flags)
    • pattern: String
    • flags: String | undefined
    • return Value

Create anregexp boxed type.

constvRegExp=vm.createRegExp("\\w+","ig");
  • VM.prototype.createDate()
    • return Value

Create andate boxed type.

constvDate=vm.createDate();
  • VM.prototype.isUndefined(value)
    • value: Value
    • return Boolean

Used to determine if the type isundefinend.

constvUndefined=vm.createUndefined();if(vm.isUndefined(vUndefined)){// ...}
  • VM.prototype.isNull(value)
    • value: Value
    • return Boolean

Used to determine if the type isnull.

constvNull=vm.createNull();if(vm.isNull(vNull)){// ...}
  • VM.prototype.isBoolean(value)
    • value: Value
    • return Boolean

Used to determine if the type isbool.

constvBoolean=vm.createBoolean(true);if(vm.isBoolean(vBoolean)){// ...}
  • VM.prototype.isNumber(value)
    • value: Value
    • return Boolean

Used to determine if the type isnumber.

constvNumber=vm.createNumber(1024);if(vm.isNumber(vNumber)){// ...}
  • VM.prototype.isString(value)
    • value: Value
    • return Boolean

Used to determine if the type isstring.

constvString=vm.createString("Hello World!");if(vm.isString(vString)){// ...}
  • VM.prototype.isObject(value)
    • value: Value
    • return Boolean

Used to determine if the type isobject.

constvObject=vm.createObject();constvArray=vm.createArray();if(vm.isObject(vObject)&&vm.isObject(vArray)){// ...}
  • VM.prototype.isArray(value)
    • value: Value
    • return Boolean

Used to determine if the type isarray.

constvArray=vm.createArray();if(vm.isArray(vArray)){// ...}
  • VM.prototype.isFunction(value)
    • value: Value
    • return Boolean

Used to determine if the type isfunction.

constvFunction=vm.createFunction("log",function(){});if(vm.isFunction(vFunction)){// ...}
  • VM.prototype.isError(value)
    • value: Value
    • return Boolean

Used to determine if the type iserror.

constvError=vm.createError('unknown error');if(vm.isError(vError)){// ...}
  • VM.prototype.isRegExp(value)
    • value: Value
    • return Boolean

Used to determine if the type isregexp.

constvRegExp=vm.createRegExp("\\w+","ig");if(vm.isRegExp(vRegExp)){// ...}
  • VM.prototype.isDate(value)
    • value: Value
    • return Boolean

Used to determine if the type isdate.

constvDate=vm.createDate();if(vm.isDate(vDate)){// ...}
  • VM.prototype.asUndefined(value)
    • value: Value
    • return undefined

Convertingundefined boxed type toplain undefined value.

constvUndefined=vm.createUndefined();vm.asUndefined(vUndefined)===undefined;
  • VM.prototype.asNull(value)
    • value: Value
    • return null

Convertingnull boxed type toplain null value.

constvNull=vm.createNull();vm.asNull(vNull)===null;
  • VM.prototype.asBoolean(value)
    • value: Value
    • return Boolean

Convertingbool boxed type toplain bool value.

constvBoolean=vm.createBoolean(true);constboolean=vm.asBoolean(vBoolean);if(boolean===true){// ...}
  • VM.prototype.asNumber(value)
    • value: Value
    • return Number

Convertingnumber boxed type toplain number value.

constvNumber=vm.createNumber(1024);constnumber=vm.asNumber(vNumber);if(number===1024){// ...}
  • VM.prototype.asString(value)
    • value: Value
    • return String

Convertingstring boxed type toplain string value.

constvString=vm.createString('Hello World!');conststring=vm.asString(vString);if(string==='Hello World!'){// ...}
  • VM.prototype.asObject(value)
    • value: Value
    • return Object

Convertingobject boxed type toinner object value.

constvObject=vm.createFunction("asObject",function(){});constobject=vm.asObject(vObject);if(object.type===12){// ...}
  • VM.prototype.instanceof(lval, rval)
    • lval: Value
    • rval: Value
    • return Boolean

Equivalent to theinstanceof keyword.

constglobal=vm.getGlobal();constvDateFunc=vm.getProperty(global,"Date");constvDate=vm.createDate();if(vm.instanceof(vDate,vDateFunc)){// ...}
  • VM.prototype.typeof(value)
    • value: Value
    • return String

Equivalent to thetypeof keyword.

constvString=vm.createString('Hello World!');if(vm.typeof(vString)==="string"){// ...}
  • VM.prototype.getProperty(value, name)
    • value: Value
    • name: String
    • return Value

Get the value of the property of the object. Return is a property boxed type.

constglobal=vm.getGlobal();constvPrint=vm.getProperty(global,"print");if(vm.isFunction(vPrint)){// ...}
  • VM.prototype.setProperty(value, name, property)
    • value: Value
    • name: String
    • property: Value
    • return Value

Assigning the property to object. Return is a property boxed type.

constglobal=vm.getGlobal();constconsole=vm.createObject();constlog=vm.createFunction("log",function(){// console.log impl});vm.setProperty(console,"log",log);vm.setProperty(global,"console",console);
  • VM.prototype.deleteProperty(value, name)
    • value: Value
    • name: String
    • return Boolean

Delete the property of object.

constglobal=vm.getGlobal();vm.deleteProperty(global,"print");constvPrint=vm.getProperty(global,"print");if(vm.isUndefined(vPrint)){// ...}
  • VM.prototype.defineProperty(value, name, desc)
    • value: Value
    • name: String
    • desc: Object
    • return Value

Equivalent to theObject.defineProperty function.

constvObject=vm.createObject();vm.defineProperty(vObject,"name",{value:vm.createString("sablejs"),});constgetter=vm.createFunction("getter",function(){returnvm.createNumber("101");});constsetter=vm.createFunction("setter",function(age){vm.setProperty(this,"__age__",age);});vm.defineProperty(vObject,"age",{enumerable:false,get:getter,set:setter,});
  • VM.prototype.getPrototype(value)
    • value: Value
    • return Value

Get the prototype of object.

constglobal=vm.getGlobal();constvStringFunc=vm.getProperty(global,"String");if(!vm.isUndefined(vStringFunc)){constvTrimStart=vm.createFunction("trimStart",function(){conststr=vm.asString(this);returnvm.createString(str);});constvStringFuncProto=vm.getPrototype(vStringFunc);vm.setProperty(vStringFuncProto,"trimStart",vTrimStart);}
  • VM.prototype.setPrototype(value, prototype)
    • value: Value
    • prototype: Value
    • return Value

Set the prototype of object.

constvA=vm.createFunction("A",function(){});constvObject=vm.createObject();vm.setProperty(vObject,'name',vm.createString('Hello World!'));vm.setPrototype(vA,vObject);
  • VM.prototype.throw(value)
    • value: Value
    • return undefined

Equivalent to thethrow keyword.

constvError=vm.createError('unknown error');vm.throw(vError);
  • VM.prototype.new(func[, arg1, arg2, arg3...])
    • func: Value
    • arg: Value
    • return Value

Equivalent to thenew keyword.

constvA=vm.createFunction('A',function(name){vm.setProperty(this,'name',name);});vm.new(vA,vm.createString("A"));
  • VM.prototype.call(func, thisPtr[, arg1, arg2, arg3...])
    • func: Value
    • thisPtr: Value | undefined
    • arg: Value
    • return Value

Equivalent to theFunction.prototype.call function.

constvLog=vm.createFunction('log',function(){consttemp=[];for(leti=0;i<arguments.length;i++){temp.push(vm.asString(arguments[i]));}console.log(...temp);// '1', 1, false});vm.call(vLog,vm.createUndefined(),vm.createString('1'),vm.createNumber(1),vm.createBoolean(false));
  • VM.prototype.destroy
    • return undefined

Destroy the VM instance.

vm.destroy();

Benchmark

sablejs may be the fastest interpreter written in JavaScript (using v8 benchmark suites):

Benchmark Enviorment:

  • Node.js v12.19.0
  • Golang 1.15.6
  • GCC 5.4.0 -O3
  • 2.4 GHz Intel Core i9
  • MacOS Mojave 10.14.6 (18G6032)
sablejssvaleval5quickjs-wasmgoja
LanguageJavaScriptJavaScriptJavaScriptC + WebAssemblyGolang
Richards11024.924.7376208
Crypto11424.620.2400104
RayTrace25892.298.5471294
NavierStokes18335.949.8665191
DeltaBlue12035.329.5402276
Total score14837.337.3452202
Baseline1▼ 2.96▼ 2.96▲ 2.05▲ 0.36
File Size(KB)216152134434-
Gzip Size(KB)294034245-

Limits

  1. Dynamic execution byeval andFunction is forbidden, but passing literal string/number/null and undefined is allowed (the interpreter doesn't contain any compiler).
eval("print('Hello World!')");// it's okeval("var "+"a=1");// it's okvarstr="Hello World!";eval("print('"+str+"')");// throw SyntaxErrorFunction("a","b","return a+b");// it's oknewFunction("a","b","return a+b");// it's okvarstr="return a+b";Function("a","b",str);// throw SyntaxErrornewFunction("a","b",str);// throw SyntaxError
  1. The browser environment relies on native browser functions such asbtoa /unescape /decodeURIComponent, etc. if you need support for IE9 or below, you need to add shims.

Bindings

License

sablejs JavaScript Engine

Copyright (c) 2020-Now ErosZhao

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

Non-profit projects of individuals or organizations and commercial projects withcommercial authorization of the author.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALLTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, 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 INTHE SOFTWARE.

About

🏖️ The safer and faster ECMA5.1 interpreter written by JavaScript

Topics

Resources

License

Stars

Watchers

Forks

Contributors4

  •  
  •  
  •  
  •  

[8]ページ先頭

©2009-2025 Movatter.jp