| // Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| // use this file except in compliance with the License. You may obtain a copy of |
| // the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| // License for the specific language governing permissions and limitations under |
| // the License. |
| |
| |
| |
| var vm = require('vm'); |
| var Fiber = require('fibers'); |
| var util = require('util'); |
| |
| var XML = require('./xml'); |
| var log = require('./console').log; |
| |
| var INPUT = { |
| 'queue':[], |
| 'waiting':null |
| }; |
| |
| |
| function print(line) { |
| log('STDOUT %s: %s', process.pid, line); |
| process.stdout.write(line + '\n'); |
| |
| try { |
| line = JSON.parse(line); |
| } catch(er) { |
| return; |
| } |
| |
| if (line[0] === 'log') { |
| log('LOG: %s', line[1]); |
| } |
| } |
| |
| function stdin (line) { |
| log('STDIN %s: %s', process.pid, line.trim()); |
| |
| if (INPUT.waiting) { |
| INPUT.waiting.run(line); |
| } else { |
| INPUT.queue.push(line); |
| } |
| } |
| |
| function readline () { |
| var line = INPUT.queue.shift(); |
| |
| if (line) { |
| return line; |
| } |
| |
| INPUT.waiting = Fiber.current; |
| line = Fiber.yield(); |
| INPUT.waiting = null; |
| |
| return line; |
| } |
| |
| |
| function evalcx (source, sandbox) { |
| sandbox = sandbox || {}; |
| var func; |
| //log('evalcx in %j: %j', Object.keys(sandbox), source) |
| |
| if (source === '') { |
| return sandbox; |
| } |
| |
| // source might be "function(doc) { emit(doc._id, 1) }" |
| source = source.replace(/;+$/, ''); |
| |
| sandbox.XML = sandbox.XML || XML; |
| source = '(' + source + ')'; |
| |
| try { |
| var id = Math.floor(Math.random() * 1000*1000); |
| var filename = '_couchdb:' + id + '.js'; |
| var script = vm.createScript(source, filename); |
| func = script.runInNewContext(sandbox); |
| } catch (er) { |
| log('Error making code: %s', er.stack); |
| return sandbox; |
| } |
| |
| return func; |
| } |
| |
| function quit(code) { |
| code = code || 1; |
| if (code < 0) { |
| code = -code; |
| } |
| |
| process.exit(code); |
| } |
| |
| function gc() { } |
| |
| |
| function toSource() { |
| if (typeof this === 'function') { |
| return '' + this; |
| } |
| |
| if (this instanceof Error) { |
| return this.stack; |
| } |
| |
| return util.inspect(this); |
| } |
| |
| Error.prototype.toSource = Error.prototype.toSource || toSource; |
| Error.prototype.toString = Error.prototype.toString || toSource; |
| Function.prototype.toSource = Function.prototype.toSource || toSource; |
| Function.prototype.toString = Function.prototype.toString || toSource; |
| |
| module.exports = { |
| 'print': print, |
| 'readline': readline, |
| 'stdin': stdin, |
| 'evalcx': evalcx, |
| 'quit': quit, |
| 'gc': gc |
| }; |
| |