@@ -1,5 +1,5 @@
{
"version": "1.4.0",
"version": "1.4.3",
"name": "npm",
"publishConfig": {
"proprietary-attribs": false
@@ -38,9 +38,9 @@
"ini": "~1.1.0",
"slide": "~1.1.5",
"abbrev": "~1.0.4",
"graceful-fs": "~2.0.0",
"graceful-fs": "^2.0.2",
"minimatch": "~0.2.14",
"nopt": "~2.1.2",
"nopt": "^2.2.0",
"rimraf": "~2.2.5",
"request": "~2.30.0",
"which": "1",
@@ -57,10 +57,10 @@
"chownr": "0",
"npmlog": "0.0.6",
"ansi": "~0.2.1",
"npm-registry-client": "~0.4.0",
"npm-registry-client": "^0.4.4",
"read-package-json": "~1.1.7",
"read-installed": "~0.2.2",
"glob": "~3.2.6",
"read-installed": "~1.0.0",
"glob": "3.2.7",
"init-package-json": "0.0.14",
"osenv": "0",
"lockfile": "~0.4.0",
@@ -17,7 +17,16 @@ if [ "x$0" = "xsh" ]; then
# on some systems, you can just do cat>npm-install.sh
# which is a bit cuter. But on others, &1 is already closed,
# so catting to another script file won't do anything.
curl -s https://npmjs.org/install.sh > npm-install-$$.sh
# Follow Location: headers, and fail on errors
curl -f -L -s https://www.npmjs.org/install.sh > npm-install-$$.sh
ret=$?
if [ $ret -eq 0 ]; then
(exit 0)
else
rm npm-install-$$.sh
echo "Failed to download script" >&2
exit $ret
fi
sh npm-install-$$.sh
ret=$?
rm npm-install-$$.sh
@@ -6,14 +6,15 @@ var test = require("tap").test
, rimraf = require("rimraf")

test("dedupe finds the common module and moves it up one level", function (t) {
t.plan(1)
t.plan(2)

setup(function () {
npm.install(".", function (err) {
if (err) return t.fail(err)
npm.dedupe(function(err) {
if (err) return t.fail(err)
t.ok(existsSync(path.join(__dirname, "dedupe", "node_modules", "minimist")))
t.ok(!existsSync(path.join(__dirname, "dedupe", "node_modules", "prime")))
})
})
})
@@ -4,6 +4,8 @@
"version": "0.0.0",
"dependencies": {
"optimist": "0.6.0",
"clean": "2.1.6"
"clean": "2.1.6",
"informal": "0.0.1",
"pathogen": "0.1.5"
}
}
@@ -0,0 +1,43 @@
var test = require("tap").test
, path = require("path")
, rimraf = require("rimraf")
, mkdirp = require("mkdirp")
, spawn = require("child_process").spawn
, npm = require.resolve("../../bin/npm-cli.js")
, node = process.execPath
, pkg = path.resolve(__dirname, "git-cache-locking")
, tmp = path.join(pkg, "tmp")
, cache = path.join(pkg, "cache")

test("git-cache-locking: install a git dependency", function (t) {
t.plan(1)

cleanup()
mkdirp.sync(cache)
mkdirp.sync(tmp)

// package c depends on a.git#master and b.git#master
// package b depends on a.git#master
var child = spawn(node, [npm, "install", "git://github.com/nigelzor/npm-4503-c.git"], {
cwd: pkg,
env: {
npm_config_cache: cache,
npm_config_tmp: tmp,
npm_config_prefix: pkg,
npm_config_global: "false",
HOME: process.env.HOME,
Path: process.env.PATH,
PATH: process.env.PATH
},
stdio: "inherit"
})

child.on("close", function (code) {
t.equal(0, code, "npm install should succeed")
cleanup()
})
})

function cleanup() {
rimraf.sync(pkg)
}
@@ -0,0 +1,43 @@
var common = require('../common-tap.js')
var test = require('tap').test
var npm = require('../../')
var osenv = require('osenv')
var path = require('path')
var fs = require('fs')
var rimraf = require('rimraf')
var mkdirp = require('mkdirp')
var pkg = path.join(__dirname, 'install-at-locally')

test("setup", function (t) {
mkdirp.sync(pkg)
mkdirp.sync(path.resolve(pkg, 'node_modules'))
process.chdir(pkg)
t.end()
})

test('"npm install ./package@1.2.3" should install local pkg', function(t) {
npm.load(function() {
npm.commands.install(['./package@1.2.3'], function(err) {
var p = path.resolve(pkg, 'node_modules/install-at-locally/package.json')
t.ok(JSON.parse(fs.readFileSync(p, 'utf8')))
t.end()
})
})
})

test('"npm install install/at/locally@./package@1.2.3" should install local pkg', function(t) {
npm.load(function() {
npm.commands.install(['./package@1.2.3'], function(err) {
var p = path.resolve(pkg, 'node_modules/install-at-locally/package.json')
t.ok(JSON.parse(fs.readFileSync(p, 'utf8')))
t.end()
})
})
})

test('cleanup', function(t) {
process.chdir(__dirname)
rimraf.sync(path.resolve(pkg, 'node_modules'))
t.end()
})

@@ -0,0 +1,5 @@
{
"name": "install-at-locally",
"version": "0.0.0",
"description": "Test for 404-parent"
}
@@ -0,0 +1,47 @@
var test = require("tap").test
var npm = require("../..")
var path = require("path")
var rimraf = require("rimraf")
var npmrc = path.join(__dirname, "npmrc")
var fs = require("fs")

test("setup", function (t) {
fs.writeFileSync(npmrc, "foo = bar\n", "ascii")
t.end()
})

test("calling set/get on config pre-load should throw", function (t) {
var threw = true
try {
npm.config.get("foo")
threw = false
} catch (er) {
t.equal(er.message, "npm.load() required")
} finally {
t.ok(threw, "get before load should throw")
}

var threw = true
try {
npm.config.set("foo", "bar")
threw = false
} catch (er) {
t.equal(er.message, "npm.load() required")
} finally {
t.ok(threw, "set before load should throw")
}

npm.load({ userconfig: npmrc }, function (er) {
if (er)
throw er
t.equal(npm.config.get("foo"), "bar")
npm.config.set("foo", "baz")
t.equal(npm.config.get("foo"), "baz")
t.end()
})
})

test("cleanup", function (t) {
rimraf.sync(npmrc)
t.end()
})
@@ -0,0 +1,41 @@
var common = require("../common-tap.js")
var test = require("tap").test
var npm = require("../../")
var mkdirp = require("mkdirp")
var rimraf = require("rimraf")
var mr = require("npm-registry-mock")
var exec = require('child_process').exec

var pkg = __dirname + '/outdated'
var NPM_BIN = __dirname + '/../../bin/npm-cli.js'
mkdirp.sync(pkg + "/cache")

function hasControlCodes(str) {
return str.length !== ansiTrim(str).length
}

function ansiTrim (str) {
var r = new RegExp("\x1b(?:\\[(?:\\d+[ABCDEFGJKSTm]|\\d+;\\d+[Hfm]|" +
"\\d+;\\d+;\\d+m|6n|s|u|\\?25[lh])|\\w)", "g");
return str.replace(r, "")
}

// note hard to automate tests for color = true
// as npm kills the color config when it detects
// it's not running in a tty
test("does not use ansi styling", function (t) {
t.plan(3)
exec('node ' + NPM_BIN + ' outdated --color false', {
cwd: pkg
}, function(err, stdout) {
t.ifError(err)
t.ok(stdout, stdout.length)
t.ok(!hasControlCodes(stdout))
})
})

test("cleanup", function (t) {
rimraf.sync(pkg + "/cache")
t.end()
})

@@ -12,13 +12,14 @@ mkdirp.sync(pkg + "/cache")

test("dicovers new versions in outdated", function (t) {
process.chdir(pkg)
t.plan(4)
t.plan(5)
npm.load({cache: pkg + "/cache", registry: common.registry}, function () {
npm.outdated(function (er, d) {
t.equal('git', d[0][3])
t.equal('git', d[0][4])
t.equal('git://github.com/robertkowalski/foo-private.git', d[0][5])
t.equal('git://user:pass@github.com/robertkowalski/foo-private.git', d[1][5])
t.equal('git://github.com/robertkowalski/foo', d[2][5])
})
})
})
@@ -6,6 +6,7 @@
"main": "index.js",
"dependencies": {
"foo-private": "git://github.com/robertkowalski/foo-private.git",
"foo-private-credentials": "git://user:pass@github.com/robertkowalski/foo-private.git"
"foo-private-credentials": "git://user:pass@github.com/robertkowalski/foo-private.git",
"foo-github": "robertkowalski/foo"
}
}
@@ -8,19 +8,41 @@ var mr = require("npm-registry-mock")
// config
var pkg = __dirname + '/outdated'

var path = require("path")

test("it should not throw", function (t) {
cleanup()
process.chdir(pkg)

var originalLog = console.log
var output = []
var expOut = [ path.resolve(__dirname, "outdated/node_modules/underscore")
, path.resolve(__dirname, "outdated/node_modules/underscore")
+ ":underscore@1.3.1"
+ ":underscore@1.3.1"
+ ":underscore@1.5.1" ]
var expData = [ [ path.resolve(__dirname, "outdated")
, "underscore"
, "1.3.1"
, "1.3.1"
, "1.5.1"
, "1.3.1" ] ]

console.log = function () {
output.push.apply(output, arguments)
}
mr(common.port, function (s) {
npm.load({
cache: pkg + "/cache",
loglevel: 'silent',
parseable: true,
registry: common.registry }
, function () {
npm.install(".", function (err) {
npm.outdated(function (er, d) {
console.log(d)
console.log = originalLog
t.same(output, expOut)
t.same(d, expData)
s.close()
t.end()
})
@@ -0,0 +1,107 @@
var test = require("tap").test
var fs = require("fs")
var node = process.execPath
var npm = require.resolve("../../bin/npm-cli.js")
var rimraf = require("rimraf")
var mr = require("npm-registry-mock")
var common = require("../common-tap.js")
var spawn = require("child_process").spawn

var pkg = __dirname + "/prune"

var server

test("reg mock", function (t) {
mr(common.port, function (s) {
server = s
t.pass("registry mock started")
t.end()
})
})

test("npm install", function (t) {
var c = spawn(node, [
npm, "install",
"--registry=" + common.registry,
"--loglevel=silent",
"--production=false"
], { cwd: pkg })
c.stderr.on("data", function(d) {
t.fail("Should not get data on stderr: " + d)
})
c.on("close", function(code) {
t.notOk(code, "exit ok")
t.end()
})
})

test("npm install test-package", function (t) {
var c = spawn(node, [
npm, "install", "test-package",
"--registry=" + common.registry,
"--loglevel=silent",
"--production=false"
], { cwd: pkg })
c.stderr.on("data", function(d) {
t.fail("Should not get data on stderr: " + d)
})
c.on("close", function(code) {
t.notOk(code, "exit ok")
t.end()
})
})

test("verify installs", function (t) {
var dirs = fs.readdirSync(pkg + "/node_modules").sort()
t.same(dirs, [ "test-package", "mkdirp", "underscore" ].sort())
t.end()
})

test("npm prune", function (t) {
var c = spawn(node, [
npm, "prune",
"--loglevel=silent",
"--production=false"
], { cwd: pkg })
c.stderr.on("data", function(d) {
t.fail("Should not get data on stderr: " + d)
})
c.on("close", function(code) {
t.notOk(code, "exit ok")
t.end()
})
})

test("verify installs", function (t) {
var dirs = fs.readdirSync(pkg + "/node_modules").sort()
t.same(dirs, [ "mkdirp", "underscore" ])
t.end()
})

test("npm prune", function (t) {
var c = spawn(node, [
npm, "prune",
"--loglevel=silent",
"--production"
], { cwd: pkg })
c.stderr.on("data", function(d) {
t.fail("Should not get data on stderr: " + d)
})
c.on("close", function(code) {
t.notOk(code, "exit ok")
t.end()
})
})

test("verify installs", function (t) {
var dirs = fs.readdirSync(pkg + "/node_modules").sort()
t.same(dirs, [ "underscore" ])
t.end()
})

test("cleanup", function (t) {
server.close()
rimraf.sync(pkg + "/node_modules")
t.pass("cleaned up")
t.end()
})
@@ -0,0 +1,13 @@
{
"name": "bla",
"description": "fixture",
"version": "0.0.1",
"main": "index.js",
"dependencies": {
"underscore": "1.3.1"
},
"devDependencies": {
"mkdirp": "*"
},
"repository": "git://github.com/robertkowalski/bogusfixture"
}
@@ -0,0 +1,52 @@
if (process.platform === "win32") {
console.error("skipping test, because windows and shebangs")
return
}

var common = require("../common-tap.js")
var mr = require("npm-registry-mock")

var test = require("tap").test
var npm = require.resolve("../../bin/npm-cli.js")
var node = process.execPath
var rimraf = require("rimraf")
var spawn = require("child_process").spawn
var fs = require("fs")

test("setup", function (t) {
var s = "#!/usr/bin/env bash\n" +
"echo \"$@\" > " + JSON.stringify(__dirname) + "/_output\n"
fs.writeFileSync(__dirname + "/_script.sh", s, "ascii")
fs.chmodSync(__dirname + "/_script.sh", "0755")
t.pass("made script")
t.end()
})

test("npm repo underscore", function (t) {
mr(common.port, function (s) {
var c = spawn(node, [
npm, "repo", "underscore",
"--registry=" + common.registry,
"--loglevel=silent",
"--browser=" + __dirname + "/_script.sh",
])
c.stdout.on("data", function(d) {
t.fail("Should not get data on stdout: " + d)
})
c.stderr.pipe(process.stderr)
c.on("close", function(code) {
t.equal(code, 0, "exit ok")
var res = fs.readFileSync(__dirname + "/_output", "ascii")
s.close()
t.equal(res, "https://github.com/jashkenas/underscore\n")
t.end()
})
})
})

test("cleanup", function (t) {
fs.unlinkSync(__dirname + "/_script.sh")
fs.unlinkSync(__dirname + "/_output")
t.pass("cleaned up")
t.end()
})
@@ -0,0 +1,66 @@
var npm = npm = require("../../")
var test = require("tap").test
var path = require("path")
var fs = require("fs")
var osenv = require("osenv")
var rimraf = require("rimraf")
var mr = require("npm-registry-mock")
var common = require("../common-tap.js")

var pkg = path.resolve(__dirname, "shrinkwrap-dev-dependency")
var desiredResultsPath = path.resolve(pkg, "desired-shrinkwrap-results.json")

test("shrinkwrap doesn't strip out the dependency", function (t) {
t.plan(1)

mr(common.port, function (s) {
setup({ production: true }, function (err) {
if (err) return t.fail(err)

npm.install(".", function (err) {
if (err) return t.fail(err)

npm.commands.shrinkwrap([], true, function (err, results) {
if (err) return t.fail(err)

fs.readFile(desiredResultsPath, function (err, desired) {
if (err) return t.fail(err)

t.deepEqual(results, JSON.parse(desired))
s.close()
t.end()
})
})
})
})
})
})

test("cleanup", function (t) {
cleanup()
t.end()
})


function setup (opts, cb) {
cleanup()
process.chdir(pkg)

var allOpts = {
cache: path.resolve(pkg, "cache"),
registry: common.registry
}

for (var key in opts) {
allOpts[key] = opts[key]
}

npm.load(allOpts, cb)
}

function cleanup () {
process.chdir(osenv.tmpdir())
rimraf.sync(path.resolve(pkg, "node_modules"))
rimraf.sync(path.resolve(pkg, "cache"))
rimraf.sync(path.resolve(pkg, "npm-shrinkwrap.json"))
}
@@ -0,0 +1,12 @@
{
"name": "npm-test-shrinkwrap-dev-dependency",
"version": "0.0.0",
"dependencies": {
"request": {
"version": "0.9.0"
},
"underscore": {
"version": "1.3.1"
}
}
}
@@ -0,0 +1,12 @@
{
"author": "Domenic Denicola",
"name": "npm-test-shrinkwrap-dev-dependency",
"version": "0.0.0",
"dependencies": {
"request": "0.9.0",
"underscore": "1.3.1"
},
"devDependencies": {
"underscore": "1.5.1"
}
}
@@ -0,0 +1,58 @@
var npm = npm = require("../../")
var test = require("tap").test
var path = require("path")
var fs = require("fs")
var osenv = require("osenv")
var rimraf = require("rimraf")
var mr = require("npm-registry-mock")
var common = require("../common-tap.js")

var pkg = path.resolve(__dirname, "shrinkwrap-shared-dev-dependency")
var desiredResultsPath = path.resolve(pkg, "desired-shrinkwrap-results.json")

test("shrinkwrap doesn't strip out the shared dependency", function (t) {
t.plan(1)

mr(common.port, function (s) {
setup(function (err) {
if (err) return t.fail(err)

npm.install(".", function (err) {
if (err) return t.fail(err)

npm.commands.shrinkwrap([], true, function (err, results) {
if (err) return t.fail(err)

fs.readFile(desiredResultsPath, function (err, desired) {
if (err) return t.fail(err)

t.deepEqual(results, JSON.parse(desired))
s.close()
t.end()
})
})
})
})
})
})

test("cleanup", function (t) {
cleanup()
t.end()
})


function setup (cb) {
cleanup()
process.chdir(pkg)

var opts = { cache: path.resolve(pkg, "cache"), registry: common.registry }
npm.load(opts, cb)
}

function cleanup () {
process.chdir(osenv.tmpdir())
rimraf.sync(path.resolve(pkg, "node_modules"))
rimraf.sync(path.resolve(pkg, "cache"))
rimraf.sync(path.resolve(pkg, "npm-shrinkwrap.json"))
}
@@ -0,0 +1,12 @@
{
"name": "npm-test-shrinkwrap-shared-dev-dependency",
"version": "0.0.0",
"dependencies": {
"test-package-with-one-dep": {
"version": "0.0.0"
},
"test-package": {
"version": "0.0.0"
}
}
}
@@ -0,0 +1,11 @@
{
"author": "Domenic Denicola",
"name": "npm-test-shrinkwrap-shared-dev-dependency",
"version": "0.0.0",
"dependencies": {
"test-package-with-one-dep": "0.0.0"
},
"devDependencies": {
"test-package": "0.0.0"
}
}
@@ -628,7 +628,9 @@ process has exited.
* `cwd` {String} Current working directory of the child process
* `input` {String|Buffer} The value which will be passed as stdin to the spawned process
- supplying this value will override `stdio[0]`
* `stdio` {Array} Child's stdio configuration.
* `stdio` {Array} Child's stdio configuration. (Default: 'pipe')
- `stderr` by default will be output to the parent process' stderr unless
`stdio` is specified
* `env` {Object} Environment key-value pairs
* `uid` {Number} Sets the user identity of the process. (See setuid(2).)
* `gid` {Number} Sets the group identity of the process. (See setgid(2).)
@@ -656,7 +658,9 @@ throw. The `Error` object will contain the entire result from
* `cwd` {String} Current working directory of the child process
* `input` {String|Buffer} The value which will be passed as stdin to the spawned process
- supplying this value will override `stdio[0]`
* `stdio` {Array} Child's stdio configuration.
* `stdio` {Array} Child's stdio configuration. (Default: 'pipe')
- `stderr` by default will be output to the parent process' stderr unless
`stdio` is specified
* `env` {Object} Environment key-value pairs
* `uid` {Number} Sets the user identity of the process. (See setuid(2).)
* `gid` {Number} Sets the group identity of the process. (See setgid(2).)
@@ -388,23 +388,39 @@ the data and public key.
Note: `verifier` object can not be used after `verify()` method has been
called.

## crypto.createDiffieHellman(prime_length)
## crypto.createDiffieHellman(prime_length, [generator])

Creates a Diffie-Hellman key exchange object and generates a prime of
the given bit length. The generator used is `2`.
`prime_length` bits and using an optional specific numeric `generator`.
If no `generator` is specified, then `2` is used.

## crypto.createDiffieHellman(prime, [encoding])
## crypto.createDiffieHellman(prime, [prime_encoding], [generator], [generator_encoding])

Creates a Diffie-Hellman key exchange object using the supplied prime.
The generator used is `2`. Encoding can be `'binary'`, `'hex'`, or
`'base64'`. If no encoding is specified, then a buffer is expected.
Creates a Diffie-Hellman key exchange object using the supplied `prime` and an
optional specific `generator`.
`generator` can be a number, string, or Buffer.
If no `generator` is specified, then `2` is used.
`prime_encoding` and `generator_encoding` can be `'binary'`, `'hex'`, or `'base64'`.
If no `prime_encoding` is specified, then a Buffer is expected for `prime`.
If no `generator_encoding` is specified, then a Buffer is expected for `generator`.

## Class: DiffieHellman

The class for creating Diffie-Hellman key exchanges.

Returned by `crypto.createDiffieHellman`.

### diffieHellman.verifyError

A bit field containing any warnings and/or errors as a result of a check performed
during initialization. The following values are valid for this property
(defined in `constants` module):

* `DH_CHECK_P_NOT_SAFE_PRIME`
* `DH_CHECK_P_NOT_PRIME`
* `DH_UNABLE_TO_CHECK_GENERATOR`
* `DH_NOT_SUITABLE_GENERATOR`

### diffieHellman.generateKeys([encoding])

Generates private and public Diffie-Hellman key values, and returns
@@ -64,6 +64,8 @@ For TCP sockets, `options` argument should be an object which specifies:

- `localAddress`: Local interface to bind to for network connections.

- `localPort`: Local port to bind to for network connections.

- `family` : Version of IP stack. Defaults to `4`.

For local domain sockets, `options` argument should be an object which
@@ -169,9 +169,13 @@ Example: the definition of `console.log`
};

`process.stderr` and `process.stdout` are unlike other streams in Node in
that writes to them are usually blocking. They are blocking in the case
that they refer to regular files or TTY file descriptors. In the case they
refer to pipes, they are non-blocking like other streams.
that writes to them are usually blocking.

- They are blocking in the case that they refer to regular files or TTY file
descriptors.
- In the case they refer to pipes:
- They are blocking in Linux/Unix.
- They are non-blocking like other streams in Windows.

To check if Node is being run in a TTY context, read the `isTTY` property
on `process.stderr`, `process.stdout`, or `process.stdin`:
@@ -193,29 +197,45 @@ See [the tty docs](tty.html#tty_tty) for more information.
A writable stream to stderr.

`process.stderr` and `process.stdout` are unlike other streams in Node in
that writes to them are usually blocking. They are blocking in the case
that they refer to regular files or TTY file descriptors. In the case they
refer to pipes, they are non-blocking like other streams.
that writes to them are usually blocking.

- They are blocking in the case that they refer to regular files or TTY file
descriptors.
- In the case they refer to pipes:
- They are blocking in Linux/Unix.
- They are non-blocking like other streams in Windows.


## process.stdin

A `Readable Stream` for stdin. The stdin stream is paused by default, so one
must call `process.stdin.resume()` to read from it.
A `Readable Stream` for stdin.

Example of opening standard input and listening for both events:

process.stdin.resume();
process.stdin.setEncoding('utf8');

process.stdin.on('data', function(chunk) {
process.stdout.write('data: ' + chunk);
process.stdin.on('readable', function(chunk) {
var chunk = process.stdin.read();
if (chunk !== null) {
process.stdout.write('data: ' + chunk);
}
});

process.stdin.on('end', function() {
process.stdout.write('end');
});

As a Stream, `process.stdin` can also be used in "old" mode that is compatible
with scripts written for node prior v0.10.
For more information see
[Stream compatibility](stream.html#stream_compatibility_with_older_node_versions).

In "old" Streams mode the stdin stream is paused by default, so one
must call `process.stdin.resume()` to read from it. Note also that calling
`process.stdin.resume()` itself would switch stream to "old" mode.

If you are starting a new project you should prefer a more recent "new" Streams
mode over "old" one.

## process.argv

@@ -999,6 +999,9 @@ how to implement Writable streams in your programs.
returning false. Default=16kb, or 16 for `objectMode` streams
* `decodeStrings` {Boolean} Whether or not to decode strings into
Buffers before passing them to [`_write()`][]. Default=true
* `objectMode` {Boolean} Whether or not the `write(anyObj)` is
a valid operation. If set you can write arbitrary data instead
of only `Buffer` / `String` data. Default=false

In classes that extend the Writable class, make sure to call the
constructor so that the buffering settings can be properly
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -1115,8 +1115,9 @@ Interface.prototype.list = function(delta) {

var current = lineno == 1 + client.currentSourceLine,
breakpoint = client.breakpoints.some(function(bp) {
return bp.script === client.currentScript &&
bp.line == lineno;
return (bp.scriptReq === client.currentScript ||
bp.script === client.currentScript) &&
bp.line == lineno;
});

if (lineno == 1) {
@@ -1557,7 +1558,6 @@ Interface.prototype.repl = function() {
this.history.control = this.repl.rli.history;
this.repl.rli.history = this.history.debug;

this.repl.prompt = '> ';
this.repl.rli.setPrompt('> ');
this.repl.displayPrompt();
};
@@ -1573,7 +1573,6 @@ Interface.prototype.exitRepl = function() {
this.repl.rli.history = this.history.control;

this.repl.context = this.context;
this.repl.prompt = 'debug> ';
this.repl.rli.setPrompt('debug> ');
this.repl.displayPrompt();
};
@@ -187,9 +187,6 @@ ServerResponse.prototype.writeHead = function(statusCode) {
var obj = arguments[headerIndex];

if (obj && this._headers) {
// Slow-case: when progressive API and header fields are passed.
headers = this._renderHeaders();

if (util.isArray(obj)) {
// handle array case
// TODO: remove when array is no longer accepted
@@ -207,8 +204,10 @@ ServerResponse.prototype.writeHead = function(statusCode) {
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
var k = keys[i];
if (k) headers[k] = obj[k];
if (k) this.setHeader(k, obj[k]);
}
// Slow-case: when progressive API and header fields are passed.
headers = this._renderHeaders();
}
} else if (this._headers) {
// only progressive api is used
@@ -1304,7 +1304,13 @@ function checkExecSyncError(ret) {


function execFileSync(/*command, options*/) {
var ret = spawnSync.apply(null, arguments);
var opts = normalizeSpawnArguments.apply(null, arguments);
var inheritStderr = !!!opts.options.stdio;

var ret = spawnSync(opts.file, opts.args.slice(1), opts.options);

if (inheritStderr)
process.stderr.write(ret.stderr);

var err = checkExecSyncError(ret);

@@ -1318,9 +1324,14 @@ exports.execFileSync = execFileSync;

function execSync(/*comand, options*/) {
var opts = normalizeExecArgs.apply(null, arguments);
var inheritStderr = opts.options ? !!!opts.options.stdio : true;

var ret = spawnSync(opts.file, opts.args, opts.options);
ret.cmd = opts.cmd;

if (inheritStderr)
process.stderr.write(ret.stderr);

var err = checkExecSyncError(ret);

if (err)
@@ -39,6 +39,8 @@ var constants = require('constants');
var stream = require('stream');
var util = require('util');

var DH_GENERATOR = 2;

// This is here because many functions accepted binary strings without
// any explicit encoding in older versions of node, and we don't want
// to break them unnecessarily.
@@ -456,17 +458,36 @@ Verify.prototype.verify = function(object, signature, sigEncoding) {

exports.createDiffieHellman = exports.DiffieHellman = DiffieHellman;

function DiffieHellman(sizeOrKey, encoding) {
function DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding) {
if (!(this instanceof DiffieHellman))
return new DiffieHellman(sizeOrKey, encoding);

if (!sizeOrKey)
this._binding = new binding.DiffieHellman();
else {
encoding = encoding || exports.DEFAULT_ENCODING;
sizeOrKey = toBuf(sizeOrKey, encoding);
this._binding = new binding.DiffieHellman(sizeOrKey);
return new DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding);

if (keyEncoding) {
if (typeof keyEncoding !== 'string' ||
(!Buffer.isEncoding(keyEncoding) && keyEncoding !== 'buffer')) {
genEncoding = generator;
generator = keyEncoding;
keyEncoding = false;
}
}

keyEncoding = keyEncoding || exports.DEFAULT_ENCODING;
genEncoding = genEncoding || exports.DEFAULT_ENCODING;

if (typeof sizeOrKey !== 'number')
sizeOrKey = toBuf(sizeOrKey, keyEncoding);

if (!generator)
generator = DH_GENERATOR;
else if (typeof generator !== 'number')
generator = toBuf(generator, genEncoding);

this._binding = new binding.DiffieHellman(sizeOrKey, generator);
Object.defineProperty(this, 'verifyError', {
enumerable: true,
value: this._binding.verifyError,
writable: false
});
}


@@ -478,6 +499,11 @@ function DiffieHellmanGroup(name) {
if (!(this instanceof DiffieHellmanGroup))
return new DiffieHellmanGroup(name);
this._binding = new binding.DiffieHellmanGroup(name);
Object.defineProperty(this, 'verifyError', {
enumerable: true,
value: this._binding.verifyError,
writable: false
});
}


@@ -776,20 +776,51 @@ function afterWrite(status, handle, req, err) {
}


function connect(self, address, port, addressType, localAddress) {
function connect(self, address, port, addressType, localAddress, localPort) {
// TODO return promise from Socket.prototype.connect which
// wraps _connectReq.

assert.ok(self._connecting);

var err;
if (localAddress) {
if (addressType === 6) {
err = self._handle.bind6(localAddress);
} else {
err = self._handle.bind(localAddress);
if (localAddress || localPort) {
if (localAddress && !exports.isIP(localAddress))
err = new TypeError(
'localAddress should be a valid IP: ' + localAddress);

if (localPort && !util.isNumber(localPort))
err = new TypeError('localPort should be a number: ' + localPort);

var bind;

switch (addressType) {
case 4:
if (!localAddress)
localAddress = '0.0.0.0';
bind = self._handle.bind;
break;
case 6:
if (!localAddress)
localAddress = '::';
bind = self._handle.bind6;
break;
default:
err = new TypeError('Invalid addressType: ' + addressType);
break;
}

if (err) {
self._destroy(err);
return;
}

debug('binding to localAddress: %s and localPort: %d',
localAddress,
localPort);

bind = bind.bind(self._handle);
err = bind(localAddress, localPort);

if (err) {
self._destroy(errnoException(err, 'bind'));
return;
@@ -897,7 +928,12 @@ Socket.prototype.connect = function(options, cb) {
// expects remoteAddress to have a meaningful value
ip = ip || (addressType === 4 ? '127.0.0.1' : '0:0:0:0:0:0:0:1');

connect(self, ip, options.port, addressType, options.localAddress);
connect(self,
ip,
options.port,
addressType,
options.localAddress,
options.localPort);
}
});
}
@@ -193,27 +193,27 @@ static void ares_sockstate_cb(void* data,
}


static Local<Array> HostentToAddresses(struct hostent* host) {
HandleScope scope(node_isolate);
static Local<Array> HostentToAddresses(Environment* env, struct hostent* host) {
HandleScope scope(env->isolate());
Local<Array> addresses = Array::New();

char ip[INET6_ADDRSTRLEN];
for (uint32_t i = 0; host->h_addr_list[i] != NULL; ++i) {
uv_inet_ntop(host->h_addrtype, host->h_addr_list[i], ip, sizeof(ip));
Local<String> address = OneByteString(node_isolate, ip);
Local<String> address = OneByteString(env->isolate(), ip);
addresses->Set(i, address);
}

return scope.Close(addresses);
}


static Local<Array> HostentToNames(struct hostent* host) {
HandleScope scope(node_isolate);
static Local<Array> HostentToNames(Environment* env, struct hostent* host) {
HandleScope scope(env->isolate());
Local<Array> names = Array::New();

for (uint32_t i = 0; host->h_aliases[i] != NULL; ++i) {
Local<String> address = OneByteString(node_isolate, host->h_aliases[i]);
Local<String> address = OneByteString(env->isolate(), host->h_aliases[i]);
names->Set(i, address);
}

@@ -377,7 +377,7 @@ class QueryAWrap: public QueryWrap {
return;
}

Local<Array> addresses = HostentToAddresses(host);
Local<Array> addresses = HostentToAddresses(env(), host);
ares_free_hostent(host);

this->CallOnComplete(addresses);
@@ -414,7 +414,7 @@ class QueryAaaaWrap: public QueryWrap {
return;
}

Local<Array> addresses = HostentToAddresses(host);
Local<Array> addresses = HostentToAddresses(env(), host);
ares_free_hostent(host);

this->CallOnComplete(addresses);
@@ -453,7 +453,7 @@ class QueryCnameWrap: public QueryWrap {
// A cname lookup always returns a single record but we follow the
// common API here.
Local<Array> result = Array::New(1);
result->Set(0, OneByteString(node_isolate, host->h_name));
result->Set(0, OneByteString(env()->isolate(), host->h_name));
ares_free_hostent(host);

this->CallOnComplete(result);
@@ -490,18 +490,16 @@ class QueryMxWrap: public QueryWrap {
}

Local<Array> mx_records = Array::New();
Local<String> exchange_symbol =
FIXED_ONE_BYTE_STRING(node_isolate, "exchange");
Local<String> priority_symbol =
FIXED_ONE_BYTE_STRING(node_isolate, "priority");
Local<String> exchange_symbol = env()->exchange_string();
Local<String> priority_symbol = env()->priority_string();

ares_mx_reply* current = mx_start;
for (uint32_t i = 0; current != NULL; ++i, current = current->next) {
Local<Object> mx_record = Object::New();
mx_record->Set(exchange_symbol,
OneByteString(node_isolate, current->host));
OneByteString(env()->isolate(), current->host));
mx_record->Set(priority_symbol,
Integer::New(current->priority, node_isolate));
Integer::New(current->priority, env()->isolate()));
mx_records->Set(i, mx_record);
}

@@ -540,7 +538,7 @@ class QueryNsWrap: public QueryWrap {
return;
}

Local<Array> names = HostentToNames(host);
Local<Array> names = HostentToNames(env(), host);
ares_free_hostent(host);

this->CallOnComplete(names);
@@ -580,7 +578,7 @@ class QueryTxtWrap: public QueryWrap {

ares_txt_reply* current = txt_out;
for (uint32_t i = 0; current != NULL; ++i, current = current->next) {
Local<String> txt = OneByteString(node_isolate, current->txt);
Local<String> txt = OneByteString(env()->isolate(), current->txt);
txt_records->Set(i, txt);
}

@@ -620,26 +618,22 @@ class QuerySrvWrap: public QueryWrap {
}

Local<Array> srv_records = Array::New();
Local<String> name_symbol =
FIXED_ONE_BYTE_STRING(node_isolate, "name");
Local<String> port_symbol =
FIXED_ONE_BYTE_STRING(node_isolate, "port");
Local<String> priority_symbol =
FIXED_ONE_BYTE_STRING(node_isolate, "priority");
Local<String> weight_symbol =
FIXED_ONE_BYTE_STRING(node_isolate, "weight");
Local<String> name_symbol = env()->name_string();
Local<String> port_symbol = env()->port_string();
Local<String> priority_symbol = env()->priority_string();
Local<String> weight_symbol = env()->weight_string();

ares_srv_reply* current = srv_start;
for (uint32_t i = 0; current != NULL; ++i, current = current->next) {
Local<Object> srv_record = Object::New();
srv_record->Set(name_symbol,
OneByteString(node_isolate, current->host));
OneByteString(env()->isolate(), current->host));
srv_record->Set(port_symbol,
Integer::New(current->port, node_isolate));
Integer::New(current->port, env()->isolate()));
srv_record->Set(priority_symbol,
Integer::New(current->priority, node_isolate));
Integer::New(current->priority, env()->isolate()));
srv_record->Set(weight_symbol,
Integer::New(current->weight, node_isolate));
Integer::New(current->weight, env()->isolate()));
srv_records->Set(i, srv_record);
}

@@ -679,34 +673,28 @@ class QueryNaptrWrap: public QueryWrap {
}

Local<Array> naptr_records = Array::New();
Local<String> flags_symbol =
FIXED_ONE_BYTE_STRING(node_isolate, "flags");
Local<String> service_symbol =
FIXED_ONE_BYTE_STRING(node_isolate, "service");
Local<String> regexp_symbol =
FIXED_ONE_BYTE_STRING(node_isolate, "regexp");
Local<String> replacement_symbol =
FIXED_ONE_BYTE_STRING(node_isolate, "replacement");
Local<String> order_symbol =
FIXED_ONE_BYTE_STRING(node_isolate, "order");
Local<String> preference_symbol =
FIXED_ONE_BYTE_STRING(node_isolate, "preference");
Local<String> flags_symbol = env()->flags_string();
Local<String> service_symbol = env()->service_string();
Local<String> regexp_symbol = env()->regexp_string();
Local<String> replacement_symbol = env()->replacement_string();
Local<String> order_symbol = env()->order_string();
Local<String> preference_symbol = env()->preference_string();

ares_naptr_reply* current = naptr_start;
for (uint32_t i = 0; current != NULL; ++i, current = current->next) {
Local<Object> naptr_record = Object::New();
naptr_record->Set(flags_symbol,
OneByteString(node_isolate, current->flags));
OneByteString(env()->isolate(), current->flags));
naptr_record->Set(service_symbol,
OneByteString(node_isolate, current->service));
OneByteString(env()->isolate(), current->service));
naptr_record->Set(regexp_symbol,
OneByteString(node_isolate, current->regexp));
OneByteString(env()->isolate(), current->regexp));
naptr_record->Set(replacement_symbol,
OneByteString(node_isolate, current->replacement));
OneByteString(env()->isolate(), current->replacement));
naptr_record->Set(order_symbol,
Integer::New(current->order, node_isolate));
Integer::New(current->order, env()->isolate()));
naptr_record->Set(preference_symbol,
Integer::New(current->preference, node_isolate));
Integer::New(current->preference, env()->isolate()));
naptr_records->Set(i, naptr_record);
}

@@ -748,20 +736,20 @@ class QuerySoaWrap: public QueryWrap {

Local<Object> soa_record = Object::New();

soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "nsname"),
OneByteString(node_isolate, soa_out->nsname));
soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "hostmaster"),
OneByteString(node_isolate, soa_out->hostmaster));
soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "serial"),
Integer::New(soa_out->serial, node_isolate));
soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "refresh"),
Integer::New(soa_out->refresh, node_isolate));
soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "retry"),
Integer::New(soa_out->retry, node_isolate));
soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "expire"),
Integer::New(soa_out->expire, node_isolate));
soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "minttl"),
Integer::New(soa_out->minttl, node_isolate));
soa_record->Set(env()->nsname_string(),
OneByteString(env()->isolate(), soa_out->nsname));
soa_record->Set(env()->hostmaster_string(),
OneByteString(env()->isolate(), soa_out->hostmaster));
soa_record->Set(env()->serial_string(),
Integer::New(soa_out->serial, env()->isolate()));
soa_record->Set(env()->refresh_string(),
Integer::New(soa_out->refresh, env()->isolate()));
soa_record->Set(env()->retry_string(),
Integer::New(soa_out->retry, env()->isolate()));
soa_record->Set(env()->expire_string(),
Integer::New(soa_out->expire, env()->isolate()));
soa_record->Set(env()->minttl_string(),
Integer::New(soa_out->minttl, env()->isolate()));

ares_free_data(soa_out);

@@ -803,7 +791,7 @@ class GetHostByAddrWrap: public QueryWrap {
void Parse(struct hostent* host) {
HandleScope handle_scope(env()->isolate());
Context::Scope context_scope(env()->context());
this->CallOnComplete(HostentToNames(host));
this->CallOnComplete(HostentToNames(env(), host));
}
};

@@ -825,10 +813,10 @@ class GetHostByNameWrap: public QueryWrap {

protected:
void Parse(struct hostent* host) {
HandleScope scope(node_isolate);
HandleScope scope(env()->isolate());

Local<Array> addresses = HostentToAddresses(host);
Local<Integer> family = Integer::New(host->h_addrtype, node_isolate);
Local<Array> addresses = HostentToAddresses(env(), host);
Local<Integer> family = Integer::New(host->h_addrtype, env()->isolate());

this->CallOnComplete(addresses, family);
}
@@ -865,8 +853,8 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
Context::Scope context_scope(env->context());

Local<Value> argv[] = {
Integer::New(status, node_isolate),
Null(node_isolate)
Integer::New(status, env->isolate()),
Null(env->isolate())
};

if (status == 0) {
@@ -906,7 +894,7 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
continue;

// Create JavaScript string
Local<String> s = OneByteString(node_isolate, ip);
Local<String> s = OneByteString(env->isolate(), ip);
results->Set(n, s);
n++;
}
@@ -933,7 +921,7 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
continue;

// Create JavaScript string
Local<String> s = OneByteString(node_isolate, ip);
Local<String> s = OneByteString(env->isolate(), ip);
results->Set(n, s);
n++;
}
@@ -956,7 +944,8 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {


static void IsIP(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

String::AsciiValue ip(args[0]);
char address_buffer[sizeof(struct in6_addr)];
@@ -1041,7 +1030,7 @@ static void GetServers(const FunctionCallbackInfo<Value>& args) {
int err = uv_inet_ntop(cur->family, caddr, ip, sizeof(ip));
assert(err == 0);

Local<String> addr = OneByteString(node_isolate, ip);
Local<String> addr = OneByteString(env->isolate(), ip);
server_array->Set(i, addr);
}

@@ -1121,9 +1110,10 @@ static void SetServers(const FunctionCallbackInfo<Value>& args) {


static void StrError(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());
const char* errmsg = ares_strerror(args[0]->Int32Value());
args.GetReturnValue().Set(OneByteString(node_isolate, errmsg));
args.GetReturnValue().Set(OneByteString(env->isolate(), errmsg));
}


@@ -1169,12 +1159,12 @@ static void Initialize(Handle<Object> target,
NODE_SET_METHOD(target, "getServers", GetServers);
NODE_SET_METHOD(target, "setServers", SetServers);

target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "AF_INET"),
Integer::New(AF_INET, node_isolate));
target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "AF_INET6"),
Integer::New(AF_INET6, node_isolate));
target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "AF_UNSPEC"),
Integer::New(AF_UNSPEC, node_isolate));
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AF_INET"),
Integer::New(AF_INET, env->isolate()));
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AF_INET6"),
Integer::New(AF_INET6, env->isolate()));
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AF_UNSPEC"),
Integer::New(AF_UNSPEC, env->isolate()));
}

} // namespace cares_wrap
@@ -23,6 +23,7 @@
#define SRC_ENV_INL_H_

#include "env.h"
#include "node.h"
#include "util.h"
#include "util-inl.h"
#include "uv.h"
@@ -364,6 +365,57 @@ inline Environment::IsolateData* Environment::isolate_data() const {
return isolate_data_;
}

// this would have been a template function were it not for the fact that g++
// sometimes fails to resolve it...
#define THROW_ERROR(fun) \
do { \
v8::HandleScope scope(isolate); \
v8::ThrowException(fun(OneByteString(isolate, errmsg))); \
} \
while (0)

inline void Environment::ThrowError(v8::Isolate* isolate, const char* errmsg) {
THROW_ERROR(v8::Exception::Error);
}

inline void Environment::ThrowTypeError(v8::Isolate* isolate,
const char* errmsg) {
THROW_ERROR(v8::Exception::TypeError);
}

inline void Environment::ThrowRangeError(v8::Isolate* isolate,
const char* errmsg) {
THROW_ERROR(v8::Exception::RangeError);
}

inline void Environment::ThrowError(const char* errmsg) {
ThrowError(isolate(), errmsg);
}

inline void Environment::ThrowTypeError(const char* errmsg) {
ThrowTypeError(isolate(), errmsg);
}

inline void Environment::ThrowRangeError(const char* errmsg) {
ThrowRangeError(isolate(), errmsg);
}

inline void Environment::ThrowErrnoException(int errorno,
const char* syscall,
const char* message,
const char* path) {
v8::ThrowException(
ErrnoException(isolate(), errorno, syscall, message, path));
}

inline void Environment::ThrowUVException(int errorno,
const char* syscall,
const char* message,
const char* path) {
v8::ThrowException(
UVException(isolate(), errorno, syscall, message, path));
}

#define V(PropertyName, StringValue) \
inline \
v8::Local<v8::String> Environment::IsolateData::PropertyName() const { \
@@ -54,6 +54,7 @@ namespace node {
#define PER_ISOLATE_STRING_PROPERTIES(V) \
V(address_string, "address") \
V(args_string, "args") \
V(argv_string, "argv") \
V(async_queue_string, "_asyncQueue") \
V(async, "async") \
V(atime_string, "atime") \
@@ -62,21 +63,35 @@ namespace node {
V(blocks_string, "blocks") \
V(buffer_string, "buffer") \
V(bytes_string, "bytes") \
V(bytes_parsed_string, "bytesParsed") \
V(byte_length_string, "byteLength") \
V(callback_string, "callback") \
V(change_string, "change") \
V(close_string, "close") \
V(code_string, "code") \
V(ctime_string, "ctime") \
V(cwd_string, "cwd") \
V(debug_port_string, "debugPort") \
V(debug_string, "debug") \
V(detached_string, "detached") \
V(dev_string, "dev") \
V(disposed_string, "_disposed") \
V(domain_string, "domain") \
V(exchange_string, "exchange") \
V(idle_string, "idle") \
V(irq_string, "irq") \
V(enter_string, "enter") \
V(env_pairs_string, "envPairs") \
V(env_string, "env") \
V(errno_string, "errno") \
V(error_string, "error") \
V(events_string, "_events") \
V(exec_argv_string, "execArgv") \
V(exec_path_string, "execPath") \
V(exiting_string, "_exiting") \
V(exit_code_string, "exitCode") \
V(exit_string, "exit") \
V(expire_string, "expire") \
V(exponent_string, "exponent") \
V(exports_string, "exports") \
V(ext_key_usage_string, "ext_key_usage") \
@@ -86,30 +101,42 @@ namespace node {
V(file_string, "file") \
V(fingerprint_string, "fingerprint") \
V(flags_string, "flags") \
V(fsevent_string, "FSEvent") \
V(gid_string, "gid") \
V(handle_string, "handle") \
V(headers_string, "headers") \
V(heap_size_limit_string, "heap_size_limit") \
V(heap_total_string, "heapTotal") \
V(heap_used_string, "heapUsed") \
V(hostmaster_string, "hostmaster") \
V(ignore_string, "ignore") \
V(immediate_callback_string, "_immediateCallback") \
V(inherit_string, "inherit") \
V(ino_string, "ino") \
V(input_string, "input") \
V(internal_string, "internal") \
V(ipv4_string, "IPv4") \
V(ipv6_lc_string, "ipv6") \
V(ipv6_string, "IPv6") \
V(issuer_string, "issuer") \
V(kill_signal_string, "killSignal") \
V(mac_string, "mac") \
V(mark_sweep_compact_string, "mark-sweep-compact") \
V(max_buffer_string, "maxBuffer") \
V(message_string, "message") \
V(method_string, "method") \
V(minttl_string, "minttl") \
V(mode_string, "mode") \
V(model_string, "model") \
V(modulus_string, "modulus") \
V(mtime_string, "mtime") \
V(name_string, "name") \
V(need_imm_cb_string, "_needImmediateCallback") \
V(netmask_string, "netmask") \
V(nice_string, "nice") \
V(nlink_string, "nlink") \
V(nsname_string, "nsname") \
V(offset_string, "offset") \
V(onchange_string, "onchange") \
V(onclienthello_string, "onclienthello") \
V(oncomplete_string, "oncomplete") \
@@ -127,17 +154,33 @@ namespace node {
V(onsignal_string, "onsignal") \
V(onstop_string, "onstop") \
V(output_string, "output") \
V(order_string, "order") \
V(owner_string, "owner") \
V(parse_error_string, "Parse Error") \
V(path_string, "path") \
V(pbkdf2_error_string, "PBKDF2 Error") \
V(pid_string, "pid") \
V(pipe_string, "pipe") \
V(port_string, "port") \
V(preference_string, "preference") \
V(priority_string, "priority") \
V(processed_string, "processed") \
V(prototype_string, "prototype") \
V(rdev_string, "rdev") \
V(readable_string, "readable") \
V(received_shutdown_string, "receivedShutdown") \
V(refresh_string, "refresh") \
V(regexp_string, "regexp") \
V(rename_string, "rename") \
V(replacement_string, "replacement") \
V(retry_string, "retry") \
V(rss_string, "rss") \
V(serial_string, "serial") \
V(scavenge_string, "scavenge") \
V(scopeid_string, "scopeid") \
V(sent_shutdown_string, "sentShutdown") \
V(serial_number_string, "serialNumber") \
V(service_string, "service") \
V(servername_string, "servername") \
V(session_id_string, "sessionId") \
V(should_keep_alive_string, "shouldKeepAlive") \
@@ -146,33 +189,51 @@ namespace node {
V(smalloc_p_string, "_smalloc_p") \
V(sni_context_err_string, "Invalid SNI context") \
V(sni_context_string, "sni_context") \
V(speed_string, "speed") \
V(stack_string, "stack") \
V(status_code_string, "statusCode") \
V(status_message_string, "statusMessage") \
V(status_string, "status") \
V(stdio_string, "stdio") \
V(subject_string, "subject") \
V(subjectaltname_string, "subjectaltname") \
V(sys_string, "sys") \
V(syscall_string, "syscall") \
V(tick_callback_string, "_tickCallback") \
V(tick_domain_cb_string, "_tickDomainCallback") \
V(tick_info_string, "_tickInfo") \
V(timeout_string, "timeout") \
V(times_string, "times") \
V(timestamp_string, "timestamp") \
V(title_string, "title") \
V(tls_npn_string, "tls_npn") \
V(tls_sni_string, "tls_sni") \
V(tls_string, "tls") \
V(tls_ticket_string, "tlsTicket") \
V(total_heap_size_executable_string, "total_heap_size_executable") \
V(total_heap_size_string, "total_heap_size") \
V(total_physical_size_string, "total_physical_size") \
V(type_string, "type") \
V(uid_string, "uid") \
V(unknown_string, "<unknown>") \
V(upgrade_string, "upgrade") \
V(url_string, "url") \
V(used_heap_size_string, "used_heap_size") \
V(user_string, "user") \
V(uv_string, "uv") \
V(valid_from_string, "valid_from") \
V(valid_to_string, "valid_to") \
V(verify_error_string, "verifyError") \
V(version_major_string, "versionMajor") \
V(version_minor_string, "versionMinor") \
V(version_string, "version") \
V(weight_string, "weight") \
V(windows_verbatim_arguments_string, "windowsVerbatimArguments") \
V(wrap_string, "wrap") \
V(writable_string, "writable") \
V(write_queue_size_string, "writeQueueSize") \
V(x_forwarded_string, "x-forwarded-for") \
V(zero_return_string, "ZERO_RETURN") \

#define ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V) \
V(async_listener_run_function, v8::Function) \
@@ -330,6 +391,23 @@ class Environment {
inline bool printed_error() const;
inline void set_printed_error(bool value);

inline void ThrowError(const char* errmsg);
inline void ThrowTypeError(const char* errmsg);
inline void ThrowRangeError(const char* errmsg);
inline void ThrowErrnoException(int errorno,
const char* syscall = NULL,
const char* message = NULL,
const char* path = NULL);
inline void ThrowUVException(int errorno,
const char* syscall = NULL,
const char* message = NULL,
const char* path = NULL);

// Convenience methods for contextify
inline static void ThrowError(v8::Isolate* isolate, const char* errmsg);
inline static void ThrowTypeError(v8::Isolate* isolate, const char* errmsg);
inline static void ThrowRangeError(v8::Isolate* isolate, const char* errmsg);

// Strings are shared across shared contexts. The getters simply proxy to
// the per-isolate primitive.
#define V(PropertyName, StringValue) \
@@ -81,14 +81,16 @@ FSEventWrap::~FSEventWrap() {
void FSEventWrap::Initialize(Handle<Object> target,
Handle<Value> unused,
Handle<Context> context) {
Environment* env = Environment::GetCurrent(context);

Local<FunctionTemplate> t = FunctionTemplate::New(New);
t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(FIXED_ONE_BYTE_STRING(node_isolate, "FSEvent"));
t->SetClassName(env->fsevent_string());

NODE_SET_PROTOTYPE_METHOD(t, "start", Start);
NODE_SET_PROTOTYPE_METHOD(t, "close", Close);

target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "FSEvent"), t->GetFunction());
target->Set(env->fsevent_string(), t->GetFunction());
}


@@ -101,12 +103,13 @@ void FSEventWrap::New(const FunctionCallbackInfo<Value>& args) {


void FSEventWrap::Start(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

FSEventWrap* wrap = Unwrap<FSEventWrap>(args.This());

if (args.Length() < 1 || !args[0]->IsString()) {
return ThrowTypeError("Bad arguments");
return env->ThrowTypeError("Bad arguments");
}

String::Utf8Value path(args[0]);
@@ -158,7 +161,7 @@ void FSEventWrap::OnEvent(uv_fs_event_t* handle, const char* filename,
// unreasonable, right? Still, we should revisit this before v1.0.
Local<String> event_string;
if (status) {
event_string = String::Empty(node_isolate);
event_string = String::Empty(env->isolate());
} else if (events & UV_RENAME) {
event_string = env->rename_string();
} else if (events & UV_CHANGE) {
@@ -169,21 +172,22 @@ void FSEventWrap::OnEvent(uv_fs_event_t* handle, const char* filename,
}

Local<Value> argv[] = {
Integer::New(status, node_isolate),
Integer::New(status, env->isolate()),
event_string,
Null(node_isolate)
Null(env->isolate())
};

if (filename != NULL) {
argv[2] = OneByteString(node_isolate, filename);
argv[2] = OneByteString(env->isolate(), filename);
}

wrap->MakeCallback(env->onchange_string(), ARRAY_SIZE(argv), argv);
}


void FSEventWrap::Close(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

FSEventWrap* wrap = Unwrap<FSEventWrap>(args.This());

@@ -44,7 +44,8 @@ extern QUEUE handle_wrap_queue;


void HandleWrap::Ref(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

HandleWrap* wrap = Unwrap<HandleWrap>(args.This());

@@ -56,7 +57,8 @@ void HandleWrap::Ref(const FunctionCallbackInfo<Value>& args) {


void HandleWrap::Unref(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

HandleWrap* wrap = Unwrap<HandleWrap>(args.This());

@@ -68,15 +70,15 @@ void HandleWrap::Unref(const FunctionCallbackInfo<Value>& args) {


void HandleWrap::Close(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

HandleWrap* wrap = Unwrap<HandleWrap>(args.This());

// guard against uninitialized handle or double close
if (wrap == NULL || wrap->handle__ == NULL)
return;

Environment* env = wrap->env();
assert(!wrap->persistent().IsEmpty());
uv_close(wrap->handle__, OnClose);
wrap->handle__ = NULL;
@@ -96,7 +98,7 @@ HandleWrap::HandleWrap(Environment* env,
flags_(0),
handle__(handle) {
handle__->data = this;
HandleScope scope(node_isolate);
HandleScope scope(env->isolate());
Wrap<HandleWrap>(object, this);
QUEUE_INSERT_TAIL(&handle_wrap_queue, &handle_wrap_queue_);
}
@@ -109,10 +111,9 @@ HandleWrap::~HandleWrap() {


void HandleWrap::OnClose(uv_handle_t* handle) {
HandleScope scope(node_isolate);

HandleWrap* wrap = static_cast<HandleWrap*>(handle->data);
Environment* env = wrap->env();
HandleScope scope(env->isolate());

// The wrap object should still be there.
assert(wrap->persistent().IsEmpty() == false);

Large diffs are not rendered by default.

@@ -61,19 +61,47 @@
#include "v8.h" // NOLINT(build/include_order)
#include "node_version.h" // NODE_MODULE_VERSION

#define NODE_DEPRECATED(msg, fn) V8_DEPRECATED(msg, fn)

// Forward-declare these functions now to stop MSVS from becoming
// terminally confused when it's done in node_internals.h
namespace node {

NODE_EXTERN v8::Local<v8::Value> ErrnoException(int errorno,
NODE_EXTERN v8::Local<v8::Value> ErrnoException(v8::Isolate* isolate,
int errorno,
const char* syscall = NULL,
const char* message = NULL,
const char* path = NULL);
NODE_EXTERN v8::Local<v8::Value> UVException(int errorno,
NODE_EXTERN v8::Local<v8::Value> UVException(v8::Isolate* isolate,
int errorno,
const char* syscall = NULL,
const char* message = NULL,
const char* path = NULL);

NODE_DEPRECATED("Use UVException(isolate, ...)",
inline v8::Local<v8::Value> ErrnoException(
int errorno,
const char* syscall = NULL,
const char* message = NULL,
const char* path = NULL) {
return ErrnoException(v8::Isolate::GetCurrent(),
errorno,
syscall,
message,
path);
})

inline v8::Local<v8::Value> UVException(int errorno,
const char* syscall = NULL,
const char* message = NULL,
const char* path = NULL) {
return UVException(v8::Isolate::GetCurrent(),
errorno,
syscall,
message,
path);
}

/*
* MakeCallback doesn't have a HandleScope. That means the callers scope
* will retain ownership of created handles from MakeCallback and related.
@@ -187,27 +215,79 @@ inline void NODE_SET_PROTOTYPE_METHOD(v8::Handle<v8::FunctionTemplate> recv,
#define NODE_SET_PROTOTYPE_METHOD node::NODE_SET_PROTOTYPE_METHOD

enum encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER};
enum encoding ParseEncoding(v8::Handle<v8::Value> encoding_v,
enum encoding ParseEncoding(v8::Isolate* isolate,
v8::Handle<v8::Value> encoding_v,
enum encoding _default = BINARY);
NODE_EXTERN void FatalException(const v8::TryCatch& try_catch);

NODE_EXTERN v8::Local<v8::Value> Encode(const void *buf, size_t len,
NODE_DEPRECATED("Use ParseEncoding(isolate, ...)",
inline enum encoding ParseEncoding(
v8::Handle<v8::Value> encoding_v,
enum encoding _default = BINARY) {
return ParseEncoding(v8::Isolate::GetCurrent(), encoding_v, _default);
})

NODE_EXTERN void FatalException(v8::Isolate* isolate,
const v8::TryCatch& try_catch);

NODE_DEPRECATED("Use FatalException(isolate, ...)",
inline void FatalException(const v8::TryCatch& try_catch) {
return FatalException(v8::Isolate::GetCurrent(), try_catch);
})

NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate,
const void* buf,
size_t len,
enum encoding encoding = BINARY);
NODE_DEPRECATED("Use Encode(isolate, ...)",
inline v8::Local<v8::Value> Encode(
const void* buf,
size_t len,
enum encoding encoding = BINARY) {
return Encode(v8::Isolate::GetCurrent(), buf, len, encoding);
})

// Returns -1 if the handle was not valid for decoding
NODE_EXTERN ssize_t DecodeBytes(v8::Handle<v8::Value>,
NODE_EXTERN ssize_t DecodeBytes(v8::Isolate* isolate,
v8::Handle<v8::Value>,
enum encoding encoding = BINARY);
NODE_DEPRECATED("Use DecodeBytes(isolate, ...)",
inline ssize_t DecodeBytes(
v8::Handle<v8::Value> val,
enum encoding encoding = BINARY) {
return DecodeBytes(v8::Isolate::GetCurrent(), val, encoding);
})

// returns bytes written.
NODE_EXTERN ssize_t DecodeWrite(char *buf,
NODE_EXTERN ssize_t DecodeWrite(v8::Isolate* isolate,
char* buf,
size_t buflen,
v8::Handle<v8::Value>,
enum encoding encoding = BINARY);
NODE_DEPRECATED("Use DecodeWrite(isolate, ...)",
inline ssize_t DecodeWrite(char* buf,
size_t buflen,
v8::Handle<v8::Value> val,
enum encoding encoding = BINARY) {
return DecodeWrite(v8::Isolate::GetCurrent(), buf, buflen, val, encoding);
})

#ifdef _WIN32
NODE_EXTERN v8::Local<v8::Value> WinapiErrnoException(int errorno,
const char *syscall = NULL, const char *msg = "",
NODE_EXTERN v8::Local<v8::Value> WinapiErrnoException(
v8::Isolate* isolate,
int errorno,
const char *syscall = NULL,
const char *msg = "",
const char *path = NULL);

NODE_DEPRECATED("Use WinapiErrnoException(isolate, ...)",
inline v8::Local<v8::Value> WinapiErrnoException(int errorno,
const char *syscall = NULL, const char *msg = "",
const char *path = NULL) {
return WinapiErrnoException(v8::Isolate::GetCurrent(),
errorno,
syscall,
msg,
path);
})
#endif

const char *signo_string(int errorno);
@@ -37,7 +37,9 @@
#define MIN(a, b) ((a) < (b) ? (a) : (b))

#define CHECK_NOT_OOB(r) \
do { if (!(r)) return ThrowRangeError("out of range index"); } while (0)
do { \
if (!(r)) return env->ThrowRangeError("out of range index"); \
} while (0)

#define ARGS_THIS(argT) \
Local<Object> obj = argT; \
@@ -66,6 +68,7 @@ using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Handle;
using v8::HandleScope;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
@@ -113,35 +116,34 @@ size_t Length(Handle<Object> obj) {
}


Local<Object> New(Handle<String> string, enum encoding enc) {
HandleScope scope(node_isolate);
Local<Object> New(Isolate* isolate, Handle<String> string, enum encoding enc) {
HandleScope scope(isolate);

size_t length = StringBytes::Size(string, enc);
size_t length = StringBytes::Size(isolate, string, enc);

Local<Object> buf = New(length);
char* data = Buffer::Data(buf);
StringBytes::Write(data, length, string, enc);
StringBytes::Write(isolate, data, length, string, enc);

return scope.Close(buf);
}


Local<Object> New(size_t length) {
HandleScope handle_scope(node_isolate);
Environment* env = Environment::GetCurrent(node_isolate);
Local<Object> obj = Buffer::New(env, length);
Local<Object> New(Isolate* isolate, size_t length) {
HandleScope handle_scope(isolate);
Local<Object> obj = Buffer::New(Environment::GetCurrent(isolate), length);
return handle_scope.Close(obj);
}


// TODO(trevnorris): these have a flaw by needing to call the Buffer inst then
// Alloc. continue to look for a better architecture.
Local<Object> New(Environment* env, size_t length) {
HandleScope scope(node_isolate);
HandleScope scope(env->isolate());

assert(length <= kMaxLength);

Local<Value> arg = Uint32::NewFromUnsigned(length, node_isolate);
Local<Value> arg = Uint32::NewFromUnsigned(length, env->isolate());
Local<Object> obj = env->buffer_constructor_function()->NewInstance(1, &arg);

// TODO(trevnorris): done like this to handle HasInstance since only checks
@@ -155,15 +157,15 @@ Local<Object> New(Environment* env, size_t length) {
} else {
data = NULL;
}
smalloc::Alloc(obj, data, length);
smalloc::Alloc(env, obj, data, length);

return scope.Close(obj);
}


Local<Object> New(const char* data, size_t length) {
HandleScope handle_scope(node_isolate);
Environment* env = Environment::GetCurrent(node_isolate);
Local<Object> New(Isolate* isolate, const char* data, size_t length) {
Environment* env = Environment::GetCurrent(isolate);
HandleScope handle_scope(env->isolate());
Local<Object> obj = Buffer::New(env, data, length);
return handle_scope.Close(obj);
}
@@ -173,11 +175,11 @@ Local<Object> New(const char* data, size_t length) {
// but for consistency w/ the other should use data. And a copy version renamed
// to something else.
Local<Object> New(Environment* env, const char* data, size_t length) {
HandleScope scope(node_isolate);
HandleScope scope(env->isolate());

assert(length <= kMaxLength);

Local<Value> arg = Uint32::NewFromUnsigned(length, node_isolate);
Local<Value> arg = Uint32::NewFromUnsigned(length, env->isolate());
Local<Object> obj = env->buffer_constructor_function()->NewInstance(1, &arg);

// TODO(trevnorris): done like this to handle HasInstance since only checks
@@ -193,18 +195,19 @@ Local<Object> New(Environment* env, const char* data, size_t length) {
new_data = NULL;
}

smalloc::Alloc(obj, new_data, length);
smalloc::Alloc(env, obj, new_data, length);

return scope.Close(obj);
}


Local<Object> New(char* data,
Local<Object> New(Isolate* isolate,
char* data,
size_t length,
smalloc::FreeCallback callback,
void* hint) {
HandleScope handle_scope(node_isolate);
Environment* env = Environment::GetCurrent(node_isolate);
Environment* env = Environment::GetCurrent(isolate);
HandleScope handle_scope(env->isolate());
Local<Object> obj = Buffer::New(env, data, length, callback, hint);
return handle_scope.Close(obj);
}
@@ -215,50 +218,51 @@ Local<Object> New(Environment* env,
size_t length,
smalloc::FreeCallback callback,
void* hint) {
HandleScope scope(node_isolate);
HandleScope scope(env->isolate());

assert(length <= kMaxLength);

Local<Value> arg = Uint32::NewFromUnsigned(length, node_isolate);
Local<Value> arg = Uint32::NewFromUnsigned(length, env->isolate());
Local<Object> obj = env->buffer_constructor_function()->NewInstance(1, &arg);

smalloc::Alloc(obj, data, length, callback, hint);
smalloc::Alloc(env, obj, data, length, callback, hint);

return scope.Close(obj);
}


Local<Object> Use(char* data, uint32_t length) {
HandleScope handle_scope(node_isolate);
Environment* env = Environment::GetCurrent(node_isolate);
Local<Object> Use(Isolate* isolate, char* data, uint32_t length) {
Environment* env = Environment::GetCurrent(isolate);
HandleScope handle_scope(env->isolate());
Local<Object> obj = Buffer::Use(env, data, length);
return handle_scope.Close(obj);
}


Local<Object> Use(Environment* env, char* data, uint32_t length) {
HandleScope scope(node_isolate);
HandleScope scope(env->isolate());

assert(length <= kMaxLength);

Local<Value> arg = Uint32::NewFromUnsigned(length, node_isolate);
Local<Value> arg = Uint32::NewFromUnsigned(length, env->isolate());
Local<Object> obj = env->buffer_constructor_function()->NewInstance(1, &arg);

smalloc::Alloc(obj, data, length);
smalloc::Alloc(env, obj, data, length);

return scope.Close(obj);
}


template <encoding encoding>
void StringSlice(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

ARGS_THIS(args.This())
SLICE_START_END(args[0], args[1], obj_length)

args.GetReturnValue().Set(
StringBytes::Encode(obj_data + start, length, encoding));
StringBytes::Encode(env->isolate(), obj_data + start, length, encoding));
}


@@ -294,12 +298,13 @@ void Base64Slice(const FunctionCallbackInfo<Value>& args) {

// bytesCopied = buffer.copy(target[, targetStart][, sourceStart][, sourceEnd]);
void Copy(const FunctionCallbackInfo<Value> &args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

Local<Object> target = args[0]->ToObject();

if (!HasInstance(target))
return ThrowTypeError("first arg should be a Buffer");
return env->ThrowTypeError("first arg should be a Buffer");

ARGS_THIS(args.This())
size_t target_length = target->GetIndexedPropertiesExternalArrayDataLength();
@@ -318,7 +323,7 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
return args.GetReturnValue().Set(0);

if (source_start > obj_length)
return ThrowRangeError("out of range index");
return env->ThrowRangeError("out of range index");

if (source_end - source_start > target_length - target_start)
source_end = source_start + target_length - target_start;
@@ -334,7 +339,8 @@ void Copy(const FunctionCallbackInfo<Value> &args) {

// buffer.fill(value[, start][, end]);
void Fill(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

ARGS_THIS(args.This())
SLICE_START_END(args[1], args[2], obj_length)
@@ -379,17 +385,18 @@ void Fill(const FunctionCallbackInfo<Value>& args) {

template <encoding encoding>
void StringWrite(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

ARGS_THIS(args.This())

if (!args[0]->IsString())
return ThrowTypeError("Argument must be a string");
return env->ThrowTypeError("Argument must be a string");

Local<String> str = args[0]->ToString();

if (encoding == HEX && str->Length() % 2 != 0)
return ThrowTypeError("Invalid hex string");
return env->ThrowTypeError("Invalid hex string");

size_t offset;
size_t max_length;
@@ -406,9 +413,10 @@ void StringWrite(const FunctionCallbackInfo<Value>& args) {
max_length = max_length / 2;

if (offset >= obj_length)
return ThrowRangeError("Offset is out of bounds");
return env->ThrowRangeError("Offset is out of bounds");

uint32_t written = StringBytes::Write(obj_data + offset,
uint32_t written = StringBytes::Write(env->isolate(),
obj_data + offset,
max_length,
str,
encoding,
@@ -459,6 +467,7 @@ static inline void Swizzle(char* start, unsigned int len) {

template <typename T, enum Endianness endianness>
void ReadFloatGeneric(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args.GetIsolate());
bool doAssert = !args[1]->BooleanValue();
size_t offset;

@@ -467,7 +476,7 @@ void ReadFloatGeneric(const FunctionCallbackInfo<Value>& args) {
if (doAssert) {
size_t len = Length(args.This());
if (offset + sizeof(T) > len || offset + sizeof(T) < offset)
return ThrowRangeError("Trying to read beyond buffer length");
return env->ThrowRangeError("Trying to read beyond buffer length");
}

union NoAlias {
@@ -508,20 +517,21 @@ void ReadDoubleBE(const FunctionCallbackInfo<Value>& args) {

template <typename T, enum Endianness endianness>
uint32_t WriteFloatGeneric(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args.GetIsolate());
bool doAssert = !args[2]->BooleanValue();

T val = static_cast<T>(args[0]->NumberValue());
size_t offset;

if (!ParseArrayIndex(args[1], 0, &offset)) {
ThrowRangeError("out of range index");
env->ThrowRangeError("out of range index");
return 0;
}

if (doAssert) {
size_t len = Length(args.This());
if (offset + sizeof(T) > len || offset + sizeof(T) < offset) {
ThrowRangeError("Trying to write beyond buffer length");
env->ThrowRangeError("Trying to write beyond buffer length");
return 0;
}
}
@@ -562,7 +572,8 @@ void WriteDoubleBE(const FunctionCallbackInfo<Value>& args) {


void ToArrayBuffer(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

ARGS_THIS(args.This());
void* adata = malloc(obj_length);
@@ -581,30 +592,30 @@ void ToArrayBuffer(const FunctionCallbackInfo<Value>& args) {


void ByteLength(const FunctionCallbackInfo<Value> &args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

if (!args[0]->IsString())
return ThrowTypeError("Argument must be a string");
return env->ThrowTypeError("Argument must be a string");

Local<String> s = args[0]->ToString();
enum encoding e = ParseEncoding(args[1], UTF8);
enum encoding e = ParseEncoding(env->isolate(), args[1], UTF8);

uint32_t size = StringBytes::Size(s, e);
uint32_t size = StringBytes::Size(env->isolate(), s, e);
args.GetReturnValue().Set(size);
}


// pass Buffer object to load prototype methods
void SetupBufferJS(const FunctionCallbackInfo<Value>& args) {
HandleScope handle_scope(args.GetIsolate());
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

assert(args[0]->IsFunction());

Local<Function> bv = args[0].As<Function>();
env->set_buffer_constructor_function(bv);
Local<Value> proto_v =
bv->Get(FIXED_ONE_BYTE_STRING(node_isolate, "prototype"));
Local<Value> proto_v = bv->Get(env->prototype_string());

assert(proto_v->IsObject());

@@ -640,15 +651,15 @@ void SetupBufferJS(const FunctionCallbackInfo<Value>& args) {
NODE_SET_METHOD(proto, "fill", Fill);

// for backwards compatibility
proto->Set(FIXED_ONE_BYTE_STRING(node_isolate, "offset"),
Uint32::New(0, node_isolate),
proto->Set(env->offset_string(),
Uint32::New(0, env->isolate()),
v8::ReadOnly);

assert(args[1]->IsObject());

Local<Object> internal = args[1].As<Object>();

internal->Set(FIXED_ONE_BYTE_STRING(node_isolate, "byteLength"),
internal->Set(env->byte_length_string(),
FunctionTemplate::New(ByteLength)->GetFunction());
}

@@ -43,22 +43,52 @@ NODE_EXTERN size_t Length(v8::Handle<v8::Value> val);
NODE_EXTERN size_t Length(v8::Handle<v8::Object> val);

// public constructor
NODE_EXTERN v8::Local<v8::Object> New(size_t length);
NODE_EXTERN v8::Local<v8::Object> New(v8::Isolate* isolate, size_t length);
NODE_DEPRECATED("Use New(isolate, ...)",
inline v8::Local<v8::Object> New(size_t length) {
return New(v8::Isolate::GetCurrent(), length);
})
// public constructor from string
NODE_EXTERN v8::Local<v8::Object> New(v8::Handle<v8::String> string,
NODE_EXTERN v8::Local<v8::Object> New(v8::Isolate* isolate,
v8::Handle<v8::String> string,
enum encoding enc = UTF8);
NODE_DEPRECATED("Use New(isolate, ...)",
inline v8::Local<v8::Object> New(v8::Handle<v8::String> string,
enum encoding enc = UTF8) {
return New(v8::Isolate::GetCurrent(), string, enc);
})
// public constructor - data is copied
// TODO(trevnorris): should be something like Copy()
NODE_EXTERN v8::Local<v8::Object> New(const char* data, size_t len);
NODE_EXTERN v8::Local<v8::Object> New(v8::Isolate* isolate,
const char* data,
size_t len);
NODE_DEPRECATED("Use New(isolate, ...)",
inline v8::Local<v8::Object> New(const char* data, size_t len) {
return New(v8::Isolate::GetCurrent(), data, len);
})
// public constructor - data is used, callback is passed data on object gc
NODE_EXTERN v8::Local<v8::Object> New(char* data,
NODE_EXTERN v8::Local<v8::Object> New(v8::Isolate* isolate,
char* data,
size_t length,
smalloc::FreeCallback callback,
void* hint);
NODE_DEPRECATED("Use New(isolate, ...)",
inline v8::Local<v8::Object> New(char* data,
size_t length,
smalloc::FreeCallback callback,
void* hint) {
return New(v8::Isolate::GetCurrent(), data, length, callback, hint);
})

// public constructor - data is used.
// TODO(trevnorris): should be New() for consistency
NODE_EXTERN v8::Local<v8::Object> Use(char* data, uint32_t len);
NODE_EXTERN v8::Local<v8::Object> Use(v8::Isolate* isolate,
char* data,
uint32_t len);
NODE_DEPRECATED("Use Use(isolate, ...)",
inline v8::Local<v8::Object> Use(char* data, uint32_t len) {
return Use(v8::Isolate::GetCurrent(), data, len);
})

// This is verbose to be explicit with inline commenting
static inline bool IsWithinBounds(size_t off, size_t len, size_t max) {
@@ -930,6 +930,22 @@ void DefineOpenSSLConstants(Handle<Object> target) {

# endif // !OPENSSL_NO_ENGINE

#ifdef DH_CHECK_P_NOT_SAFE_PRIME
NODE_DEFINE_CONSTANT(target, DH_CHECK_P_NOT_SAFE_PRIME);
#endif

#ifdef DH_CHECK_P_NOT_PRIME
NODE_DEFINE_CONSTANT(target, DH_CHECK_P_NOT_PRIME);
#endif

#ifdef DH_UNABLE_TO_CHECK_GENERATOR
NODE_DEFINE_CONSTANT(target, DH_UNABLE_TO_CHECK_GENERATOR);
#endif

#ifdef DH_NOT_SUITABLE_GENERATOR
NODE_DEFINE_CONSTANT(target, DH_NOT_SUITABLE_GENERATOR);
#endif

#ifdef OPENSSL_NPN_NEGOTIATED
#define NPN_ENABLED 1
NODE_DEFINE_CONSTANT(target, NPN_ENABLED);