Skip to content
This repository has been archived by the owner on Mar 25, 2019. It is now read-only.

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
getify committed Feb 21, 2010
0 parents commit e81625a
Show file tree
Hide file tree
Showing 10 changed files with 762 additions and 0 deletions.
101 changes: 101 additions & 0 deletions README.txt
@@ -0,0 +1,101 @@
BikechainJS Engine
v0.0.1 (c) 2010 Kyle Simpson
MIT License


BikechainJS is a minimal server-side JavaScript wrapper environment (engine) around V8. It consists of a single executable "engine" which takes one or more JavaScript files as arguments, and executes them.

"engine.js" is the bootstrapper for the global environment setup. It is required (in the same directory as the "engine") and is automatically loaded, so must not be manually specified to be loaded.


--------------

Installation:

1. Make sure you have a compiled, functional V8: http://code.google.com/p/v8/

2. If you created the "shared" V8 library (recommended), proceed to step 4.

3. If you created the "static" V8 library, edit the makefile to reference to proper static library file.

4. Run "make" and then "make clean".

5. You should now have a "engine" executable in the root directory. You can execute a JavaScript file by passing it as a parameter to engine, like this:

./engine dosomething.js


--------------

Provided global environment:

1. require(module-name): require() is used to load a module. The module name is case-sensitive and must not contain the file extension (.js). A loaded module does not automatically create anything in the global namespace. Instead, the module instance is instead returned from the require() call.

2. include(path-to-file,[forceReload]): include() is used to load/parse a javascript file into the executing environment. The filename should be specified completely, including any relative or absolute path as necessary. "forceReload" is an optional bool parameter (defaults to false) forces the module sub-system to reload the module manually from the file system. Otherwise, modules are cached when loaded to improve performance.

3. include_once(path-to-file): will ensure an exact file (via path) only gets loaded/parsed once.

4. alert(), console.log(), console.warn(), and console.error() are all defined and mapped to [system].stdout.print().


--------------

Modules:

Several modules are available to be loaded into the executing environment by using the global require() function.

1. "system": System (standard I/O)

* [system].stdout.write(str): writes "str" to the standard output
* [system].stdout.print(str): writes "str" to the standard output, followed by a new-line
* [system].stdout.flush(): flushes the output buffer (if necessary)
* [system].stdin.read(): if stdin has any buffered, reads from stdin up until an EOF. Otherwise, read returns empty immediately (non-blocking).
* [system].stderr.write(str): same as stdout.write()
* [system].stderr.print(str): same as stdout.print()
* [system].stderr.flush(): same as stdout.flush()


2. "fs": Filesystem (file I/O)

* [fs].read(file): returns the entire contents of the file
* [fs].write(file,str): writes "str" to "file"


3. "os": Operating System (process execution)

* [os].command(cmd, [..cmds, ..]): execute a command on the local system, specified by "cmd" and "cmds" parameters
-- returns iopipe:
[iopipe].stdout.read(): reads the output from the executed command


4. "promise": "Promises" (sync/async deferral)

* [promise]: Ex: var Promise = require("promise"); Promise(func);
--Passes a promise "P" object to func as first parameter
-- "P" has a .fulfill([val]) function which specifies the promise is finished/fulfilled, and optionally passes along a "val" value.
--Returns an object that can be chained off of, with a .then(func) function, which gets a promise object "P" passed to it
-- "P" has a .value property which is the chained/passed value from the fulfilled promise

Example:

var Promise = require("promise");
Promise(function(P){
doAsync(function(){ P.fullfill("Done"); });
})
.then(function(P){
alert(P.value); // "Done"
});


5. "sbfunction": "Sandbox Functions" (protects special core functions by sandboxing them)

* [sb]: Ex: var sbfunc = require("sbfunction"); func = sbfunc(func);
--sandboxes the passed in function and returns it

Example:

function myfunc() { ... }

var sbfunc = require("sbfunction");
var myfunc = sbfunc(myfunc);

69 changes: 69 additions & 0 deletions engine.js
@@ -0,0 +1,69 @@
/*! BikechainJS (engine.js)
v0.0.1 (c) Kyle Simpson
MIT License
*/


(function(imports){
var global = this,
FS,
SYSTEM,
imports_names = [],
imports_funcs = [],
loaded_modules = {},
loaded_includes = {}
;

for (var i in imports) {
if (imports.hasOwnProperty(i)) {
imports_names[imports_names.length] = i;
imports_funcs[imports_funcs.length] = imports[i];
}
}

global.require = function(module,forceReload) {
forceReload = !(!forceReload);
var source;

if (!FS) {
source = imports.FSREAD("modules/fs.js");
loaded_modules["fs"] = FS = Function.apply(global,imports_names.concat([source])).apply(global,imports_funcs);
}

if (!forceReload && typeof loaded_modules[module] !== "undefined") return loaded_modules[module];

if (module !== "fs") {
source = FS.read("modules/"+module+".js");
return (loaded_modules[module] = Function.apply(global,imports_names.concat([source])).apply(global,imports_funcs));
}
return FS;
}

var sbfunc = global.require("sbfunction");

global.require = sbfunc(global.require); // sandbox "require" as special core function

SYSTEM = global.require("system");

global.include = sbfunc(function(src,forceReload){ // sandbox "include" as special core function
forceReload = !(!forceReload);

if (!forceReload && typeof loaded_includes[src] !== "undefined") return loaded_includes[src];

loaded_includes[src] = FS.read(src);

eval.call(this,loaded_includes[src]);
});

global.include_once = sbfunc(function(src){ // sandbox "include_once" as special core function
if (typeof loaded_includes[src] === "undefined") global.include.call(this,src);
});

global.console = {};
global.alert = global.console.log = global.console.warn = global.console.error = captureoutput = sbfunc(function(){
for (var i=0, len=arguments.length; i<len; i++) {
SYSTEM.stdout.print(arguments[i]);
}
});

})
12 changes: 12 additions & 0 deletions makefile
@@ -0,0 +1,12 @@
## BikechainJS (makefile)
## v0.0.1 (c) Kyle Simpson
## MIT License

engine : engine.o
g++ -o engine -lv8 src/obj/engine.o

engine.o : engine.cpp
g++ -c src/engine.cpp -Isrc/includes/ -osrc/obj/engine.o

clean:
rm src/obj/*.o; strip engine
22 changes: 22 additions & 0 deletions modules/fs.js
@@ -0,0 +1,22 @@
/*! BikechainJS (fs.js)
v0.0.1 (c) Kyle Simpson
MIT License
*/

return (function(){
var publicAPI;

function read(file) {
return FSREAD(file);
}

function write(file,content) {
return FSWRITE(file,content);
}

publicAPI = {
read:read,
write:write
};
return publicAPI;
})();
35 changes: 35 additions & 0 deletions modules/os.js
@@ -0,0 +1,35 @@
/*! BikechainJS (os.js)
v0.0.1 (c) Kyle Simpson
MIT License
*/

return (function(global){
var publicAPI;

function iopipe(handle) {
var pipes = {
stdout:{
read:function(){ return handle; }
},
stdin:{
write:function(){ return; }
},
stderr:{
read:function(){ return handle; }
}
};
return pipes;
}

function command() {
var exec = SYSEXEC.apply(global,arguments);

return iopipe(exec);
}

publicAPI = {
command:command
};
return publicAPI;

})(this);
56 changes: 56 additions & 0 deletions modules/promise.js
@@ -0,0 +1,56 @@
/*! BikechainJS (promise.js)
v0.0.1 (c) Kyle Simpson
MIT License
*/

return (function(){
var undef;
function Promise(){}
Promise.prototype.constructor = Promise;

return function(cb) {
var publicAPI, queue = [], old_ret, promise_fulfilled = false;

function fulfill(val) {
var ret_val = val;
if (typeof ret_val != "undefined") old_ret = ret_val;

try {
return val;
}
finally {
for (var i=0,len=queue.length; i<len; i++) {
if (typeof ret_val != "undefined") old_ret = ret_val;

ret_val = queue[0].call(publicAPI,ret_val);

if (typeof ret_val == "undefined") { ret_val = old_ret; }
else if (ret_val && ret_val.constructor !== Promise) old_ret = ret_val;

queue.shift();

if (ret_val && ret_val.constructor === Promise) {
promise_fulfilled = false;
ret_val.then(function(P){ promise_fulfilled = true; return (old_ret = fulfill(P.value)); });
break;
}
}
}
}

publicAPI = new Promise();

publicAPI.then = function(cb){
queue[queue.length] = function(val){ return cb.call(publicAPI,{value:val}); };
if (promise_fulfilled) fulfill(old_ret);
return publicAPI;
};

cb.call(publicAPI,{fulfill:function(val){
promise_fulfilled = true;
fulfill.call(publicAPI,val);
},value:undef});

return publicAPI;
};
})();
30 changes: 30 additions & 0 deletions modules/sbfunction.js
@@ -0,0 +1,30 @@
/*! BikechainJS (sbfunction.js)
v0.0.1 (c) Kyle Simpson
MIT License
*/

/* Adapted from:
* Fuse JavaScript framework, version Alpha
* (c) 2008-2010 John-David Dalton
*
* FuseJS is freely distributable under the terms of an MIT-style license.
* For details, see the FuseJS web site: http://www.fusejs.com/
*
*--------------------------------------------------------------------------*/

return (function(global) {
function SubFunc(func) {
func.__proto__ = funcPlugin;
return func;
}

var funcPlugin, __Function = global.Function;

// make prototype values conform to ECMA spec and inherit from regular natives
(SubFunc.prototype = new __Function('')).__proto__ = __Function.prototype;

// assign constructor property
(funcPlugin = SubFunc.prototype).constructor = SubFunc;

return SubFunc;
})(this);
49 changes: 49 additions & 0 deletions modules/system.js
@@ -0,0 +1,49 @@
/*! BikechainJS (system.js)
v0.0.1 (c) Kyle Simpson
MIT License
*/

return (function(){
var publicAPI, stdin, stdout, stderr;

function read() {
return IOREAD();
}

function write() {
for (var i=0; i<arguments.length; i++) {
IOWRITE(arguments[0]);
}
}

function flush() {
IOFLUSH();
}

stdin = {
read:read
};
stdout = {
write:write,
print:function(){
write.apply(this,arguments);
write("\n");
flush();
}
};
stderr = {
write:function(){
publicAPI.stdout.write.apply(this,arguments);
},
print:function(){
publicAPI.stdout.print.apply(this,arguments);
}
};

publicAPI = {
stdin:stdin,
stdout:stdout,
stderr:stderr
};
return publicAPI;
})();

0 comments on commit e81625a

Please sign in to comment.