Compare commits

..

2 Commits

Author SHA1 Message Date
Trent Mick
1f4e0c02b5 build: fix gcc 4.7 sunos build
gcc 4.7 doesn't understand -threads, use -pthreads instead.

Fixes #4211.
2012-10-30 22:48:38 +01:00
Ben Noordhuis
7fd1c08b16 bench: backport http_simple benchmark from master 2011-10-29 07:23:01 +02:00
7688 changed files with 317652 additions and 1628313 deletions

1
.gitattributes vendored
View File

@@ -1 +0,0 @@
test/fixtures/* -text

53
.gitignore vendored
View File

@@ -1,13 +1,10 @@
core
vgcore.*
v8*.log
perf.data
perf.data.old
build
.waf*
tags
.lock-wscript
*.pyc
doc/api.xml
tools/nodejs.pc
tmp/
node
node_g
@@ -15,49 +12,3 @@ node_g
.benchmark_reports
/.project
/.cproject
icu_config.gypi
/out
# various stuff that VC++ produces/uses
Debug/
Release/
!doc/blog/**
*.sln
!nodemsi.sln
*.suo
*.vcproj
*.vcxproj
*.vcxproj.user
*.vcxproj.filters
UpgradeLog*.XML
_UpgradeReport_Files/
ipch/
*.sdf
*.opensdf
/config.mk
/config.gypi
*-nodegyp*
/gyp-mac-tool
/dist-osx
/npm.wxs
/tools/msvs/npm.wixobj
email.md
deps/v8-*
./node_modules
.svn/
# generated by gyp on Windows
deps/openssl/openssl.props
deps/openssl/openssl.targets
deps/openssl/openssl.xml
# build/release artifacts
/*.tar.gz
/SHASUMS*.txt*
/tools/wrk/wrk
# test artifacts
tools/faketime

122
.mailmap
View File

@@ -1,122 +0,0 @@
Aaron Heckmann <aaron.heckmann@gmail.com> <aaron.heckmann+github@gmail.com>
Abe Fettig <abefettig@gmail.com> <abe@fettig.net>
Alex Kocharin <rlidwka@kocharin.ru>
Alex Kocharin <rlidwka@kocharin.ru> <alex@kocharin.ru>
Alexis Sellier <self@cloudhead.net>
Alexis Sellier <self@cloudhead.net> <alexis@cloudhead.io>
Arlo Breault <arlolra@gmail.com>
Artem Zaytsev <a.arepo@gmail.com>
Atsuo Fukaya <fukayatsu@gmail.com>
Ben Noordhuis <info@bnoordhuis.nl> <bnoordhuis@bender.(none)>
Ben Taber <ben.taber@gmail.com>
Bert Belder <bertbelder@gmail.com> <bert@piscisaureus2.(none)>
Bert Belder <bertbelder@gmail.com> <info@2bs.nl>
Bert Belder <bertbelder@gmail.com> <piscisaureus@Berts-MacBook-Pro.local>
Brandon Benvie <brandon@bbenvie.com> <brandon@brandonbenvie.com>
Brian White <mscdex@mscdex.net>
Brian White <mscdex@mscdex.net> <mscdex@gmail.com>
Chew Choon Keat <choonkeat@gmail.com>
Christopher Lenz <cmlenz@gmail.com> <chris@lamech.local>
Daniel Berger <code+node@dpbis.net>
Daniel Chcouri <333222@gmail.com>
Daniel Gröber <darklord@darkboxed.org>
Daniel Gröber <darklord@darkboxed.org> <dxld@darkboxed.org>
Daniel Pihlström <sciolist.se@gmail.com>
Dave Pacheco <dap@joyent.com> <dap@cs.brown.edu>
David Siegel <david@artcom.de> <david.siegel@artcom.de>
Domenic Denicola <domenic@domenicdenicola.com>
Eduard Burtescu <eddy_me08@yahoo.com>
Einar Otto Stangvik <einaros@gmail.com>
Elliott Cable <me@ell.io>
EungJun Yi <semtlenori@gmail.com>
Evan Larkin <evan.larkin.il.com> <evan.larkin.iit@gmail.com>
Farid Neshat <FaridN_SOAD@yahoo.com>
Felix Böhm <felixboehm55@googlemail.com> <me@feedic.com>
Felix Geisendörfer <felix@debuggable.com>
Felix Geisendörfer <felix@debuggable.com>
Friedemann Altrock <frodenius@gmail.com>
Fuji Goro <gfuji@cpan.org>
Gabriel de Perthuis <g2p.code@gmail.com>
Gil Pedersen <git@gpost.dk> <github@gpost.dk>
Henry Chin <hheennrryy@gmail.com>
Herbert Vojčík <herby@mailbox.sk>
Igor Soarez <igorsoarez@gmail.com>
Igor Zinkovsky <igorzi@microsoft.com>
Isaac Z. Schlueter <i@izs.me>
Isaac Z. Schlueter <i@izs.me> <i@foohack.com>
Jake Verbaten <raynos2@gmail.com>
Jered Schmidt <tr@nslator.jp>
Joe Shaw <joe@joeshaw.org> <joeshaw@litl.com>
Johan Bergström <bugs@bergstroem.nu>
Johan Dahlberg <jfd@distrop.com> <dahlberg.johan@gmail.com>
Jonas Pfenniger <jonas@pfenniger.name> <jonas@stvs.ch>
Jonathan Rentzsch <jwr.git@redshed.net>
Josh Erickson <josh@snoj.us>
Joshua S. Weinstein <josher19@users.sf.net>
Jérémy Lal <kapouer@melix.org>
Jérémy Lal <kapouer@melix.org> <holisme@gmail.com>
Kai Sasaki Lewuathe <sasaki_kai@lewuathe.sakura.ne.jp>
Kazuyuki Yamada <tasogare.pg@gmail.com>
Koichi Kobayashi <koichik@improvement.jp>
Kris Kowal <kris.kowal@cixar.com>
Kyle Robinson Young <kyle@dontkry.com>
Luke Bayes <lbayes@patternpark.com>
Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com>
Mathias Pettersson <mape@mape.me>
Michael Bernstein <michaelrbernstein@gmail.com>
Michael Wilber <gcr@sneakygcr.net>
Micheil Smith <micheil@brandedcode.com> <micheil@yettobebranded.net>
Mikael Bourges-Sevenier <mikeseven@gmail.com> <msevenier@motorola.com>
Nebu Pookins<nebu@nebupookins.net>
Nicholas Kinsey <pyrotechnick@feistystudios.com>
Onne Gorter <onne@onnlucky.com>
Paul Querna <pquerna@apache.org> <paul@querna.org>
Ray Morgan <rmorgan@zappos.com>
Ray Solomon <raybsolomon@gmail.com>
Rick Olson <technoweenie@gmail.com>
Ryan Dahl <ry@tinyclouds.org>
Ryan Emery <seebees@gmail.com>
Sam Shull <brickysam26@gmail.com> <brickysam26@samuel-shulls-computer.local>
Sam Shull <brickysam26@gmail.com> <sshull@squaremouth.com>
Sambasiva Suda <sambasivarao@gmail.com>
San-Tai Hsu <v@fatpipi.com>
Scott Blomquist <github@scott.blomqui.st> <sblom@microsoft.com>
Sergey Kryzhanovsky <skryzhanovsky@gmail.com> <another@dhcp199-223-red.yandex.net>
Shannen Saez <shannenlaptop@gmail.com>
Shigeki Ohtsu <ohtsu@d.jp> <ohtsu@iij.ad.jp>
Siddharth Mahendraker <siddharth_mahen@hotmail.com> <siddharth_mahen@me.com>
Simon Willison <simon@simonwillison.net>
Stanislav Opichal <opichals@gmail.com>
Stefan Bühler <stbuehler@web.de>
TJ Holowaychuk <tj@vision-media.ca>
TJ Holowaychuk <tj@vision-media.ca> <tjholowayhuk@gmail.com>
Tadashi SAWADA <cesare@mayverse.jp>
Takahiro ANDO <takahiro.ando@gmail.com>
Ted Young <ted@radicaldesigns.org>
Thomas Lee <thomas.lee@shinetech.com> <tom@tom-debian.sensis.com.au>
Tim Caswell <tim@creationix.com> <tim@0-26-8-e9-4c-e1.dyn.utdallas.edu>
Tim Price <timprice@mangoraft.com>
Tim Smart <timehandgod@gmail.com> <tim@fostle.com>
Tim Smart <timehandgod@gmail.com> <timehandgod@gmail.com>
Tom Hughes-Croucher <tom.hughes@palm.com>
Tom Hughes-Croucher <tom.hughes@palm.com> <tom_croucher@yahoo.com>
Trevor Burnham <trevor@databraid.com> <trevorburnham@gmail.com>
Tyler Larson <talltyler@gmail.com>
Vincent Voyer <v@fasterize.com>
Willi Eggeling <email@wje-online.de>
Yoshihiro KIKUCHI <yknetg@gmail.com>
Yuichiro MASUI <masui@masuidrive.jp>
Zachary Scott <zachary@zacharyscott.net> <zachary.s.scott@gmail.com>
Zoran Tomicic <ztomicic@gmail.com>
# These people didn't contribute patches to node directly,
# but we've landed their v8 patches in the node repository:
Daniel Clifford <danno@chromium.org>
Erik Corry <erik.corry@gmail.com>
Jakob Kummerow <jkummerow@chromium.org>
Kevin Millikin <kmillikin@chromium.org>
Lasse R.H. Nielsen <lrn@chromium.org>
Michael Starzinger <mstarzinger@chromium.org>
Toon Verwaest <verwaest@chromium.org>
Vyacheslav Egorov <vegorov@chromium.org>
Yang Guo <yangguo@chromium.org>

View File

@@ -1,14 +0,0 @@
language: node_js
before_script:
- "./configure"
- "make"
script:
- "make test"
notifications:
email: false
irc:
- "irc.freenode.net#libuv"

358
AUTHORS
View File

@@ -59,7 +59,7 @@ Arlo Breault <arlolra@gmail.com>
Kris Kowal <kris.kowal@cixar.com>
Jacek Becela <jacek.becela@gmail.com>
Rob Ellis <kazoomer@gmail.com>
Tim Smart <timehandgod@gmail.com>
Tim Smart <timehAndGod@gmail.com>
Herbert Vojčík <herby@mailbox.sk>
Krishna Rajendran <krishna@emptybox.org>
Nicholas Kinsey <pyrotechnick@feistystudios.com>
@@ -98,7 +98,8 @@ Jerome Etienne <jerome.etienne@gmail.com>
Dmitriy Shalashov <skaurus@gmail.com>
Adam Wiggins <adam@heroku.com>
Rick Olson <technoweenie@gmail.com>
Sergey Kryzhanovsky <skryzhanovsky@gmail.com>
David Siegel <david.siegel@artcom.de>
Sergey Kzyzhanovsky <skryzhanovsky@gmail.com>
Marco Rogers <marco.rogers@gmail.com>
Benjamin Fritsch <beanie@benle.de>
Jan Kassens <jan@kassens.net>
@@ -124,7 +125,7 @@ Sam Stephenson <sam@37signals.com>
Jorge Chamorro Bieling <jorge@jorgechamorro.com>
Evan Larkin <evan.larkin.il.com>
Sean Coates <sean@seancoates.com>
Tom Hughes-Croucher <tom.hughes@palm.com>
Tom Hughes <tom.hughes@palm.com>
Joshua Peek <josh@joshpeek.com>
Nathan Rajlich <nathan@tootallnate.net>
Peteris Krumins <peteris.krumins@gmail.com>
@@ -143,13 +144,13 @@ Daniel Gröber <darklord@darkboxed.org>
Travis Swicegood <development@domain51.com>
Oleg Slobodskoi <oleg008@gmail.com>
Jeremy Martin <jmar777@gmail.com>
Michael Wilber <gcr@sneakygcr.net>
Michael W <gcr@sneakygcr.net>
Sean Braithwaite <brapse@gmail.com>
Anders Conbere <aconbere@gmail.com>
Devin Torres <devin@devintorres.com>
Theo Schlossnagle <jesus@omniti.com>
Kai Chen <kaichenxyz@gmail.com>
Daniel Chcouri <333222@gmail.com>
Daniel C <333222@gmail.com>
Mihai Călin Bazon <mihai@bazon.net>
Ali Farhadi <a.farhadi@gmail.com>
Daniel Ennis <aikar@aikar.co>
@@ -158,375 +159,38 @@ Greg Hughes <greg@ghughes.com>
David Trejo <david.daniel.trejo@gmail.com>
Joe Walnes <joe@walnes.com>
Koichi Kobayashi <koichik@improvement.jp>
Daniel Gröber <dxld@darkboxed.org>
Konstantin Käfer <github@kkaefer.com>
Richard Rodger <richard@ricebridge.com>
Andreas Reich <andreas@reich.name>
Tony Huang <cnwzhjs@gmail.com>
Dean McNamee <dean@gmail.com>
Trevor Burnham <trevor@databraid.com>
Zachary Scott <zachary@zacharyscott.net>
Zachary Scott <zachary.s.scott@gmail.com>
Arnout Kazemier <info@3rd-Eden.com>
George Stagas <gstagas@gmail.com>
Ben Weaver <ben@orangesoda.net>
Scott McWhirter <scott.mcwhirter@joyent.com>
Jakub Lekstan <jakub.lekstan@dreamlab.pl>
Nick Campbell <nicholas.j.campbell@gmail.com>
Nebu Pookins <nebu@nebupookins.net>
Tim Baumann <tim@timbaumann.info>
Robert Mustacchi <rm@joyent.com>
George Miroshnykov <george.miroshnykov@gmail.com>
Mark Cavage <mark.cavage@joyent.com>
Håvard Stranden <havard.stranden@gmail.com>
Marcel Laverdet <marcel@laverdet.com>
Alexandre Marangone <a.marangone@gmail.com>
Mark Cavage <mark.cavage@joyent.com>
Ryan Petrello <lists@ryanpetrello.com>
Fuji Goro <gfuji@cpan.org>
Siddharth Mahendraker <siddharth_mahen@hotmail.com>
Dave Pacheco <dap@joyent.com>
Mathias Buus <m@ge.tt>
Henry Rawas <henryr@schakra.com>
Yoshihiro KIKUCHI <yknetg@gmail.com>
Brett Kiefer <kiefer@gmail.com>
Mariano Iglesias <mariano@cricava.com>
Jörn Horstmann <git@jhorstmann.net>
Joe Shaw <joe@joeshaw.org>
Niklas Fiekas <niklas.fiekas@googlemail.com>
Adam Luikart <me@adamluikart.com>
Artem Zaytsev <a.arepo@gmail.com>
Joe Shaw <joeshaw@litl.com>
Alex Xu <alex_y_xu@yahoo.ca>
Jeremy Selier <jeremy@jolicloud.com>
Igor Zinkovsky <igorzi@microsoft.com>
Kip Gebhardt <kip.gebhardt@voxer.com>
Stefan Rusu <saltwaterc@gmail.com>
Shigeki Ohtsu <ohtsu@d.jp>
Wojciech Wnętrzak <w.wnetrzak@gmail.com>
Devon Govett <devongovett@gmail.com>
Steve Engledow <steve.engledow@proxama.com>
Pierre-Alexandre St-Jean <pierrealexandre.stjean@gmail.com>
Reid Burke <me@reidburke.com>
Vicente Jimenez Aguilar <googuy@gmail.com>
Tadashi SAWADA <cesare@mayverse.jp>
Jeroen Janssen <jeroen.janssen@gmail.com>
Daniel Pihlström <sciolist.se@gmail.com>
Stefan Bühler <stbuehler@web.de>
Alexander Uvarov <alexander.uvarov@gmail.com>
Aku Kotkavuo <aku@hibana.net>
Peter Bright <drpizza@quiscalusmexicanus.org>
SAWADA Tadashi <cesare@mayverse.jp>
Logan Smyth <loganfsmyth@gmail.com>
Christopher Wright <christopherwright@gmail.com>
Glen Low <glen.low@pixelglow.com>
Thomas Shinnick <tshinnic@gmail.com>
Mickaël Delahaye <mickael.delahaye@gmail.com>
Antranig Basman <antranig.basman@colorado.edu>
Maciej Małecki <maciej.malecki@notimplemented.org>
Evan Martin <martine@danga.com>
Peter Lyons <pete@peterlyons.com>
Jann Horn <jannhorn@googlemail.com>
Abimanyu Raja <abimanyuraja@gmail.com>
Niclas Hoyer <niclas@verbugt.de>
Karl Skomski <karl@skomski.com>
Michael Jackson <mjijackson@gmail.com>
Ashok Mudukutore <ashok@lineratesystems.com>
Sean Cunningham <sean.cunningham@mandiant.com>
Vitor Balocco <vitorbal@gmail.com>
Ben Leslie <benno@benno.id.au>
Eric Lovett <etlovett@gmail.com>
Christian Tellnes <christian@tellnes.no>
Colton Baker <github@netrefuge.net>
Tyler Larson <talltyler@gmail.com>
Tomasz Janczuk <tomasz@janczuk.org>
Ilya Dmitrichenko <errordeveloper@gmail.com>
Simen Brekken <simen.brekken@gmail.com>
Guglielmo Ferri <44gatti@gmail.com>
Thomas Parslow <tom@almostobsolete.net>
Ryan Emery <seebees@gmail.com>
Jordan Sissel <jls@semicomplete.com>
Matt Robenolt <matt@ydekproductions.com>
Jacob H.C. Kragh <jhckragh@gmail.com>
Benjamin Pasero <benjamin.pasero@gmail.com>
Scott Anderson <sanderson7@gmail.com>
Yoji SHIDARA <dara@shidara.net>
Mathias Bynens <mathias@qiwi.be>
Łukasz Walukiewicz <lukasz@walukiewicz.eu>
Artur Adib <arturadib@gmail.com>
E. Azer Koçulu <azer@kodfabrik.com>
Paddy Byers <paddy.byers@gmail.com>
Roman Shtylman <shtylman@gmail.com>
Kyle Robinson Young <kyle@dontkry.com>
Tim Oxley <secoif@gmail.com>
Eduard Burtescu <eddy_me08@yahoo.com>
Ingmar Runge <ingmar@irsoft.de>
Russ Bradberry <rbradberry@gmail.com>
Andreas Madsen <amwebdk@gmail.com>
Adam Malcontenti-Wilson <adman.com@gmail.com>
Avi Flax <avi@aviflax.com>
Pedro Teixeira <pedro.teixeira@gmail.com>
Johan Bergström <bugs@bergstroem.nu>
James Hartig <james.hartig@grooveshark.com>
Shannen Saez <shannenlaptop@gmail.com>
Seong-Rak Choi <ragiragi@hanmail.net>
Dave Irvine <davman99@gmail.com>
Ju-yeong Park <interruptz@gmail.com>
Phil Sung <psung@dnanexus.com>
Damon Oehlman <damon.oehlman@sidelab.com>
Mikael Bourges-Sevenier <mikeseven@gmail.com>
Emerson Macedo <emerleite@gmail.com>
Ryunosuke SATO <tricknotes.rs@gmail.com>
Michael Bernstein <michaelrbernstein@gmail.com>
Guillermo Rauch <rauchg@gmail.com>
Dan Williams <dan@igniter.com>
Brandon Benvie <brandon@bbenvie.com>
Nicolas LaCasse <nlacasse@borderstylo.com>
Dan VerWeire <dverweire@gmail.com>
Matthew Fitzsimmons <matt@joyent.com>
Philip Tellis <philip.tellis@gmail.com>
Christopher Jeffrey <chjjeffrey@gmail.com>
Seth Fitzsimmons <seth@mojodna.net>
Einar Otto Stangvik <einaros@gmail.com>
Paul Vorbach <paul@vorb.de>
Luke Gallagher <notfornoone@gmail.com>
Tomasz Buchert <tomek.buchert@gmail.com>
Myles Byrne <myles@myles.id.au>
T.C. Hollingsworth <tchollingsworth@gmail.com>
Cam Pedersen <diffference@gmail.com>
Roly Fentanes <roly426@gmail.com>
Ted Young <ted@radicaldesigns.org>
Joshua Holbrook <josh.holbrook@gmail.com>
Blake Miner <miner.blake@gmail.com>
Vincent Ollivier <contact@vincentollivier.com>
Jimb Esser <jimb@railgun3d.com>
Sambasiva Suda <sambasivarao@gmail.com>
Sadique Ali <sadiqalikm@gmail.com>
Dmitry Nizovtsev <dmitry@ukrteam.com>
Alex Kocharin <rlidwka@kocharin.ru>
Ming Liu <vmliu1@gmail.com>
Shea Levy <shea@shealevy.com>
Nao Iizuka <iizuka@kyu-mu.net>
Christian Ress <christian@ressonline.de>
Rod Vagg <rod@vagg.org>
Matt Ezell <ezell.matt@gmail.com>
Charlie McConnell <charlie@charlieistheman.com>
Farid Neshat <FaridN_SOAD@yahoo.com>
Johannes Wüller <johanneswueller@gmail.com>
Erik Lundin <mjor.himself@gmail.com>
Bryan Cantrill <bryan@joyent.com>
Yosef Dinerstein <yosefd@microsoft.com>
Nathan Friedly <nathan@nfriedly.com>
Aaron Jacobs <jacobsa@google.com>
Mustansir Golawala <mgolawala@gmail.com>
Atsuo Fukaya <fukayatsu@gmail.com>
Domenic Denicola <domenic@domenicdenicola.com>
Joshua S. Weinstein <josher19@users.sf.net>
Dane Springmeyer <dane@dbsgeo.com>
Erik Dubbelboer <erik@dubbelboer.com>
Malte-Thorben Bruns <skenqbx@googlemail.com>
Michael Thomas <aelmalinka@gmail.com>
Garen Torikian <gjtorikian@gmail.com>
EungJun Yi <semtlenori@gmail.com>
Vincent Voyer <v@fasterize.com>
Takahiro ANDO <takahiro.ando@gmail.com>
Brian Schroeder <bts@gmail.com>
J. Lee Coltrane <lee@projectmastermind.com>
Javier Hernández <jhernandez@emergya.com>
James Koval <james.ross.koval@gmail.com>
Kevin Gadd <kevin.gadd@gmail.com>
Ray Solomon <raybsolomon@gmail.com>
Kevin Bowman <github@magicmonkey.org>
Erwin van der Koogh <github@koogh.com>
Matt Gollob <mattgollob@gmail.com>
Simon Sturmer <sstur@me.com>
Joel Brandt <joelrbrandt@gmail.com>
Marc Harter <wavded@gmail.com>
Nuno Job <nunojobpinto@gmail.com>
Ben Kelly <ben@wanderview.com>
Felix Böhm <felixboehm55@googlemail.com>
George Shank <shankga@gmail.com>
Gabriel de Perthuis <g2p.code@gmail.com>
Vladimir Beloborodov <redhead.ru@gmail.com>
Tim Macfarlane <timmacfarlane@gmail.com>
Jonas Westerlund <jonas.westerlund@me.com>
Dominic Tarr <dominic.tarr@gmail.com>
Justin Plock <jplock@gmail.com>
Timothy J Fontaine <tjfontaine@gmail.com>
Toshihiro Nakamura <toshihiro.nakamura@gmail.com>
Ivan Torres <mexpolk@gmail.com>
Philipp Hagemeister <phihag@phihag.de>
Mike Morearty <mike@morearty.com>
Pavel Lang <langpavel@phpskelet.org>
Peter Rybin <peter.rybin@gmail.com>
Joe Andaverde <joe@andaverde.net>
Eugen Dueck <eugen@dueck.org>
Gil Pedersen <git@gpost.dk>
Tyler Neylon <tylerneylon@gmail.com>
Josh Erickson <josh@snoj.us>
Golo Roden <webmaster@goloroden.de>
Ron Korving <rkorving@wizcorp.jp>
Brandon Wilson <chlavois@gmail.com>
Ian Babrou <ibobrik@gmail.com>
Bearice Ren <bearice@gmail.com>
Ankur Oberoi <aoberoi@gmail.com>
Atsuya Takagi <atsuya.takagi@gmail.com>
Pooya Karimian <pkarimian@sencha.com>
Frédéric Germain <frederic.germain@gmail.com>
Robin Lee <cheeselee@fedoraproject.org>
Kazuyuki Yamada <tasogare.pg@gmail.com>
Adam Blackburn <regality@gmail.com>
Willi Eggeling <email@wje-online.de>
Paul Serby <paul.serby@clock.co.uk>
Andrew Paprocki <andrew@ishiboo.com>
Ricky Ng-Adam <rngadam@lophilo.com>
Aaditya Bhatia <aadityabhatia@gmail.com>
Max Ogden <max@maxogden.com>
Igor Soarez <igorsoarez@gmail.com>
Olivier Lalonde <olalonde@gmail.com>
Francois Marier <francois@mozilla.com>
Trevor Norris <trev.norris@gmail.com>
Kai Sasaki Lewuathe <sasaki_kai@lewuathe.sakura.ne.jp>
Nicolas Chambrier <naholyr@gmail.com>
Tim Bradshaw <tfb@cley.com>
Johannes Ewald <mail@johannesewald.de>
Chris Dent <chris.dent@gmail.com>
Dan Milon <danmilon@gmail.com>
Brandon Philips <brandon.philips@rackspace.com>
Frederico Silva <frederico.silva@gmail.com>
Jan Wynholds <jan@rootmusic.com>
Girish Ramakrishnan <girish@forwardbias.in>
Anthony Pesch <anthony@usamp.com>
Stephen Gallagher <sgallagh@redhat.com>
Sergey Kholodilov <serghol@gmail.com>
Tim Kuijsten <tim@netsend.nl>
Michael Axiak <mike@axiak.net>
Chad Rhyner <chadrhyner@gmail.com>
Ben Taber <ben.taber@gmail.com>
Luke Arduini <luke.arduini@me.com>
Luke Bayes <lbayes@patternpark.com>
Nirk Niggler <nirk.niggler@gmail.com>
James Hight <james@zavoo.com>
Mike Harsch <mike@harschsystems.com>
Alexandr Emelin <frvzmb@gmail.com>
James Campos <james.r.campos@gmail.com>
Dave Olszewski <cxreg@pobox.com>
Tim Price <timprice@mangoraft.com>
Jake Verbaten <raynos2@gmail.com>
Jacob Gable <jacob.gable@gmail.com>
Rick Yakubowski <richard@orpha-systems.com>
Dan Kohn <dan@dankohn.com>
Andy Burke <aburke@bitflood.org>
Sugendran Ganess <sugendran@sugendran.net>
Jim Schubert <james.schubert@gmail.com>
Victor Costan <costan@gmail.com>
Arianit Uka <arianit@bigvikinggames.com>
Andrei Sedoi <bsnote@gmail.com>
Eugene Girshov <eugene.girshov@nixu.com>
Evan Oxfeld <eoxfeld@nearinfinity.com>
Lars-Magnus Skog <lars.magnus.skog@gmail.com>
Raymond Feng <enjoyjava@gmail.com>
Aaron Cannon <cannona@fireantproductions.com>
Xidorn Quan <quanxunzhen@gmail.com>
Paolo Fragomeni <paolo@async.ly>
Scott Blomquist <github@scott.blomqui.st>
Henry Chin <hheennrryy@gmail.com>
Julian Gruber <julian@juliangruber.com>
JeongHoon Byun <outsideris@gmail.com>
Iskren Ivov Chernev <iskren.chernev@gmail.com>
Alexey Kupershtokh <alexey.kupershtokh@gmail.com>
Benjamin Ruston <benjy.ruston@gmail.com>
Mitar Milutinovic <mitar.git@tnode.com>
Michael Hart <michael.hart.au@gmail.com>
Andrew Hart <hartandrewr@gmail.com>
Rafael Garcia <rgarcia2009@gmail.com>
Tobias Müllerleile <tobias@muellerleile.net>
Stanislav Ochotnicky <sochotnicky@redhat.com>
Ryan Graham <r.m.graham@gmail.com>
Kelly Gerber <kellygerber22@yahoo.com>
Ryan Doenges <rhdoenges@gmail.com>
Sean Silva <chisophugis@gmail.com>
Miroslav Bajtoš <miro.bajtos@gmail.com>
Sam Roberts <vieuxtech@gmail.com>
Kevin Locke <kevin@kevinlocke.name>
Daniel Moore <polaris@northhorizon.net>
Robert Kowalski <rok@kowalski.gd>
Benoit Vallée <github@benoitvallee.net>
Ryuichi Okumura <okuryu@okuryu.com>
Brandon Frohs <bfrohs@gmail.com>
Nathan Zadoks <nathan@nathan7.eu>
Rafael Henrique Moreira <rafadev7@gmail.com>
Daniel G. Taylor <dan@programmer-art.org>
Kiyoshi Nomo <tokyoincidents.g@gmail.com>
Veres Lajos <vlajos@gmail.com>
Yuan Chuan <yuanchuan23@gmail.com>
Peter Rust <peter@cornerstonenw.com>
Shuan Wang <shuanwang@gmail.com>
Andrew Chilton <andychilton@gmail.com>
Wyatt Preul <wpreul@gmail.com>
Forrest L Norvell <ogd@aoaioxxysz.net>
Eran Hammer <eran@hueniverse.com>
Daniel Chatfield <chatfielddaniel@gmail.com>
Eivind Uggedal <eivind@uggedal.com>
Edward Hutchins <eahutchins@gmail.com>
Chris Wren <cthewren@gmail.com>
Duan Yao <duanyao@ustc.edu>
Eric Schrock <Eric.Schrock@delphix.com>
Zarko Stankovic <stankovic.zarko@gmail.com>
Maxim Bogushevich <boga1@mail.ru>
Phillip Alexander <git@phillipalexander.io>
Tim Wood <washwithcare@gmail.com>
Linus Unnebäck <linus@folkdatorn.se>
Nikolai Vavilov <vvnicholas@gmail.com>
Michael Ridgway <mcridgway@gmail.com>
Yazhong Liu <yorkiefixer@gmail.com>
Gabriel Falkenberg <gabriel.falkenberg@gmail.com>
Kai Groner <kai@gronr.com>
Gabriel Farrell <g@grrawr.com>
Nicolas Kaiser <nikai@nikai.net>
Lev Gimelfarb <lev.gimelfarb@gmail.com>
Dav Glass <davglass@gmail.com>
ayanamist <contact@ayanamist.com>
Lorenz Leutgeb <lorenz.leutgeb@gmail.com>
Brandon Cheng <bcheng.gt@gmail.com>
Alexis Campailla <alexis@janeasystems.com>
Jun Ma <roammm@gmail.com>
Maxime Quandalle <maxime.quandalle@gmail.com>
Benjamin Waters <ben25890@gmail.com>
Doron Pagot <doronpagot@gmail.com>
Kenan Sulayman <kenan@sly.mn>
Christian Schulz <me@rndm.de>
Pedro Ballesteros <nitroduna@gmail.com>
Anton Khlynovskiy <subzey@gmail.com>
Nicolas Talle <dev@nicolab.net>
Mike Pennisi <mike@mikepennisi.com>
Greg Brail <greg@apigee.com>
Shuhei Kagawa <shuhei.kagawa@gmail.com>
Josh Dague <daguej@email.uc.edu>
Goh Yisheng (Andrew) <mail.yisheng@gmail.com>
William Bert <william@spanishdict.com>
Greg Sabia Tucker <greg@narrowlabs.com>
Calvin Metcalf <calvin.metcalf@gmail.com>
cjihrig <cjihrig@gmail.com>
Chris Barber <chris@cb1inc.com>
Nick Apperson <apperson@gmail.com>
Oguz Bastemur <obastemur@gmail.com>
Maurice Butler <maurice.butler@gmail.com>
Chris Dickinson <christopher.s.dickinson@gmail.com>
Julien Gilli <julien.gilli@joyent.com>
Jakob Gillich <jakob@gillich.me>
James Halliday <mail@substack.net>
Kevin Simper <kevin.simper@gmail.com>
Jackson Tian <shyvo1987@gmail.com>
Tristan Berger <tristan.berger@gmail.com>
Mathias Schreck <schreck.mathias@googlemail.com>
Matthew Fitzsimmons <matt@fitzage.com>
Swaagie <info@martijnswaagman.nl>
Emmanuel Odeke <emmanuel.odeke@cmgcanada.ca>
Eric Mill <eric@konklone.com>
Brendan Ashworth <squirrelslikeacorns@gmail.com>
Alejandro Oviedo <alejandro.oviedo.g@gmail.com>
pkcs <pkcs@gmx.com>
Saúl Ibarra Corretgé <saghul@gmail.com>
silverwind <silv3rwind@gmail.com>
Steven R. Loomis <srl@icu-project.org>
James M Snell <jasnell@gmail.com>
Amir Saboury <amir.saboury@gmail.com>
Florin-Cristian Gavrila <cristi_gavrila1@yahoo.com>
Tyler Anton <mtyleranton@gmail.com>
Jonas Dohse <jonas@dohse.ch>

View File

@@ -1,2 +0,0 @@
all:
@echo "I need GNU make. Please run \`gmake\` instead."

97
CMakeLists.txt Normal file
View File

@@ -0,0 +1,97 @@
cmake_minimum_required(VERSION 2.6)
project(node)
if(USE_GCOV)
set(CMAKE_BUILD_TYPE "Debug")
# Set global c and c++ flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
# Link flags used for creating executables
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcov -fprofile-arcs")
# Link flags used for creating shared libraries
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lgcov -profile-arcs")
endif()
#
# options
#
find_package(PythonInterp 2 REQUIRED)
option(SHARED_V8 "use system shared V8 library")
option(SHARED_LIBEV "use system shared libev library")
option(SHARED_CARES "use system shared c-ares library")
option(V8_SNAPSHOT "turn on snapshot when building stock v8")
option(V8_OPROFILE "Add oprofile support")
option(V8_GDBJIT "add gdbjit support")
option(DTRACE "build with DTrace (experimental)")
# cmake policies to get rid of some warnings
cmake_policy(SET CMP0009 NEW) # GLOB_RECURSE should no follow symlinks
# generic cmake configuration
include("cmake/configure.cmake")
# find and configure libs
include("cmake/libs.cmake")
# setup node build targets
include("cmake/node_build.cmake")
# setup v8 build targets
include("cmake/v8_build.cmake")
# docs
## might want to move this to doc/CMakeLists.txt
include("cmake/docs.cmake")
# tests
enable_testing()
include(CTest)
add_subdirectory("test/")
# package
include("cmake/package.cmake")
#
# Final build configuration output
#
message("** Build Summary **")
message(" Version: ${node_version_string}")
message(" Prefix: ${PREFIX}")
message(" Build Type: ${CMAKE_BUILD_TYPE}")
message(" Architecture: ${CMAKE_SYSTEM_PROCESSOR}")
message(" Platform: ${node_platform}")
if(SHARED_V8)
message(" V8: ${V8_LIBRARY_PATH}")
#else()
#message(" V8 jobs: ${parallel_jobs}")
endif()
if(SHARED_libev)
message(" libev: ${LIBEV_LIBRARY}")
endif()
if(SHARED_CARES)
message(" libc-ares: ${LIBCARES_LIBRARY}")
endif()
message(" RT library: ${RT}")
message(" DL library: ${DL}")
if(${OPENSSL_FOUND} MATCHES TRUE)
message(" OpenSSL: ${OPENSSL_LIBRARIES}")
endif()
if(USE_GCOV)
message(" gcov: enabled")
endif()
message(" CCFLAGS: ${CCFLAGS}")
message(" CPPFLAGS: ${CPPFLAGS}")

View File

@@ -1,141 +0,0 @@
# CONTRIBUTING
The node.js project welcomes new contributors. This document will guide you
through the process.
### FORK
Fork the project [on GitHub](https://github.com/joyent/node) and check out
your copy.
```
$ git clone git@github.com:username/node.git
$ cd node
$ git remote add upstream git://github.com/joyent/node.git
```
Now decide if you want your feature or bug fix to go into the master branch
or the stable branch. As a rule of thumb, bug fixes go into the stable branch
while new features go into the master branch.
The stable branch is effectively frozen; patches that change the node.js
API/ABI or affect the run-time behavior of applications get rejected.
The rules for the master branch are less strict; consult the
[stability index page][] for details.
In a nutshell, modules are at varying levels of API stability. Bug fixes are
always welcome but API or behavioral changes to modules at stability level 3
and up are off-limits.
Node.js has several bundled dependencies in the deps/ and the tools/
directories that are not part of the project proper. Any changes to files
in those directories or its subdirectories should be sent to their respective
projects. Do not send your patch to us, we cannot accept it.
In case of doubt, open an issue in the [issue tracker][], post your question
to the [node.js mailing list][] or contact one of the [project maintainers][]
on [IRC][].
Especially do so if you plan to work on something big. Nothing is more
frustrating than seeing your hard work go to waste because your vision
does not align with that of a project maintainer.
### BRANCH
Okay, so you have decided on the proper branch. Create a feature branch
and start hacking:
```
$ git checkout -b my-feature-branch -t origin/v0.10
```
(Where v0.10 is the latest stable branch as of this writing.)
### COMMIT
Make sure git knows your name and email address:
```
$ git config --global user.name "J. Random User"
$ git config --global user.email "j.random.user@example.com"
```
Writing good commit logs is important. A commit log should describe what
changed and why. Follow these guidelines when writing one:
1. The first line should be 50 characters or less and contain a short
description of the change prefixed with the name of the changed
subsystem (e.g. "net: add localAddress and localPort to Socket").
2. Keep the second line blank.
3. Wrap all other lines at 72 columns.
A good commit log looks like this:
```
subsystem: explaining the commit in one line
Body of commit message is a few lines of text, explaining things
in more detail, possibly giving some background about the issue
being fixed, etc etc.
The body of the commit message can be several paragraphs, and
please do proper word-wrap and keep columns shorter than about
72 characters or so. That way `git log` will show things
nicely even when it is indented.
```
The header line should be meaningful; it is what other people see when they
run `git shortlog` or `git log --oneline`.
Check the output of `git log --oneline files_that_you_changed` to find out
what subsystem (or subsystems) your changes touch.
### REBASE
Use `git rebase` (not `git merge`) to sync your work from time to time.
```
$ git fetch upstream
$ git rebase upstream/v0.10 # or upstream/master
```
### TEST
Bug fixes and features should come with tests. Add your tests in the
test/simple/ directory. Look at other tests to see how they should be
structured (license boilerplate, common includes, etc.).
```
$ make jslint test
```
Make sure the linter is happy and that all tests pass. Please, do not submit
patches that fail either check.
### PUSH
```
$ git push origin my-feature-branch
```
Go to https://github.com/username/node and select your feature branch. Click
the 'Pull Request' button and fill out the form.
Pull requests are usually reviewed within a few days. If there are comments
to address, apply your changes in a separate commit and push that to your
feature branch. Post a comment in the pull request afterwards; GitHub does
not send out notifications when you add commits.
[stability index page]: https://github.com/joyent/node/blob/master/doc/api/documentation.markdown
[issue tracker]: https://github.com/joyent/node/issues
[node.js mailing list]: http://groups.google.com/group/nodejs
[IRC]: http://webchat.freenode.net/?channels=node.js
[project maintainers]: https://github.com/joyent/node/wiki/Project-Organization

7
CTestConfig.cmake Normal file
View File

@@ -0,0 +1,7 @@
set(CTEST_PROJECT_NAME "node")
set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")
set(CTEST_DROP_METHOD "http")
set(CTEST_DROP_SITE "my.cdash.org")
set(CTEST_DROP_LOCATION "/submit.php?project=node")
set(CTEST_DROP_SITE_CDASH TRUE)

3193
ChangeLog

File diff suppressed because it is too large Load Diff

801
LICENSE
View File

@@ -24,788 +24,45 @@ IN THE SOFTWARE.
====
This license applies to all parts of Node that are not externally
maintained libraries. The externally maintained libraries used by Node are:
maintained libraries.
- V8, located at deps/v8. V8's license follows:
"""
This license applies to all parts of V8 that are not externally
maintained libraries. The externally maintained libraries used by V8
are:
The externally maintained libraries used by Node are:
- PCRE test suite, located in
test/mjsunit/third_party/regexp-pcre.js. This is based on the
test suite from PCRE-7.3, which is copyrighted by the University
of Cambridge and Google, Inc. The copyright notice and license
are embedded in regexp-pcre.js.
- v8, located at deps/v8. v8 is copyright Google, Inc, and released
under a BSD license.
- Layout tests, located in test/mjsunit/third_party. These are
based on layout tests from webkit.org which are copyrighted by
Apple Computer, Inc. and released under a 3-clause BSD license.
- libev, located at deps/libev, and libeio, located at deps/libeio. libev
and libeio are copyright Marc Alexander Lehmann, and dual-licensed
under the MIT license and GPL2.
- Strongtalk assembler, the basis of the files assembler-arm-inl.h,
assembler-arm.cc, assembler-arm.h, assembler-ia32-inl.h,
assembler-ia32.cc, assembler-ia32.h, assembler-x64-inl.h,
assembler-x64.cc, assembler-x64.h, assembler-mips-inl.h,
assembler-mips.cc, assembler-mips.h, assembler.cc and assembler.h.
This code is copyrighted by Sun Microsystems Inc. and released
under a 3-clause BSD license.
- WAF build system, located at tools/waf. WAF is copyright Thomas Nagy,
and released under the MIT license.
- Valgrind client API header, located at third_party/valgrind/valgrind.h
This is release under the BSD license.
- The SCONS build system, located at tools/scons. SCONS is copyright
the SCONS Foundation and released under the MIT license.
These libraries have their own licenses; we recommend you read them,
as their terms may differ from the terms below.
Copyright 2006-2012, the V8 project authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
- C-Ares, an asynchronous DNS client, located at deps/cares. C-Ares license
follows:
"""
/* Copyright 1998 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
"""
- OpenSSL located at deps/openssl. OpenSSL is cryptographic software written
by Eric Young (eay@cryptsoft.com) to provide SSL/TLS encryption. OpenSSL's
license follows:
"""
/* ====================================================================
* Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
"""
- HTTP Parser, located at deps/http_parser. HTTP Parser's license follows:
"""
http_parser.c is based on src/http/ngx_http_parse.c from NGINX copyright
Igor Sysoev.
Additional changes are licensed under the same terms as NGINX and
copyright Joyent, Inc. and other Node contributors. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
"""
- Closure Linter is located at tools/closure_linter. Closure's license
follows:
"""
# Copyright (c) 2007, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
- tools/cpplint.py is a C++ linter. Its license follows:
"""
# Copyright (c) 2009 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
- lib/punycode.js is copyright 2011 Mathias Bynens <http://mathiasbynens.be/>
and released under the MIT license.
"""
* Punycode.js <http://mths.be/punycode>
* Copyright 2011 Mathias Bynens <http://mathiasbynens.be/>
* Available under MIT license <http://mths.be/mit>
"""
- tools/gyp. GYP is a meta-build system. GYP's license follows:
"""
Copyright (c) 2009 Google Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
- Zlib at deps/zlib. zlib's license follows:
"""
/* zlib.h -- interface of the 'zlib' general purpose compression library
version 1.2.8, April 28th, 2013
Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
*/
"""
- npm is a package manager program located at deps/npm.
npm's license follows:
"""
Copyright (c) Isaac Z. Schlueter
All rights reserved.
npm is released under the Artistic 2.0 License.
The text of the License follows:
--------
The Artistic License 2.0
Copyright (c) 2000-2006, The Perl Foundation.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
This license establishes the terms under which a given free software
Package may be copied, modified, distributed, and/or redistributed.
The intent is that the Copyright Holder maintains some artistic
control over the development of that Package while still keeping the
Package available as open source and free software.
You are always permitted to make arrangements wholly outside of this
license directly with the Copyright Holder of a given Package. If the
terms of this license do not permit the full use that you propose to
make of the Package, you should contact the Copyright Holder and seek
a different licensing arrangement.
Definitions
"Copyright Holder" means the individual(s) or organization(s)
named in the copyright notice for the entire Package.
"Contributor" means any party that has contributed code or other
material to the Package, in accordance with the Copyright Holder's
procedures.
"You" and "your" means any person who would like to copy,
distribute, or modify the Package.
"Package" means the collection of files distributed by the
Copyright Holder, and derivatives of that collection and/or of
those files. A given Package may consist of either the Standard
Version, or a Modified Version.
"Distribute" means providing a copy of the Package or making it
accessible to anyone else, or in the case of a company or
organization, to others outside of your company or organization.
"Distributor Fee" means any fee that you charge for Distributing
this Package or providing support for this Package to another
party. It does not mean licensing fees.
"Standard Version" refers to the Package if it has not been
modified, or has been modified only in ways explicitly requested
by the Copyright Holder.
"Modified Version" means the Package, if it has been changed, and
such changes were not explicitly requested by the Copyright
Holder.
"Original License" means this Artistic License as Distributed with
the Standard Version of the Package, in its current version or as
it may be modified by The Perl Foundation in the future.
"Source" form means the source code, documentation source, and
configuration files for the Package.
"Compiled" form means the compiled bytecode, object code, binary,
or any other form resulting from mechanical transformation or
translation of the Source form.
Permission for Use and Modification Without Distribution
(1) You are permitted to use the Standard Version and create and use
Modified Versions for any purpose without restriction, provided that
you do not Distribute the Modified Version.
Permissions for Redistribution of the Standard Version
(2) You may Distribute verbatim copies of the Source form of the
Standard Version of this Package in any medium without restriction,
either gratis or for a Distributor Fee, provided that you duplicate
all of the original copyright notices and associated disclaimers. At
your discretion, such verbatim copies may or may not include a
Compiled form of the Package.
(3) You may apply any bug fixes, portability changes, and other
modifications made available from the Copyright Holder. The resulting
Package will still be considered the Standard Version, and as such
will be subject to the Original License.
Distribution of Modified Versions of the Package as Source
(4) You may Distribute your Modified Version as Source (either gratis
or for a Distributor Fee, and with or without a Compiled form of the
Modified Version) provided that you clearly document how it differs
from the Standard Version, including, but not limited to, documenting
any non-standard features, executables, or modules, and provided that
you do at least ONE of the following:
(a) make the Modified Version available to the Copyright Holder
of the Standard Version, under the Original License, so that the
Copyright Holder may include your modifications in the Standard
Version.
(b) ensure that installation of your Modified Version does not
prevent the user installing or running the Standard Version. In
addition, the Modified Version must bear a name that is different
from the name of the Standard Version.
(c) allow anyone who receives a copy of the Modified Version to
make the Source form of the Modified Version available to others
under
(i) the Original License or
(ii) a license that permits the licensee to freely copy,
modify and redistribute the Modified Version using the same
licensing terms that apply to the copy that the licensee
received, and requires that the Source form of the Modified
Version, and of any works derived from it, be made freely
available in that license fees are prohibited but Distributor
Fees are allowed.
Distribution of Compiled Forms of the Standard Version
or Modified Versions without the Source
(5) You may Distribute Compiled forms of the Standard Version without
the Source, provided that you include complete instructions on how to
get the Source of the Standard Version. Such instructions must be
valid at the time of your distribution. If these instructions, at any
time while you are carrying out such distribution, become invalid, you
must provide new instructions on demand or cease further distribution.
If you provide valid instructions or cease distribution within thirty
days after you become aware that the instructions are invalid, then
you do not forfeit any of your rights under this license.
(6) You may Distribute a Modified Version in Compiled form without
the Source, provided that you comply with Section 4 with respect to
the Source of the Modified Version.
Aggregating or Linking the Package
(7) You may aggregate the Package (either the Standard Version or
Modified Version) with other packages and Distribute the resulting
aggregation provided that you do not charge a licensing fee for the
Package. Distributor Fees are permitted, and licensing fees for other
components in the aggregation are permitted. The terms of this license
apply to the use and Distribution of the Standard or Modified Versions
as included in the aggregation.
(8) You are permitted to link Modified and Standard Versions with
other works, to embed the Package in a larger work of your own, or to
build stand-alone binary or bytecode versions of applications that
include the Package, and Distribute the result without restriction,
provided the result does not expose a direct interface to the Package.
Items That are Not Considered Part of a Modified Version
(9) Works (including, but not limited to, modules and scripts) that
merely extend or make use of the Package, do not, by themselves, cause
the Package to be a Modified Version. In addition, such works are not
considered parts of the Package itself, and are not subject to the
terms of this license.
General Provisions
(10) Any use, modification, and distribution of the Standard or
Modified Versions is governed by this Artistic License. By using,
modifying or distributing the Package, you accept this license. Do not
use, modify, or distribute the Package, if you do not accept this
- C-Ares, an asynchronous DNS client, located at deps/c-ares. C-Ares is
copyright the Massachusetts Institute of Technology, authored by
Greg Hudson, Daniel Stenberg and others, and released under the MIT
license.
(11) If your Modified Version has been derived from a Modified
Version made by someone other than you, you are nevertheless required
to ensure that your Modified Version complies with the requirements of
this license.
- Node, optionally, dynamically links to OpenSSL, cryptographic software
written by Eric Young (eay@cryptsoft.com) to provide SSL/TLS encryption.
OpenSSL is copyright The OpenSSL Project and released under the OpenSSL
license. OpenSSL is not included in the Node distribution.
See http://openssl.org/ for more information.
(12) This license does not grant you the right to use any trademark,
service mark, tradename, or logo of the Copyright Holder.
- tools/doctool/markdown.js is copyright 2009-2010 Dominic Baggott and Ash
Berli and released under the MIT license.
(13) This license includes the non-exclusive, worldwide,
free-of-charge patent license to make, have made, use, offer to sell,
sell, import and otherwise transfer the Package with respect to any
patent claims licensable by the Copyright Holder that are necessarily
infringed by the Package. If you institute patent litigation
(including a cross-claim or counterclaim) against any party alleging
that the Package constitutes direct or contributory patent
infringement, then this Artistic License to you shall terminate on the
date that such litigation is filed.
- HTTP Parser, located at deps/http_parser, is a small C library
copyright Ryan Lienhart Dahl and released under the MIT license.
(14) Disclaimer of Warranty:
THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL
LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- src/platform_darwin_proctitle.cc, has code taken from the Chromium
project copyright Google Inc. and released under a BSD license.
- tools/closure_linter is copyright The Closure Linter Authors and
Google Inc. and released under the Apache License, version 2.0.
--------
"Node.js" and "node" trademark Joyent, Inc. npm is not officially
part of the Node.js project, and is neither owned by nor
officially affiliated with Joyent, Inc.
Packages published in the npm registry (other than the Software and
its included dependencies) are not part of npm itself, are the sole
property of their respective maintainers, and are not covered by
this license.
"npm Logo" created by Mathias Pettersson and Brian Hammond,
used with permission.
"Gubblebum Blocky" font
Copyright (c) by Tjarda Koster, http://jelloween.deviantart.com
included for use in the npm website and documentation,
used with permission.
This program uses several Node modules contained in the node_modules/
subdirectory, according to the terms of their respective licenses.
"""
- tools/doc/node_modules/marked. Marked is a Markdown parser. Marked's
license follows:
"""
Copyright (c) 2011-2012, Christopher Jeffrey (https://github.com/chjj/)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
- test/gc/node_modules/weak. Node-weak is a node.js addon that provides garbage
collector notifications. Node-weak's license follows:
"""
Copyright (c) 2011, Ben Noordhuis <info@bnoordhuis.nl>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
"""
- src/ngx-queue.h. ngx-queue.h is taken from the nginx source tree. nginx's
license follows:
"""
Copyright (C) 2002-2012 Igor Sysoev
Copyright (C) 2011,2012 Nginx, Inc.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
"""
- wrk is located at tools/wrk. wrk's license follows:
"""
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
"""
- tools/cpplint.py is copyright Google Inc. and released under a
BSD license.

382
Makefile
View File

@@ -1,368 +1,129 @@
-include config.mk
WAF=python tools/waf-light
BUILDTYPE ?= Release
PYTHON ?= python
NINJA ?= ninja
DESTDIR ?=
SIGN ?=
web_root = node@nodejs.org:~/web/nodejs.org/
NODE ?= ./node
all: program
# Default to verbose builds.
# To do quiet/pretty builds, run `make V=` to set V to an empty string,
# or set the V environment variable to an empty string.
V ?= 1
all-progress:
@$(WAF) -p build
# BUILDTYPE=Debug builds both release and debug builds. If you want to compile
# just the debug build, run `make -C out BUILDTYPE=Debug` instead.
ifeq ($(BUILDTYPE),Release)
all: out/Makefile node
else
all: out/Makefile node node_g
endif
program:
@$(WAF) --product-type=program build
# The .PHONY is needed to ensure that we recursively use the out/Makefile
# to check for changes.
.PHONY: node node_g
staticlib:
@$(WAF) --product-type=cstaticlib build
ifeq ($(USE_NINJA),1)
node: config.gypi
$(NINJA) -C out/Release/
ln -fs out/Release/node node
dynamiclib:
@$(WAF) --product-type=cshlib build
node_g: config.gypi
$(NINJA) -C out/Debug/
ln -fs out/Debug/node $@
else
node: config.gypi out/Makefile
$(MAKE) -C out BUILDTYPE=Release V=$(V)
ln -fs out/Release/node node
node_g: config.gypi out/Makefile
$(MAKE) -C out BUILDTYPE=Debug V=$(V)
ln -fs out/Debug/node $@
endif
out/Makefile: common.gypi deps/uv/uv.gyp deps/http_parser/http_parser.gyp deps/zlib/zlib.gyp deps/v8/build/common.gypi deps/v8/tools/gyp/v8.gyp node.gyp config.gypi
ifeq ($(USE_NINJA),1)
touch out/Makefile
$(PYTHON) tools/gyp_node.py -f ninja
else
$(PYTHON) tools/gyp_node.py -f make
endif
config.gypi: configure
$(PYTHON) ./configure
install: all
$(PYTHON) tools/install.py $@ $(DESTDIR)
install:
@$(WAF) install
uninstall:
$(PYTHON) tools/install.py $@ $(DESTDIR)
clean:
-rm -rf out/Makefile node node_g out/$(BUILDTYPE)/node blog.html email.md
-find out/ -name '*.o' -o -name '*.a' | xargs rm -rf
-rm -rf node_modules
distclean:
-rm -rf out
-rm -f config.gypi
-rm -f config.mk
-rm -rf node node_g blog.html email.md
-rm -rf node_modules
@$(WAF) uninstall
test: all
$(PYTHON) tools/test.py --mode=release simple message
$(MAKE) jslint
test-http1: all
$(PYTHON) tools/test.py --mode=release --use-http1 simple message
python tools/test.py --mode=release simple message
test-valgrind: all
$(PYTHON) tools/test.py --mode=release --valgrind simple message
python tools/test.py --mode=release --valgrind simple message
test/gc/node_modules/weak/build/Release/weakref.node:
@if [ ! -f node ]; then make all; fi
./node deps/npm/node_modules/node-gyp/bin/node-gyp rebuild \
--directory="$(shell pwd)/test/gc/node_modules/weak" \
--nodedir="$(shell pwd)"
test-gc: all test/gc/node_modules/weak/build/Release/weakref.node
$(PYTHON) tools/test.py --mode=release gc
test-all: all test/gc/node_modules/weak/build/Release/weakref.node
$(PYTHON) tools/test.py --mode=debug,release
make test-npm
test-all-http1: all
$(PYTHON) tools/test.py --mode=debug,release --use-http1
test-all: all
python tools/test.py --mode=debug,release
test-all-valgrind: all
$(PYTHON) tools/test.py --mode=debug,release --valgrind
python tools/test.py --mode=debug,release --valgrind
test-release: all
$(PYTHON) tools/test.py --mode=release
python tools/test.py --mode=release
test-debug: all
$(PYTHON) tools/test.py --mode=debug
python tools/test.py --mode=debug
test-message: all
$(PYTHON) tools/test.py message
python tools/test.py message
test-simple: all
$(PYTHON) tools/test.py simple
python tools/test.py simple
test-pummel: all
$(PYTHON) tools/test.py pummel
python tools/test.py pummel
test-internet: all
$(PYTHON) tools/test.py internet
python tools/test.py internet
test-npm: node
./node deps/npm/test/run.js
test-npm-publish: node
npm_package_config_publishtest=true ./node deps/npm/test/run.js
test-timers:
$(MAKE) --directory=tools faketime
$(PYTHON) tools/test.py --mode=release timers
test-timers-clean:
$(MAKE) --directory=tools clean
build/default/node: all
apidoc_sources = $(wildcard doc/api/*.markdown)
apidocs = $(addprefix out/,$(apidoc_sources:.markdown=.html)) \
$(addprefix out/,$(apidoc_sources:.markdown=.json))
apidocs = $(addprefix build/,$(apidoc_sources:.markdown=.html))
apidoc_dirs = out/doc out/doc/api/ out/doc/api/assets
apidoc_dirs = build/doc build/doc/api/ build/doc/api/assets
apiassets = $(subst api_assets,api/assets,$(addprefix out/,$(wildcard doc/api_assets/*)))
apiassets = $(subst api_assets,api/assets,$(addprefix build/,$(wildcard doc/api_assets/*)))
website_files = \
out/doc/sh_main.js \
out/doc/sh_javascript.min.js
build/doc/index.html \
build/doc/v0.4_announcement.html \
build/doc/cla.html \
build/doc/sh_main.js \
build/doc/sh_javascript.min.js \
build/doc/sh_vim-dark.css \
build/doc/logo.png \
build/doc/sponsored.png \
build/doc/favicon.ico \
build/doc/pipe.css
doc: $(apidoc_dirs) $(website_files) $(apiassets) $(apidocs) tools/doc/ out/doc/changelog.html node
doc-branch: NODE_DOC_VERSION = v$(shell $(PYTHON) tools/getnodeversion.py | cut -f1,2 -d.)
doc-branch: doc
doc: build/default/node $(apidoc_dirs) $(website_files) $(apiassets) $(apidocs)
$(apidoc_dirs):
mkdir -p $@
out/doc/api/assets/%: doc/api_assets/% out/doc/api/assets/
build/doc/api/assets/%: doc/api_assets/% build/doc/api/assets/
cp $< $@
out/doc/changelog.html: ChangeLog doc/changelog-head.html doc/changelog-foot.html tools/build-changelog.sh node
bash tools/build-changelog.sh
build/doc/%: doc/%
cp $< $@
out/doc/%: doc/%
cp -r $< $@
build/doc/api/%.html: doc/api/%.markdown build/default/node $(apidoc_dirs) $(apiassets) tools/doctool/doctool.js
build/default/node tools/doctool/doctool.js doc/template.html $< > $@
out/doc/api/%.json: doc/api/%.markdown node
NODE_DOC_VERSION=$(NODE_DOC_VERSION) out/Release/node tools/doc/generate.js --format=json $< > $@
out/doc/api/%.html: doc/api/%.markdown node
NODE_DOC_VERSION=$(NODE_DOC_VERSION) out/Release/node tools/doc/generate.js --format=html --template=doc/template.html $< > $@
email.md: ChangeLog tools/email-footer.md
bash tools/changelog-head.sh | sed 's|^\* #|* \\#|g' > $@
cat tools/email-footer.md | sed -e 's|__VERSION__|'$(VERSION)'|g' >> $@
blog.html: email.md
cat $< | ./node tools/doc/node_modules/.bin/marked > $@
build/doc/%:
website-upload: doc
rsync -r out/doc/ node@nodejs.org:~/web/nodejs.org/
ssh node@nodejs.org '\
rm -f ~/web/nodejs.org/dist/latest &&\
ln -s $(VERSION) ~/web/nodejs.org/dist/latest &&\
rm -f ~/web/nodejs.org/docs/latest &&\
ln -s $(VERSION) ~/web/nodejs.org/docs/latest &&\
rm -f ~/web/nodejs.org/dist/node-latest.tar.gz &&\
ln -s $(VERSION)/node-$(VERSION).tar.gz ~/web/nodejs.org/dist/node-latest.tar.gz'
scp -r build/doc/* $(web_root)
doc-branch-upload: NODE_DOC_VERSION = v$(shell $(PYTHON) tools/getnodeversion.py | cut -f1,2 -d.)
doc-branch-upload: doc-branch
echo $(NODE_DOC_VERSION)
rsync -r out/doc/api/ node@nodejs.org:~/web/nodejs.org/$(NODE_DOC_VERSION)
docopen: out/doc/api/all.html
-google-chrome out/doc/api/all.html
docopen: build/doc/api/all.html
-google-chrome build/doc/api/all.html
docclean:
-rm -rf out/doc
-rm -rf build/doc
RAWVER=$(shell $(PYTHON) tools/getnodeversion.py)
VERSION=v$(RAWVER)
NODE_DOC_VERSION=$(VERSION)
RELEASE=$(shell $(PYTHON) tools/getnodeisrelease.py)
PLATFORM=$(shell uname | tr '[:upper:]' '[:lower:]')
ifeq ($(findstring x86_64,$(shell uname -m)),x86_64)
DESTCPU ?= x64
else
DESTCPU ?= ia32
endif
ifeq ($(DESTCPU),x64)
ARCH=x64
else
ifeq ($(DESTCPU),arm)
ARCH=arm
else
ARCH=x86
endif
endif
clean:
$(WAF) clean
-find tools -name "*.pyc" | xargs rm -f
distclean: docclean
-find tools -name "*.pyc" | xargs rm -f
-rm -rf build/ node node_g
check:
@tools/waf-light check
VERSION=$(shell git describe)
TARNAME=node-$(VERSION)
ifdef NIGHTLY
TAG = nightly-$(NIGHTLY)
TARNAME=node-$(VERSION)-$(TAG)
endif
TARBALL=$(TARNAME).tar.gz
BINARYNAME=$(TARNAME)-$(PLATFORM)-$(ARCH)
BINARYTAR=$(BINARYNAME).tar.gz
PKG=out/$(TARNAME).pkg
PACKAGEMAKER ?= /Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker
PKGSRC=nodejs-$(DESTCPU)-$(RAWVER).tgz
ifdef NIGHTLY
PKGSRC=nodejs-$(DESTCPU)-$(RAWVER)-$(TAG).tgz
endif
dist: doc $(TARBALL) $(PKG)
PKGDIR=out/dist-osx
release-only:
@if [ "$(shell git status --porcelain | egrep -v '^\?\? ')" = "" ]; then \
exit 0 ; \
else \
echo "" >&2 ; \
echo "The git repository is not clean." >&2 ; \
echo "Please commit changes before building release tarball." >&2 ; \
echo "" >&2 ; \
git status --porcelain | egrep -v '^\?\?' >&2 ; \
echo "" >&2 ; \
exit 1 ; \
fi
@if [ "$(NIGHTLY)" != "" -o "$(RELEASE)" = "1" ]; then \
exit 0; \
else \
echo "" >&2 ; \
echo "#NODE_VERSION_IS_RELEASE is set to $(RELEASE)." >&2 ; \
echo "Did you remember to update src/node_version.cc?" >&2 ; \
echo "" >&2 ; \
exit 1 ; \
fi
pkg: $(PKG)
$(PKG): release-only
rm -rf $(PKGDIR)
rm -rf out/deps out/Release
$(PYTHON) ./configure --without-snapshot --dest-cpu=ia32 --tag=$(TAG)
$(MAKE) install V=$(V) DESTDIR=$(PKGDIR)/32
rm -rf out/deps out/Release
$(PYTHON) ./configure --without-snapshot --dest-cpu=x64 --tag=$(TAG)
$(MAKE) install V=$(V) DESTDIR=$(PKGDIR)
SIGN="$(APP_SIGN)" PKGDIR="$(PKGDIR)" bash tools/osx-codesign.sh
lipo $(PKGDIR)/32/usr/local/bin/node \
$(PKGDIR)/usr/local/bin/node \
-output $(PKGDIR)/usr/local/bin/node-universal \
-create
mv $(PKGDIR)/usr/local/bin/node-universal $(PKGDIR)/usr/local/bin/node
rm -rf $(PKGDIR)/32
$(PACKAGEMAKER) \
--id "org.nodejs.Node" \
--doc tools/osx-pkg.pmdoc \
--out $(PKG)
SIGN="$(INT_SIGN)" PKG="$(PKG)" bash tools/osx-productsign.sh
$(TARBALL): release-only node doc
#dist: doc/node.1 doc/api
dist: doc
git archive --format=tar --prefix=$(TARNAME)/ HEAD | tar xf -
mkdir -p $(TARNAME)/doc/api
mkdir -p $(TARNAME)/doc
cp doc/node.1 $(TARNAME)/doc/node.1
cp -r out/doc/api/* $(TARNAME)/doc/api/
cp -r build/doc/api $(TARNAME)/doc/api
rm -rf $(TARNAME)/deps/v8/test # too big
rm -rf $(TARNAME)/doc/images # too big
find $(TARNAME)/ -type l | xargs rm # annoying on windows
tar -cf $(TARNAME).tar $(TARNAME)
rm -rf $(TARNAME)
gzip -f -9 $(TARNAME).tar
tar: $(TARBALL)
$(BINARYTAR): release-only
rm -rf $(BINARYNAME)
rm -rf out/deps out/Release
$(PYTHON) ./configure --prefix=/ --without-snapshot --dest-cpu=$(DESTCPU) --tag=$(TAG) $(CONFIG_FLAGS)
$(MAKE) install DESTDIR=$(BINARYNAME) V=$(V) PORTABLE=1
cp README.md $(BINARYNAME)
cp LICENSE $(BINARYNAME)
cp ChangeLog $(BINARYNAME)
tar -cf $(BINARYNAME).tar $(BINARYNAME)
rm -rf $(BINARYNAME)
gzip -f -9 $(BINARYNAME).tar
binary: $(BINARYTAR)
$(PKGSRC): release-only
rm -rf dist out
$(PYTHON) configure --prefix=/ --without-snapshot \
--dest-cpu=$(DESTCPU) --tag=$(TAG) $(CONFIG_FLAGS)
$(MAKE) install DESTDIR=dist
(cd dist; find * -type f | sort) > packlist
pkg_info -X pkg_install | \
egrep '^(MACHINE_ARCH|OPSYS|OS_VERSION|PKGTOOLS_VERSION)' > build-info
pkg_create -B build-info -c tools/pkgsrc/comment -d tools/pkgsrc/description \
-f packlist -I /opt/local -p dist -U $(PKGSRC)
pkgsrc: $(PKGSRC)
dist-upload: $(TARBALL) $(PKG)
ssh node@nodejs.org mkdir -p web/nodejs.org/dist/$(VERSION)
scp $(TARBALL) node@nodejs.org:~/web/nodejs.org/dist/$(VERSION)/$(TARBALL)
scp $(PKG) node@nodejs.org:~/web/nodejs.org/dist/$(VERSION)/$(TARNAME).pkg
wrkclean:
$(MAKE) -C tools/wrk/ clean
rm tools/wrk/wrk
wrk: tools/wrk/wrk
tools/wrk/wrk:
$(MAKE) -C tools/wrk/
bench-net: all
@$(NODE) benchmark/common.js net
bench-crypto: all
@$(NODE) benchmark/common.js crypto
bench-tls: all
@$(NODE) benchmark/common.js tls
bench-http: wrk all
@$(NODE) benchmark/common.js http
bench-fs: all
@$(NODE) benchmark/common.js fs
bench-misc: all
@$(MAKE) -C benchmark/misc/function_call/
@$(NODE) benchmark/common.js misc
bench-array: all
@$(NODE) benchmark/common.js arrays
bench-buffer: all
@$(NODE) benchmark/common.js buffers
bench-all: bench bench-misc bench-array bench-buffer
bench: bench-net bench-http bench-fs bench-tls
bench-http-simple:
bench:
benchmark/http_simple_bench.sh
bench-idle:
@@ -370,15 +131,12 @@ bench-idle:
sleep 1
./node benchmark/idle_clients.js &
jslintfix:
PYTHONPATH=tools/closure_linter/ $(PYTHON) tools/closure_linter/closure_linter/fixjsstyle.py --strict --nojsdoc -r lib/ -r src/ --exclude_files lib/punycode.js
jslint:
PYTHONPATH=tools/closure_linter/ $(PYTHON) tools/closure_linter/closure_linter/gjslint.py --unix_mode --strict --nojsdoc -r lib/ -r src/ --exclude_files lib/punycode.js
PYTHONPATH=tools/closure_linter/ python tools/closure_linter/closure_linter/gjslint.py --unix_mode --strict --nojsdoc -r lib/ -r src/ -r test/
cpplint:
@$(PYTHON) tools/cpplint.py $(wildcard src/*.cc src/*.h src/*.c)
@python tools/cpplint.py $(wildcard src/*.cc src/*.h src/*.c)
lint: jslint cpplint
.PHONY: lint cpplint jslint bench clean docopen docclean doc dist distclean check uninstall install install-includes install-bin all staticlib dynamiclib test test-all website-upload pkg blog blogclean tar binary release-only bench-http-simple bench-idle bench-all bench bench-misc bench-array bench-buffer bench-net bench-http bench-fs bench-tls
.PHONY: lint cpplint jslint bench clean docopen docclean doc dist distclean check uninstall install all program staticlib dynamiclib test test-all website-upload

40
Makefile.cmake Normal file
View File

@@ -0,0 +1,40 @@
BUILD?=build
VERBOSE?=0
PARALLEL_JOBS?=1
CMAKE?=cmake
TOOLCHAIN_FILE=#./cmake/codesourcery-arm-toolchain.cmake
all: package
$(BUILD)/Makefile:
mkdir $(BUILD) || exit 0
cd $(BUILD) && $(CMAKE) -DCMAKE_VERBOSE_MAKEFILE=$(VERBOSE) -DCMAKE_TOOLCHAIN_FILE=$(TOOLCHAIN_FILE) ..
build: $(BUILD)/Makefile
cd $(BUILD) && make -j $(PARALLEL_JOBS)
install: build
cd $(BUILD) && sudo make install
clean:
rm -rf $(BUILD)
doc: $(BUILD)/Makefile
cd $(BUILD) && make doc
package: $(BUILD)/Makefile
cd $(BUILD) && make package
test: $(BUILD)/Makefile
cd $(BUILD) && make test
cdash: $(BUILD)/Makefile
cd $(BUILD) && make Experimental
cdash-cov: $(BUILD)/Makefile
cd $(BUILD) && $(CMAKE) -DUSE_GCOV=True .. && make Experimental
cdash-mem: $(BUILD)/Makefile
cd $(BUILD) && make NightlyMemoryCheck
.PHONY: build install clean doc package test cdash cdash-cov cdash-mem

77
README.cmake Normal file
View File

@@ -0,0 +1,77 @@
Instructions for building with cmake
Make sure you have cmake:
Ubuntu/Debian: sudo apt-get install cmake
Mac: http://www.cmake.org/files/v2.8/cmake-2.8.3-Darwin-universal.dmg
Other platforms: http://www.cmake.org/cmake/resources/software.html
To build:
make -f Makefile.cmake
make -f Makefile.cmake install
To run the tests:
make -f Makefile.cmake test
To build the documentation:
make -f Makefile.cmake doc
To read the documentation:
man doc/node.1
To build distro packages (tgz, deb, rpm, PackageMaker):
make -f Makefile.cmake package
To submit test results (see http://my.cdash.org/index.php?project=node):
make -f Makefile.cmake cdash
To submit coverage test results:
make -f Makefile.cmake cdash-cov
To submit valgrind test results:
make -f Makefile.cmake cdash-mem
Cross-compiling:
An example toolchain file for the CodeSourcery ARM toolchain is included in
the cmake directory: codesourcery-arm-toolchain.cmake.
Install the CodeSourcery toolchain, set the path to the toolchain in
cmake/codesourcery-arm-toolchain.cmake, and uncomment the TOOLCHAIN_FILE
variable in Makefile.cmake to use it.
If you are using cmake directly, just add the flag
"-DCMAKE_TOOLCHAIN_FILE=/path/to/toolchain-file" when
running cmake.
Using cmake directly:
cd ~/your-node-source-dir
mkdir name-of-build-dir (can be anything)
cd name-of-build-dir
cmake ..
At this point you have generated a set of Makefiles and can use the standard
make commands (make, make install, etc.). The Makefile.cmake file is just a
wrapper around these commands; take a look at it for more details.
Other build targets:
make Experimental
make Nightly
make NightlyMemoryCheck
make Continuous
Additional options:
In the CMakeLists.txt, you'll see things like
option(SHARED_V8, ...). If you want to enable any of those options you can
pass "-DOPTION=True" when running cmake (e.g., cmake -DSHARED_V8=True).
See http://nodejs.org/ for more information. For help and discussion
subscribe to the mailing list by visiting
http://groups.google.com/group/nodejs or by sending an email to
nodejs+subscribe@googlegroups.com.

View File

@@ -1,74 +1,33 @@
Evented I/O for V8 javascript. [![Build Status](https://secure.travis-ci.org/joyent/node.png)](http://travis-ci.org/joyent/node)
Evented I/O for V8 javascript.
===
### To build:
Prerequisites (Unix only):
* GCC 4.2 or newer
* Python 2.6 or 2.7
* GNU Make 3.81 or newer
* libexecinfo (FreeBSD and OpenBSD only)
Unix/Macintosh:
To build:
./configure
make
make install
If your python binary is in a non-standard location or has a
non-standard name, run the following instead:
export PYTHON=/path/to/python
$PYTHON ./configure
make
make install
Windows:
vcbuild.bat
You can download pre-built binaries for various operating systems from
[http://nodejs.org/download/](http://nodejs.org/download/). The Windows
and OS X installers will prompt you for the location to install to.
The tarballs are self-contained; you can extract them to a local directory
with:
tar xzf /path/to/node-<version>-<platform>-<arch>.tar.gz
Or system-wide with:
cd /usr/local && tar --strip-components 1 -xzf \
/path/to/node-<version>-<platform>-<arch>.tar.gz
### To run the tests:
Unix/Macintosh:
To run the tests:
make test
Windows:
vcbuild.bat test
### To build the documentation:
To build the documentation:
make doc
### To read the documentation:
To read the documentation:
man doc/node.1
Resources for Newcomers
---
- [The Wiki](https://github.com/joyent/node/wiki)
- [The Wiki](http://github.com/ry/node/wiki)
- [nodejs.org](http://nodejs.org/)
- [how to install node.js and npm (node package manager)](http://www.joyent.com/blog/installing-node-and-npm/)
- [list of modules](https://github.com/joyent/node/wiki/modules)
- [searching the npm registry](http://npmjs.org/)
- [list of companies and projects using node](https://github.com/joyent/node/wiki/Projects,-Applications,-and-Companies-Using-Node)
- [how to install node.js and npm (node package manager)](http://joyeur.com/2010/12/10/installing-node-and-npm/)
- [list of modules](http://github.com/ry/node/wiki/modules)
- [list of companies and projects using node](http://github.com/ry/node/wiki)
- [node.js mailing list](http://groups.google.com/group/nodejs)
- irc chatroom, [#node.js on freenode.net](http://webchat.freenode.net?channels=node.js&uio=d4)
- [community](https://github.com/joyent/node/wiki/Community)
- [contributing](https://github.com/joyent/node/wiki/Contributing)
- [big list of all the helpful wiki pages](https://github.com/joyent/node/wiki/_pages)
- [community](https://github.com/ry/node/wiki/Community)
- [contributing](https://github.com/ry/node/wiki/Contributing)
- [big list of all the helpful wiki pages](https://github.com/ry/node/wiki/_pages)

33
TODO Normal file
View File

@@ -0,0 +1,33 @@
- fix tests for NODE_MODULE_CONTEXTS=1
- readline
- fix for two column glyphs. use Markus Kuhn's wcwidth.c
- fix for commands that extend beyond term width
- Erradicate all traces of 'binary' encoding. Only used, now, in OpenSSL
binding.
- EventSource branch merged
- Use C++ style casts everywhere.
- Ruby-like Process#detach (is that possible?)
- stderr isn't flushing on exit
- ReadStream should not use an offset in calls to fs.read
(so that it can pull in files larger than 2G)
- process object should be defined in src/node.js not in c++
- Test for EMFILE accept spin bug.
- Deprecate setEncoding() and instead add option to on('data').
Example:
stdin.on('data', { encoding: 'utf8' }, function (chunk) {
process.stdout.write('WRITE: ' + chunk);
});
Perhaps by assigning cb.opts.encoding and calling
EventEmitter.optHandlers.encoding() if it exists.
- DOCS
- anchor links next to each function, for easy linking.
EG <a href="#fs.stat">#</a>
- "node --raw-js script.js" should bipass all Node code and load a raw V8
interpreter
- Use http_parser_execute2() in node_http_parser.cc and make req.pause()
work correctly
https://github.com/ry/http-parser/blob/c95a5479596e95b7cdd88ca9d7b32fd3afb4379c/http_parser.h#L266

88
TODO.win32 Normal file
View File

@@ -0,0 +1,88 @@
- Implement setenv / unsetenv
- Implement other stuff missing in node.cc/process
Like getuid, getgid, setgid, kill etc.
- Better `net` support
* getaddrinfo
* setMulticastTTL, setMembership, setLoopback
* pipe, socketpair
* A named pipe should be provided when a unix socket is requested.
* SendMsg and RecvMsg should be supported with named pipes.
- New libev backend
The current libev backend supports sockets only. This complicates stuff like
child processes, stdio. Best would be if node_net switched from exposing
readyness notifications to using completion notifications, so on windows we
could use IOCP for sockets. Experts tell me that is really the fastest way
to work with sockets on windows.
- Child process issues
* Communication between parent and child is slow; it uses a socketpair
where a pipe would be much faster. Replace it by a pipe when there
is a libev backend that supports waiting for a pipe.
* When a child process spawns the pid is not available straightaway.
On linux the pid is available immediately because fork() doesn't
block; on windows a libeio thread is used to call CreateProcess.
So this can't really be fixed, but it could be worked around by adding a
'spawn' or 'pid' event.
* passing socket custom_fds is not supported
* child_process.exec() only works on systems with msys installed.
It's because it relies on the 'sh' shell. The default windows shell
is 'cmd' and it works a little differently. Maybe add an option to
specify the shell to exec()?
- Make colorful util.inspect work on windows.
- Stdio: support passing sockets between master/child process
Normal windows applications wouldn't like this, but it can be useful for
communication between node processes. This requires
stdio.isStdinBlocking/isStdoutBlocking to be smarter.
- Skip/fix tests that can never pass on windows
- Find a solution for fs.symlink / fs.lstat / fs.chown
Windows has different symlink types: file symlinks (vista+),
directory symlinks (vista+), junction points (xp+)
- Handle _open_osfhandle failures
E.g. currently we're using the construct _open_osfhandle(socket/open/accept(...)).
Now socket() can fail by itself and _open_osfhandle can fail by itself too.
If socket() fails it returns -1 so _open_osfhandle fails as well, but and we'll always return/throw EBADF.
If _open_osfhandle fails but socket doesn't, a stray handle is left open. It should be fixed.
- Think about `make install`
- Extensions
Should be DLLs on windows.
- Link pthreads-w32 statically by default
- Link Mingw libraries statically by default
Like libstdc++.dll, more maybe.
Microsoft libs are always there, no static linkage required (e.g. msvcrt, winsock2).
- Make (open?)SSL work
- Support using shared libs (libeio, v8, c-ares)
Need to link with with a stub library. Libraries should use `dllexport`,
headers must have `dllimport`.
- V8: push MINGW32 build fixes upstream
- Work around missing pread/pwrite more elegantly
Currently it's exported from libeio, while it wasn't intended to be exported.
The libeio workaround implementation sucks, it uses a global mutex.
It should be possible to implement pread and pwrite using winapi's ReadFile/Writefile
directly, passing an OVERLAPPED structure while not associating with an completion port.
- Work around missing inet_pton/inet_ntop more elegantly
Currently it's exported from from c-ares, while it wasn't intended to be exported.
It prevents linking c-ares dynamically.
- See what libev/libeio changes can be pushed upstream
- 64-bit build
Should be possible with MinGW-w64, it's pretty good.
- ... much more probably

View File

@@ -1,20 +0,0 @@
var common = require('../common.js');
var bench = common.createBenchmark(main, {
type: 'Array Buffer Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split(' '),
n: [25]
});
function main(conf) {
var type = conf.type;
var clazz = global[type];
var n = +conf.n;
bench.start();
var arr = new clazz(n * 1e6);
for (var i = 0; i < 10; ++i) {
for (var j = 0, k = arr.length; j < k; ++j) {
arr[j] = (j ^ k) & 127;
}
}
bench.end(n);
}

View File

@@ -1,20 +0,0 @@
var common = require('../common.js');
var bench = common.createBenchmark(main, {
type: 'Array Buffer Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split(' '),
n: [25]
});
function main(conf) {
var type = conf.type;
var clazz = global[type];
var n = +conf.n;
bench.start();
var arr = new clazz(n * 1e6);
for (var i = 0; i < 10; ++i) {
for (var j = 0, k = arr.length; j < k; ++j) {
arr[j] = 0.0;
}
}
bench.end(n);
}

View File

@@ -1,20 +0,0 @@
var common = require('../common.js');
var bench = common.createBenchmark(main, {
type: 'Array Buffer Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split(' '),
n: [25]
});
function main(conf) {
var type = conf.type;
var clazz = global[type];
var n = +conf.n;
bench.start();
var arr = new clazz(n * 1e6);
for (var i = 0; i < 10; ++i) {
for (var j = 0, k = arr.length; j < k; ++j) {
arr[j] = 0;
}
}
bench.end(n);
}

View File

@@ -0,0 +1,6 @@
SlowBuffer = require('buffer').SlowBuffer;
for (var i = 0; i < 1e6; i++) {
b = new SlowBuffer(10);
b[1] = 2
}

View File

@@ -1,36 +0,0 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('../common.js');
var bench = common.createBenchmark(main, {});
function main(conf) {
var N = 64 * 1024 * 1024;
var b = Buffer(N);
var s = '';
for (var i = 0; i < 256; ++i) s += String.fromCharCode(i);
bench.start();
for (var i = 0; i < N; i += 256) b.write(s, i, 256, 'ascii');
for (var i = 0; i < 32; ++i) b.toString('base64');
bench.end(64);
}

View File

@@ -1,19 +0,0 @@
SlowBuffer = require('buffer').SlowBuffer;
var common = require('../common.js');
var bench = common.createBenchmark(main, {
type: ['fast', 'slow'],
len: [10, 1024],
n: [1024]
});
function main(conf) {
var len = +conf.len;
var n = +conf.n;
var clazz = conf.type === 'fast' ? Buffer : SlowBuffer;
bench.start();
for (var i = 0; i < n * 1024; i++) {
b = new clazz(len);
}
bench.end(n);
}

View File

@@ -1,31 +0,0 @@
var common = require('../common.js');
var bench = common.createBenchmark(main, {
noAssert: [false, true],
buffer: ['fast', 'slow'],
type: ['UInt8', 'UInt16LE', 'UInt16BE',
'UInt32LE', 'UInt32BE',
'Int8', 'Int16LE', 'Int16BE',
'Int32LE', 'Int32BE',
'FloatLE', 'FloatBE',
'DoubleLE', 'DoubleBE'],
millions: [1]
});
function main(conf) {
var noAssert = conf.noAssert === 'true';
var len = +conf.millions * 1e6;
var clazz = conf.buf === 'fast' ? Buffer : require('buffer').SlowBuffer;
var buff = new clazz(8);
var fn = 'read' + conf.type;
buff.writeDoubleLE(0, 0, noAssert);
var testFunction = new Function('buff', [
"for (var i = 0; i !== " + len + "; i++) {",
" buff." + fn + "(0, " + JSON.stringify(noAssert) + ");",
"}"
].join("\n"));
bench.start();
testFunction(buff);
bench.end(len / 1e6);
}

View File

@@ -1,69 +0,0 @@
var common = require('../common.js');
var bench = common.createBenchmark(main, {
noAssert: [false, true],
buffer: ['fast', 'slow'],
type: ['UInt8', 'UInt16LE', 'UInt16BE',
'UInt32LE', 'UInt32BE',
'Int8', 'Int16LE', 'Int16BE',
'Int32LE', 'Int32BE',
'FloatLE', 'FloatBE',
'DoubleLE', 'DoubleBE'],
millions: [1]
});
const INT8 = 0x7f;
const INT16 = 0x7fff;
const INT32 = 0x7fffffff;
const UINT8 = (INT8 * 2) + 1;
const UINT16 = (INT16 * 2) + 1;
const UINT32 = INT32;
var mod = {
writeInt8: INT8,
writeInt16BE: INT16,
writeInt16LE: INT16,
writeInt32BE: INT32,
writeInt32LE: INT32,
writeUInt8: UINT8,
writeUInt16BE: UINT16,
writeUInt16LE: UINT16,
writeUInt32BE: UINT32,
writeUInt32LE: UINT32
};
function main(conf) {
var noAssert = conf.noAssert === 'true';
var len = +conf.millions * 1e6;
var clazz = conf.buf === 'fast' ? Buffer : require('buffer').SlowBuffer;
var buff = new clazz(8);
var fn = 'write' + conf.type;
if (fn.match(/Int/))
benchInt(buff, fn, len, noAssert);
else
benchFloat(buff, fn, len, noAssert);
}
function benchInt(buff, fn, len, noAssert) {
var m = mod[fn];
var testFunction = new Function('buff', [
"for (var i = 0; i !== " + len + "; i++) {",
" buff." + fn + "(i & " + m + ", 0, " + JSON.stringify(noAssert) + ");",
"}"
].join("\n"));
bench.start();
testFunction(buff);
bench.end(len / 1e6);
}
function benchFloat(buff, fn, len, noAssert) {
var testFunction = new Function('buff', [
"for (var i = 0; i !== " + len + "; i++) {",
" buff." + fn + "(i, 0, " + JSON.stringify(noAssert) + ");",
"}"
].join("\n"));
bench.start();
testFunction(buff);
bench.end(len / 1e6);
}

View File

@@ -1,57 +0,0 @@
var common = require('../common.js');
var bench = common.createBenchmark(main, {
type: ['Uint8', 'Uint16LE', 'Uint16BE',
'Uint32LE', 'Uint32BE',
'Int8', 'Int16LE', 'Int16BE',
'Int32LE', 'Int32BE',
'Float32LE', 'Float32BE',
'Float64LE', 'Float64BE'],
millions: [1]
});
const INT8 = 0x7f;
const INT16 = 0x7fff;
const INT32 = 0x7fffffff;
const UINT8 = INT8 * 2;
const UINT16 = INT16 * 2;
const UINT32 = INT32 * 2;
var mod = {
setInt8: INT8,
setInt16: INT16,
setInt32: INT32,
setUint8: UINT8,
setUint16: UINT16,
setUint32: UINT32
};
function main(conf) {
var len = +conf.millions * 1e6;
var ab = new ArrayBuffer(8);
var dv = new DataView(ab, 0, 8);
var le = /LE$/.test(conf.type);
var fn = 'set' + conf.type.replace(/[LB]E$/, '');
if (/int/i.test(fn))
benchInt(dv, fn, len, le);
else
benchFloat(dv, fn, len, le);
}
function benchInt(dv, fn, len, le) {
var m = mod[fn];
bench.start();
for (var i = 0; i < len; i++) {
dv[fn](0, i % m, le);
}
bench.end(len / 1e6);
}
function benchFloat(dv, fn, len, le) {
bench.start();
for (var i = 0; i < len; i++) {
dv[fn](0, i * 0.1, le);
}
bench.end(len / 1e6);
}

View File

@@ -1,199 +0,0 @@
var assert = require('assert');
var path = require('path');
var silent = +process.env.NODE_BENCH_SILENT;
exports.PORT = process.env.PORT || 12346;
// If this is the main module, then run the benchmarks
if (module === require.main) {
var type = process.argv[2];
if (!type) {
console.error('usage:\n ./node benchmark/common.js <type>');
process.exit(1);
}
var fs = require('fs');
var dir = path.join(__dirname, type);
var tests = fs.readdirSync(dir);
var spawn = require('child_process').spawn;
runBenchmarks();
}
function runBenchmarks() {
var test = tests.shift();
if (!test)
return;
if (test.match(/^[\._]/))
return process.nextTick(runBenchmarks);
console.error(type + '/' + test);
test = path.resolve(dir, test);
var a = (process.execArgv || []).concat(test);
var child = spawn(process.execPath, a, { stdio: 'inherit' });
child.on('close', function(code) {
if (code)
process.exit(code);
else {
console.log('');
runBenchmarks();
}
});
}
exports.createBenchmark = function(fn, options) {
return new Benchmark(fn, options);
};
function Benchmark(fn, options) {
this.fn = fn;
this.options = options;
this.config = parseOpts(options);
this._name = require.main.filename.split(/benchmark[\/\\]/).pop();
this._start = [0,0];
this._started = false;
var self = this;
process.nextTick(function() {
self._run();
});
}
// benchmark an http server.
Benchmark.prototype.http = function(p, args, cb) {
var self = this;
var wrk = path.resolve(__dirname, '..', 'tools', 'wrk', 'wrk');
var regexp = /Requests\/sec:[ \t]+([0-9\.]+)/;
var spawn = require('child_process').spawn;
var url = 'http://127.0.0.1:' + exports.PORT + p;
args = args.concat(url);
var out = '';
var child = spawn(wrk, args);
child.stdout.setEncoding('utf8');
child.stdout.on('data', function(chunk) {
out += chunk;
});
child.on('close', function(code) {
if (cb)
cb(code);
if (code) {
console.error('wrk failed with ' + code);
process.exit(code)
}
var m = out.match(regexp);
var qps = m && +m[1];
if (!qps) {
console.error('%j', out);
console.error('wrk produced strange output');
process.exit(1);
}
self.report(+qps);
});
};
Benchmark.prototype._run = function() {
if (this.config)
return this.fn(this.config);
// one more more options weren't set.
// run with all combinations
var main = require.main.filename;
var settings = [];
var queueLen = 1;
var options = this.options;
var queue = Object.keys(options).reduce(function(set, key) {
var vals = options[key];
assert(Array.isArray(vals));
// match each item in the set with each item in the list
var newSet = new Array(set.length * vals.length);
var j = 0;
set.forEach(function(s) {
vals.forEach(function(val) {
newSet[j++] = s.concat(key + '=' + val);
});
});
return newSet;
}, [[main]]);
var spawn = require('child_process').spawn;
var node = process.execPath;
var i = 0;
function run() {
var argv = queue[i++];
if (!argv)
return;
var child = spawn(node, argv, { stdio: 'inherit' });
child.on('close', function(code, signal) {
if (code)
console.error('child process exited with code ' + code);
else
run();
});
}
run();
};
function parseOpts(options) {
// verify that there's an option provided for each of the options
// if they're not *all* specified, then we return null.
var keys = Object.keys(options);
var num = keys.length;
var conf = {};
for (var i = 2; i < process.argv.length; i++) {
var m = process.argv[i].match(/^(.+)=(.+)$/);
if (!m || !m[1] || !m[2] || !options[m[1]])
return null;
else {
conf[m[1]] = isFinite(m[2]) ? +m[2] : m[2]
num--;
}
}
// still go ahead and set whatever WAS set, if it was.
if (num !== 0) {
Object.keys(conf).forEach(function(k) {
options[k] = [conf[k]];
});
}
return num === 0 ? conf : null;
};
Benchmark.prototype.start = function() {
if (this._started)
throw new Error('Called start more than once in a single benchmark');
this._started = true;
this._start = process.hrtime();
};
Benchmark.prototype.end = function(operations) {
var elapsed = process.hrtime(this._start);
if (!this._started)
throw new Error('called end without start');
if (typeof operations !== 'number')
throw new Error('called end() without specifying operation count');
var time = elapsed[0] + elapsed[1]/1e9;
var rate = operations/time;
this.report(rate);
};
Benchmark.prototype.report = function(value) {
var heading = this.getHeading();
if (!silent)
console.log('%s: %s', heading, value.toPrecision(5));
process.exit(0);
};
Benchmark.prototype.getHeading = function() {
var conf = this.config;
return this._name + ' ' + Object.keys(conf).map(function(key) {
return key + '=' + conf[key];
}).join(' ');
}

View File

@@ -1,151 +0,0 @@
var usage = 'node benchmark/compare.js ' +
'<node-binary1> <node-binary2> ' +
'[--html] [--red|-r] [--green|-g]';
var show = 'both';
var nodes = [];
var html = false;
for (var i = 2; i < process.argv.length; i++) {
var arg = process.argv[i];
switch (arg) {
case '--red': case '-r':
show = show === 'green' ? 'both' : 'red';
break;
case '--green': case '-g':
show = show === 'red' ? 'both' : 'green';
break;
case '--html':
html = true;
break;
case '-h': case '-?': case '--help':
console.log(usage);
process.exit(0);
default:
nodes.push(arg);
break;
}
}
if (!html) {
var start = '';
var green = '\033[1;32m';
var red = '\033[1;31m';
var reset = '\033[m';
var end = '';
} else {
var start = '<pre style="background-color:#333;color:#eee">';
var green = '<span style="background-color:#0f0;color:#000">';
var red = '<span style="background-color:#f00;color:#fff">';
var reset = '</span>';
var end = '</pre>';
}
var runBench = process.env.NODE_BENCH || 'bench';
if (nodes.length !== 2)
return console.error('usage:\n %s', usage);
var spawn = require('child_process').spawn;
var results = {};
var toggle = 1;
var r = (+process.env.NODE_BENCH_RUNS || 1) * 2;
run();
function run() {
if (--r < 0)
return compare();
toggle = ++toggle % 2;
var node = nodes[toggle];
console.error('running %s', node);
var env = {};
for (var i in process.env)
env[i] = process.env[i];
env.NODE = node;
var out = '';
var child = spawn('make', [runBench], { env: env });
child.stdout.setEncoding('utf8');
child.stdout.on('data', function(c) {
out += c;
});
child.stderr.pipe(process.stderr);
child.on('close', function(code) {
if (code) {
console.error('%s exited with code=%d', node, code);
process.exit(code);
} else {
out.trim().split(/\r?\n/).forEach(function(line) {
line = line.trim();
if (!line)
return;
var s = line.split(':');
var num = +s.pop();
if (!num && num !== 0)
return;
line = s.join(':');
var res = results[line] = results[line] || {};
res[node] = res[node] || [];
res[node].push(num);
});
run();
}
});
}
function compare() {
// each result is an object with {"foo.js arg=bar":12345,...}
// compare each thing, and show which node did the best.
// node[0] is shown in green, node[1] shown in red.
var maxLen = -Infinity;
var util = require('util');
console.log(start);
Object.keys(results).map(function(bench) {
var res = results[bench];
var n0 = avg(res[nodes[0]]);
var n1 = avg(res[nodes[1]]);
var pct = ((n0 - n1) / n1 * 100).toFixed(2);
var g = n0 > n1 ? green : '';
var r = n0 > n1 ? '' : red;
var c = r || g;
if (show === 'green' && !g || show === 'red' && !r)
return;
var r0 = util.format('%s%s: %d%s', g, nodes[0], n0.toPrecision(5), g ? reset : '');
var r1 = util.format('%s%s: %d%s', r, nodes[1], n1.toPrecision(5), r ? reset : '');
var pct = c + pct + '%' + reset;
var l = util.format('%s: %s %s', bench, r0, r1);
maxLen = Math.max(l.length + pct.length, maxLen);
return [l, pct];
}).filter(function(l) {
return l;
}).forEach(function(line) {
var l = line[0];
var pct = line[1];
var dotLen = maxLen - l.length - pct.length + 2;
var dots = ' ' + new Array(Math.max(0, dotLen)).join('.') + ' ';
console.log(l + dots + pct);
});
console.log(end);
}
function avg(list) {
if (list.length >= 3) {
list = list.sort();
var q = Math.floor(list.length / 4) || 1;
list = list.slice(q, -q);
}
return list.reduce(function(a, b) {
return a + b;
}, 0) / list.length;
}

View File

@@ -1,101 +0,0 @@
var common = require('../common.js');
var bench = common.createBenchmark(main, {
writes: [500],
cipher: [ 'AES192', 'AES256' ],
type: ['asc', 'utf', 'buf'],
len: [2, 1024, 102400, 1024 * 1024],
api: ['legacy', 'stream']
});
function main(conf) {
var api = conf.api;
if (api === 'stream' && process.version.match(/^v0\.[0-8]\./)) {
console.error('Crypto streams not available until v0.10');
// use the legacy, just so that we can compare them.
api = 'legacy';
}
var crypto = require('crypto');
var assert = require('assert');
var alice = crypto.getDiffieHellman('modp5');
var bob = crypto.getDiffieHellman('modp5');
alice.generateKeys();
bob.generateKeys();
var pubEnc = /^v0\.[0-8]/.test(process.version) ? 'binary' : null;
var alice_secret = alice.computeSecret(bob.getPublicKey(), pubEnc, 'hex');
var bob_secret = bob.computeSecret(alice.getPublicKey(), pubEnc, 'hex');
// alice_secret and bob_secret should be the same
assert(alice_secret == bob_secret);
var alice_cipher = crypto.createCipher(conf.cipher, alice_secret);
var bob_cipher = crypto.createDecipher(conf.cipher, bob_secret);
var message;
var encoding;
switch (conf.type) {
case 'asc':
message = new Array(conf.len + 1).join('a');
encoding = 'ascii';
break;
case 'utf':
message = new Array(conf.len / 2 + 1).join('ü');
encoding = 'utf8';
break;
case 'buf':
message = new Buffer(conf.len);
message.fill('b');
break;
default:
throw new Error('unknown message type: ' + conf.type);
}
var fn = api === 'stream' ? streamWrite : legacyWrite;
// write data as fast as possible to alice, and have bob decrypt.
// use old API for comparison to v0.8
bench.start();
fn(alice_cipher, bob_cipher, message, encoding, conf.writes);
}
function streamWrite(alice, bob, message, encoding, writes) {
var written = 0;
bob.on('data', function(c) {
written += c.length;
});
bob.on('end', function() {
// Gbits
var bits = written * 8;
var gbits = bits / (1024 * 1024 * 1024);
bench.end(gbits);
});
alice.pipe(bob);
while (writes-- > 0)
alice.write(message, encoding);
alice.end();
}
function legacyWrite(alice, bob, message, encoding, writes) {
var written = 0;
for (var i = 0; i < writes; i++) {
var enc = alice.update(message, encoding);
var dec = bob.update(enc);
written += dec.length;
}
var enc = alice.final();
var dec = bob.update(enc);
written += dec.length;
dec = bob.final();
written += dec.length;
var bits = written * 8;
var gbits = written / (1024 * 1024 * 1024);
bench.end(gbits);
}

View File

@@ -1,86 +0,0 @@
// throughput benchmark
// creates a single hasher, then pushes a bunch of data through it
var common = require('../common.js');
var crypto = require('crypto');
var bench = common.createBenchmark(main, {
writes: [500],
algo: [ 'sha256', 'md5' ],
type: ['asc', 'utf', 'buf'],
out: ['hex', 'binary', 'buffer'],
len: [2, 1024, 102400, 1024 * 1024],
api: ['legacy', 'stream']
});
function main(conf) {
var api = conf.api;
if (api === 'stream' && process.version.match(/^v0\.[0-8]\./)) {
console.error('Crypto streams not available until v0.10');
// use the legacy, just so that we can compare them.
api = 'legacy';
}
var crypto = require('crypto');
var assert = require('assert');
var message;
var encoding;
switch (conf.type) {
case 'asc':
message = new Array(conf.len + 1).join('a');
encoding = 'ascii';
break;
case 'utf':
message = new Array(conf.len / 2 + 1).join('ü');
encoding = 'utf8';
break;
case 'buf':
message = new Buffer(conf.len);
message.fill('b');
break;
default:
throw new Error('unknown message type: ' + conf.type);
}
var fn = api === 'stream' ? streamWrite : legacyWrite;
bench.start();
fn(conf.algo, message, encoding, conf.writes, conf.len, conf.out);
}
function legacyWrite(algo, message, encoding, writes, len, outEnc) {
var written = writes * len;
var bits = written * 8;
var gbits = bits / (1024 * 1024 * 1024);
while (writes-- > 0) {
var h = crypto.createHash(algo);
h.update(message, encoding);
var res = h.digest(outEnc);
// include buffer creation costs for older versions
if (outEnc === 'buffer' && typeof res === 'string')
res = new Buffer(res, 'binary');
}
bench.end(gbits);
}
function streamWrite(algo, message, encoding, writes, len, outEnc) {
var written = writes * len;
var bits = written * 8;
var gbits = bits / (1024 * 1024 * 1024);
while (writes-- > 0) {
var h = crypto.createHash(algo);
if (outEnc !== 'buffer')
h.setEncoding(outEnc);
h.write(message, encoding);
h.end();
h.read();
}
bench.end(gbits);
}

View File

@@ -1,77 +0,0 @@
// throughput benchmark
// creates a single hasher, then pushes a bunch of data through it
var common = require('../common.js');
var crypto = require('crypto');
var bench = common.createBenchmark(main, {
writes: [500],
algo: [ 'sha256', 'md5' ],
type: ['asc', 'utf', 'buf'],
len: [2, 1024, 102400, 1024 * 1024],
api: ['legacy', 'stream']
});
function main(conf) {
var api = conf.api;
if (api === 'stream' && process.version.match(/^v0\.[0-8]\./)) {
console.error('Crypto streams not available until v0.10');
// use the legacy, just so that we can compare them.
api = 'legacy';
}
var crypto = require('crypto');
var assert = require('assert');
var message;
var encoding;
switch (conf.type) {
case 'asc':
message = new Array(conf.len + 1).join('a');
encoding = 'ascii';
break;
case 'utf':
message = new Array(conf.len / 2 + 1).join('ü');
encoding = 'utf8';
break;
case 'buf':
message = new Buffer(conf.len);
message.fill('b');
break;
default:
throw new Error('unknown message type: ' + conf.type);
}
var fn = api === 'stream' ? streamWrite : legacyWrite;
bench.start();
fn(conf.algo, message, encoding, conf.writes, conf.len);
}
function legacyWrite(algo, message, encoding, writes, len) {
var written = writes * len;
var bits = written * 8;
var gbits = bits / (1024 * 1024 * 1024);
var h = crypto.createHash(algo);
while (writes-- > 0)
h.update(message, encoding);
h.digest();
bench.end(gbits);
}
function streamWrite(algo, message, encoding, writes, len) {
var written = writes * len;
var bits = written * 8;
var gbits = bits / (1024 * 1024 * 1024);
var h = crypto.createHash(algo);
while (writes-- > 0)
h.write(message, encoding);
h.end();
h.read();
bench.end(gbits);
}

42
benchmark/fast_buffer2.js Normal file
View File

@@ -0,0 +1,42 @@
var SlowBuffer = require('buffer').SlowBuffer;
var POOLSIZE = 8*1024;
var pool;
function allocPool () {
pool = new SlowBuffer(POOLSIZE);
pool.used = 0;
}
function FastBuffer (length) {
this.length = length;
if (length > POOLSIZE) {
// Big buffer, just alloc one.
this.parent = new Buffer(length);
this.offset = 0;
} else {
// Small buffer.
if (!pool || pool.length - pool.used < length) allocPool();
this.parent = pool;
this.offset = pool.used;
pool.used += length;
}
// HERE HERE HERE
SlowBuffer.makeFastBuffer(this.parent, this, this.offset, this.length);
}
exports.FastBuffer = FastBuffer;
FastBuffer.prototype.get = function (i) {
if (i < 0 || i >= this.length) throw new Error("oob");
return this.parent[this.offset + i];
};
FastBuffer.prototype.set = function (i, v) {
if (i < 0 || i >= this.length) throw new Error("oob");
return this.parent[this.offset + i] = v;
};
// TODO define slice, toString, write, etc.
// slice should not use c++

View File

@@ -0,0 +1,6 @@
FastBuffer = require('./fast_buffer2').FastBuffer;
for (var i = 0; i < 1e6; i++) {
b = new FastBuffer(10);
b[1] = 2;
}

View File

@@ -0,0 +1,4 @@
for (var i = 0; i < 1e6; i++) {
b = new Buffer(10);
b[1] = 2;
}

View File

@@ -1,96 +0,0 @@
// If there are no args, then this is the root. Run all the benchmarks!
if (!process.argv[2])
parent();
else
runTest(+process.argv[2], +process.argv[3], process.argv[4]);
function parent() {
var types = [ 'string', 'buffer' ];
var durs = [ 1, 5 ];
var sizes = [ 1, 10, 100, 2048, 10240 ];
var queue = [];
types.forEach(function(t) {
durs.forEach(function(d) {
sizes.forEach(function(s) {
queue.push([__filename, d, s, t]);
});
});
});
var spawn = require('child_process').spawn;
var node = process.execPath;
run();
function run() {
var args = queue.shift();
if (!args)
return;
var child = spawn(node, args, { stdio: 'inherit' });
child.on('close', function(code, signal) {
if (code)
throw new Error('Benchmark failed: ' + args.slice(1));
run();
});
}
}
function runTest(dur, size, type) {
if (type !== 'string')
type = 'buffer';
switch (type) {
case 'string':
var chunk = new Array(size + 1).join('a');
break;
case 'buffer':
var chunk = new Buffer(size);
chunk.fill('a');
break;
}
var writes = 0;
var fs = require('fs');
try { fs.unlinkSync('write_stream_throughput'); } catch (e) {}
var start
var end;
function done() {
var time = end[0] + end[1]/1E9;
var written = fs.statSync('write_stream_throughput').size / 1024;
var rate = (written / time).toFixed(2);
console.log('fs_write_stream_dur_%d_size_%d_type_%s: %d',
dur, size, type, rate);
try { fs.unlinkSync('write_stream_throughput'); } catch (e) {}
}
var f = require('fs').createWriteStream('write_stream_throughput');
f.on('drain', write);
f.on('open', write);
f.on('close', done);
// streams2 fs.WriteStreams will let you send a lot of writes into the
// buffer before returning false, so capture the *actual* end time when
// all the bytes have been written to the disk, indicated by 'finish'
f.on('finish', function() {
end = process.hrtime(start);
});
var ending = false;
function write() {
// don't try to write after we end, even if a 'drain' event comes.
// v0.8 streams are so sloppy!
if (ending)
return;
start = start || process.hrtime();
while (false !== f.write(chunk));
end = process.hrtime(start);
if (end[0] >= dur) {
ending = true;
f.end();
}
}
}

View File

@@ -1,87 +0,0 @@
// test the througput of the fs.WriteStream class.
var path = require('path');
var common = require('../common.js');
var filename = path.resolve(__dirname, '.removeme-benchmark-garbage');
var fs = require('fs');
var filesize = 1000 * 1024 * 1024;
var assert = require('assert');
var type, encoding, size;
var bench = common.createBenchmark(main, {
type: ['buf', 'asc', 'utf'],
size: [1024, 4096, 65535, 1024*1024]
});
function main(conf) {
type = conf.type;
size = +conf.size;
switch (type) {
case 'buf':
encoding = null;
break;
case 'asc':
encoding = 'ascii';
break;
case 'utf':
encoding = 'utf8';
break;
default:
throw new Error('invalid type');
}
makeFile(runTest);
}
function runTest() {
assert(fs.statSync(filename).size === filesize);
var rs = fs.createReadStream(filename, {
bufferSize: size,
encoding: encoding
});
rs.on('open', function() {
bench.start();
});
var bytes = 0;
rs.on('data', function(chunk) {
bytes += chunk.length;
});
rs.on('end', function() {
try { fs.unlinkSync(filename); } catch (e) {}
// MB/sec
bench.end(bytes / (1024 * 1024));
});
}
function makeFile() {
var buf = new Buffer(filesize / 1024);
if (encoding === 'utf8') {
// ü
for (var i = 0; i < buf.length; i++) {
buf[i] = i % 2 === 0 ? 0xC3 : 0xBC;
}
} else if (encoding === 'ascii') {
buf.fill('a');
} else {
buf.fill('x');
}
try { fs.unlinkSync(filename); } catch (e) {}
var w = 1024;
var ws = fs.createWriteStream(filename);
ws.on('close', runTest);
ws.on('drain', write);
write();
function write() {
do {
w--;
} while (false !== ws.write(buf) && w > 0);
if (w === 0)
ws.end();
}
}

View File

@@ -1,48 +0,0 @@
// Call fs.readFile over and over again really fast.
// Then see how many times it got called.
// Yes, this is a silly benchmark. Most benchmarks are silly.
var path = require('path');
var common = require('../common.js');
var filename = path.resolve(__dirname, '.removeme-benchmark-garbage');
var fs = require('fs');
var bench = common.createBenchmark(main, {
dur: [5],
len: [1024, 16 * 1024 * 1024],
concurrent: [1, 10]
});
function main(conf) {
var len = +conf.len;
try { fs.unlinkSync(filename); } catch (e) {}
var data = new Buffer(len);
data.fill('x');
fs.writeFileSync(filename, data);
data = null;
var reads = 0;
bench.start();
setTimeout(function() {
bench.end(reads);
try { fs.unlinkSync(filename); } catch (e) {}
}, +conf.dur * 1000);
function read() {
fs.readFile(filename, afterRead);
}
function afterRead(er, data) {
if (er)
throw er;
if (data.length !== len)
throw new Error('wrong number of bytes returned');
reads++;
read();
}
var cur = +conf.concurrent;
while (cur--) read();
}

View File

@@ -1,78 +0,0 @@
// test the througput of the fs.WriteStream class.
var path = require('path');
var common = require('../common.js');
var filename = path.resolve(__dirname, '.removeme-benchmark-garbage');
var fs = require('fs');
var bench = common.createBenchmark(main, {
dur: [5],
type: ['buf', 'asc', 'utf'],
size: [2, 1024, 65535, 1024 * 1024]
});
function main(conf) {
var dur = +conf.dur;
var type = conf.type;
var size = +conf.size;
var encoding;
var chunk;
switch (type) {
case 'buf':
chunk = new Buffer(size);
chunk.fill('b');
break;
case 'asc':
chunk = new Array(size + 1).join('a');
encoding = 'ascii';
break;
case 'utf':
chunk = new Array(Math.ceil(size/2) + 1).join('ü');
encoding = 'utf8';
break;
default:
throw new Error('invalid type');
}
try { fs.unlinkSync(filename); } catch (e) {}
var started = false;
var ending = false;
var ended = false;
setTimeout(function() {
ending = true;
f.end();
}, dur * 1000);
var f = fs.createWriteStream(filename);
f.on('drain', write);
f.on('open', write);
f.on('close', done);
f.on('finish', function() {
ended = true;
var written = fs.statSync(filename).size / 1024;
try { fs.unlinkSync(filename); } catch (e) {}
bench.end(written / 1024);
});
function write() {
// don't try to write after we end, even if a 'drain' event comes.
// v0.8 streams are so sloppy!
if (ending)
return;
if (!started) {
started = true;
bench.start();
}
while (false !== f.write(chunk, encoding));
}
function done() {
if (!ended)
f.emit('finish');
}
}

View File

@@ -0,0 +1,43 @@
var binding = require('./build/default/binding');
c = 0
function js() {
return c++; //(new Date()).getTime();
}
var cxx = binding.hello;
var i, N = 100000000;
console.log(js());
console.log(cxx());
var start = new Date();
for (i = 0; i < N; i++) {
js();
}
var jsDiff = new Date() - start;
console.log(N +" JS function calls: " + jsDiff);
var start = new Date();
for (i = 0; i < N; i++) {
cxx();
}
var cxxDiff = new Date() - start;
console.log(N +" C++ function calls: " + cxxDiff);
function toMicro (diff) {
return (diff / N) * 1000000;
}
console.log("\nJS function call speed: %d microseconds", toMicro(jsDiff));
console.log("C++ function call speed: %d microseconds", toMicro(cxxDiff));
console.log("\nJS speedup " + (cxxDiff / jsDiff));

View File

@@ -0,0 +1,19 @@
#include <v8.h>
#include <node.h>
#include <time.h>
using namespace v8;
static int c = 0;
static Handle<Value> Hello(const Arguments& args) {
HandleScope scope;
//time_t tv = time(NULL);
return scope.Close(Integer::New(c++));
}
extern "C" void init (Handle<Object> target) {
HandleScope scope;
//target->Set(String::New("hello"), String::New("World"));
NODE_SET_METHOD(target, "hello", Hello);
}

View File

@@ -0,0 +1,15 @@
srcdir = '.'
blddir = 'build'
VERSION = '0.0.1'
def set_options(opt):
opt.tool_options('compiler_cxx')
def configure(conf):
conf.check_tool('compiler_cxx')
conf.check_tool('node_addon')
def build(bld):
obj = bld.new_task_gen('cxx', 'shlib', 'node_addon')
obj.target = 'binding'
obj.source = 'binding.cc'

View File

@@ -1,116 +0,0 @@
#!/bin/bash
cd "$(dirname "$(dirname $0)")"
node=${NODE:-./node}
name=${NAME:-stacks}
if type sysctl &>/dev/null; then
# darwin and linux
sudo sysctl -w net.inet.ip.portrange.first=12000
sudo sysctl -w net.inet.tcp.msl=1000
sudo sysctl -w kern.maxfiles=1000000 kern.maxfilesperproc=1000000
elif type /usr/sbin/ndd &>/dev/null; then
# sunos
/usr/sbin/ndd -set /dev/tcp tcp_smallest_anon_port 12000
/usr/sbin/ndd -set /dev/tcp tcp_largest_anon_port 65535
/usr/sbin/ndd -set /dev/tcp tcp_max_buf 2097152
/usr/sbin/ndd -set /dev/tcp tcp_xmit_hiwat 1048576
/usr/sbin/ndd -set /dev/tcp tcp_recv_hiwat 1048576
fi
ulimit -n 100000
$node benchmark/http_simple.js &
nodepid=$!
echo "node pid = $nodepid"
sleep 1
# has to stay alive until dtrace exits
dtrace -n 'profile-97/pid == '$nodepid' && arg1/{ @[jstack(150, 8000)] = count(); } tick-60s { exit(0); }' \
| grep -v _ZN2v88internalL21Builtin_HandleApiCallENS0_12_GLOBAL__N_116BuiltinA \
> "$name".src &
dtracepid=$!
echo "dtrace pid = $dtracepid"
sleep 1
test () {
c=$1
t=$2
l=$3
k=$4
ab $k -t 10 -c $c http://127.0.0.1:8000/$t/$l \
2>&1 | grep Req
}
#test 100 bytes 1024
#test 10 bytes 100 -k
#test 100 bytes 1024 -k
#test 100 bytes 1024 -k
#test 100 bytes 1024 -k
echo 'Keep going until dtrace stops listening...'
while pargs $dtracepid &>/dev/null; do
test 100 bytes ${LENGTH:-1} -k
done
kill $nodepid
echo 'Turn the stacks into a svg'
stackvis dtrace flamegraph-svg < "$name".src > "$name".raw.svg
echo 'Prune tiny stacks out of the graph'
node -e '
var infile = process.argv[1];
var outfile = process.argv[2];
var output = "";
var fs = require("fs");
var input = fs.readFileSync(infile, "utf8");
input = input.split("id=\"details\" > </text>");
var head = input.shift() + "id=\"details\" > </text>";
input = input.join("id=\"details\" > </text>");
var tail = "</svg>";
input = input.split("</svg>")[0];
var minyKept = Infinity;
var minyOverall = Infinity;
var rects = input.trim().split(/\n/).filter(function(rect) {
var my = rect.match(/y="([0-9\.]+)"/);
if (!my)
return false;
var y = +my[1];
if (!y)
return false;
minyOverall = Math.min(minyOverall, y);
// pluck off everything that will be less than one pixel.
var mw = rect.match(/width="([0-9\.]+)"/)
if (mw) {
var width = +mw[1];
if (!(width >= 1))
return false;
}
minyKept = Math.min(minyKept, y);
return true;
});
// move everything up to the top of the page.
var ydiff = minyKept - minyOverall;
rects = rects.map(function(rect) {
var my = rect.match(/y="([0-9\.]+)"/);
var y = +my[1];
var newy = y - ydiff;
rect = rect.replace(/y="([0-9\.]+)"/, "y=\"" + newy + "\"");
return rect;
});
fs.writeFileSync(outfile, head + "\n" + rects.join("\n") + "\n" + tail);
' "$name".raw.svg "$name".svg
echo ''
echo 'done. Results in '"$name"'.svg'

View File

@@ -1,43 +0,0 @@
#!/bin/bash
cd "$(dirname "$(dirname $0)")"
if type sysctl &>/dev/null; then
# darwin and linux
sudo sysctl -w net.ipv4.ip_local_port_range="12000 65535"
sudo sysctl -w net.inet.ip.portrange.first=12000
sudo sysctl -w net.inet.tcp.msl=1000
sudo sysctl -w kern.maxfiles=1000000 kern.maxfilesperproc=1000000
elif type /usr/sbin/ndd &>/dev/null; then
# sunos
/usr/sbin/ndd -set /dev/tcp tcp_smallest_anon_port 12000
/usr/sbin/ndd -set /dev/tcp tcp_largest_anon_port 65535
/usr/sbin/ndd -set /dev/tcp tcp_max_buf 2097152
/usr/sbin/ndd -set /dev/tcp tcp_xmit_hiwat 1048576
/usr/sbin/ndd -set /dev/tcp tcp_recv_hiwat 1048576
fi
ulimit -n 100000
k=${KEEPALIVE}
if [ "$k" = "no" ]; then
k=""
else
k="-k"
fi
node=${NODE:-./node}
$node benchmark/http_simple.js &
npid=$!
sleep 1
if [ "$k" = "-k" ]; then
echo "using keepalive"
fi
for i in a a a a a a a a a a a a a a a a a a a a; do
ab $k -t 10 -c 100 http://127.0.0.1:8000/${TYPE:-bytes}/${LENGTH:-1024} \
2>&1 | grep Req | egrep -o '[0-9\.]+'
done
kill $npid

View File

@@ -1,69 +0,0 @@
// Measure the time it takes for the HTTP client to send a request body.
var common = require('../common.js');
var http = require('http');
var bench = common.createBenchmark(main, {
dur: [5],
type: ['asc', 'utf', 'buf'],
bytes: [32, 256, 1024],
method: ['write', 'end '] // two spaces added to line up each row
});
function main(conf) {
var dur = +conf.dur;
var len = +conf.bytes;
var encoding;
var chunk;
switch (conf.type) {
case 'buf':
chunk = new Buffer(len);
chunk.fill('x');
break;
case 'utf':
encoding = 'utf8';
chunk = new Array(len / 2 + 1).join('ü');
break;
case 'asc':
chunk = new Array(len + 1).join('a');
break;
}
var nreqs = 0;
var options = {
headers: { 'Connection': 'keep-alive', 'Transfer-Encoding': 'chunked' },
agent: new http.Agent({ maxSockets: 1 }),
host: '127.0.0.1',
port: common.PORT,
path: '/',
method: 'POST'
};
var server = http.createServer(function(req, res) {
res.end();
});
server.listen(options.port, options.host, function() {
setTimeout(done, dur * 1000);
bench.start();
pummel();
});
function pummel() {
var req = http.request(options, function(res) {
nreqs++;
pummel(); // Line up next request.
res.resume();
});
if (conf.method === 'write') {
req.write(chunk, encoding);
req.end();
} else {
req.end(chunk, encoding);
}
}
function done() {
bench.end(nreqs);
}
}

View File

@@ -1,38 +0,0 @@
var common = require('../common.js');
var PORT = common.PORT;
var cluster = require('cluster');
if (cluster.isMaster) {
var bench = common.createBenchmark(main, {
// unicode confuses ab on os x.
type: ['bytes', 'buffer'],
length: [4, 1024, 102400],
c: [50, 500]
});
} else {
require('../http_simple.js');
}
function main(conf) {
process.env.PORT = PORT;
var workers = 0;
var w1 = cluster.fork();
var w2 = cluster.fork();
cluster.on('listening', function() {
workers++;
if (workers < 2)
return;
setTimeout(function() {
var path = '/' + conf.type + '/' + conf.length;
var args = ['-r', '-t', 5, '-c', conf.c, '-k'];
var args = ['-r', 5000, '-t', 8, '-c', conf.c];
bench.http(path, args, function() {
w1.destroy();
w2.destroy();
});
}, 100);
});
}

View File

@@ -1,59 +0,0 @@
// When calling .end(buffer) right away, this triggers a "hot path"
// optimization in http.js, to avoid an extra write call.
//
// However, the overhead of copying a large buffer is higher than
// the overhead of an extra write() call, so the hot path was not
// always as hot as it could be.
//
// Verify that our assumptions are valid.
var common = require('../common.js');
var PORT = common.PORT;
var bench = common.createBenchmark(main, {
type: ['asc', 'utf', 'buf'],
kb: [64, 128, 256, 1024],
c: [100],
method: ['write', 'end '] // two spaces added to line up each row
});
function main(conf) {
http = require('http');
var chunk;
var len = conf.kb * 1024;
switch (conf.type) {
case 'buf':
chunk = new Buffer(len);
chunk.fill('x');
break;
case 'utf':
encoding = 'utf8';
chunk = new Array(len / 2 + 1).join('ü');
break;
case 'asc':
chunk = new Array(len + 1).join('a');
break;
}
function write(res) {
res.write(chunk);
res.end();
}
function end(res) {
res.end(chunk);
}
var method = conf.method === 'write' ? write : end;
var args = ['-r', 5000, '-t', 8, '-c', conf.c];
var server = http.createServer(function(req, res) {
method(res);
});
server.listen(common.PORT, function() {
bench.http('/', args, function() {
server.close();
});
});
}

View File

@@ -1,23 +0,0 @@
var common = require('../common.js');
var PORT = common.PORT;
var bench = common.createBenchmark(main, {
// unicode confuses ab on os x.
type: ['bytes', 'buffer'],
length: [4, 1024, 102400],
c: [50, 500]
});
function main(conf) {
process.env.PORT = PORT;
var spawn = require('child_process').spawn;
var server = require('../http_simple.js');
setTimeout(function() {
var path = '/' + conf.type + '/' + conf.length; //+ '/' + conf.chunks;
var args = ['-r', 5000, '-t', 8, '-c', conf.c];
bench.http(path, args, function() {
server.close();
});
}, 2000);
}

View File

@@ -1,127 +0,0 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var spawn = require('child_process').spawn;
var cluster = require('cluster');
var http = require('http');
var options = {
mode: 'master',
host: '127.0.0.1',
port: 22344,
path: '/',
servers: 1,
clients: 1
};
for (var i = 2; i < process.argv.length; ++i) {
var args = process.argv[i].split('=', 2);
var key = args[0];
var val = args[1];
options[key] = val;
}
switch (options.mode) {
case 'master': startMaster(); break;
case 'server': startServer(); break;
case 'client': startClient(); break;
default: throw new Error('Bad mode: ' + options.mode);
}
process.title = 'http_bench[' + options.mode + ']';
// monkey-patch the log functions so they include name + pid
console.log = patch(console.log);
console.trace = patch(console.trace);
console.error = patch(console.error);
function patch(fun) {
var prefix = process.title + '[' + process.pid + '] ';
return function() {
var args = Array.prototype.slice.call(arguments);
args[0] = prefix + args[0];
return fun.apply(console, args);
};
}
function startMaster() {
if (!cluster.isMaster) return startServer();
for (var i = ~~options.servers; i > 0; --i) cluster.fork();
for (var i = ~~options.clients; i > 0; --i) {
var cp = spawn(process.execPath, [__filename, 'mode=client']);
cp.stdout.pipe(process.stdout);
cp.stderr.pipe(process.stderr);
}
}
function startServer() {
http.createServer(onRequest).listen(options.port, options.host);
var body = Array(1024).join('x');
var headers = {'Content-Length': '' + body.length};
function onRequest(req, res) {
req.on('error', onError);
res.on('error', onError);
res.writeHead(200, headers);
res.end(body);
}
function onError(err) {
console.error(err.stack);
}
}
function startClient() {
// send off a bunch of concurrent requests
// TODO make configurable
sendRequest();
sendRequest();
function sendRequest() {
var req = http.request(options, onConnection);
req.on('error', onError);
req.end();
}
// add a little back-off to prevent EADDRNOTAVAIL errors, it's pretty easy
// to exhaust the available port range
function relaxedSendRequest() {
setTimeout(sendRequest, 1);
}
function onConnection(res) {
res.on('error', onError);
res.on('data', onData);
res.on('end', relaxedSendRequest);
}
function onError(err) {
console.error(err.stack);
relaxedSendRequest();
}
function onData(data) {
// this space intentionally left blank
}
}

View File

@@ -1,13 +0,0 @@
var http = require('http');
var port = parseInt(process.env.PORT, 10) || 8000;
var defaultLag = parseInt(process.argv[2], 10) || 100;
http.createServer(function(req, res) {
res.writeHead(200, { 'content-type': 'text/plain',
'content-length': '2' });
var lag = parseInt(req.url.split("/").pop(), 10) || defaultLag;
setTimeout(function() {
res.end('ok');
}, lag);
}).listen(port, 'localhost');

View File

@@ -1,120 +1,92 @@
var path = require('path'),
exec = require('child_process').exec,
http = require('http');
path = require("path");
exec = require("child_process").exec;
http = require("http");
var port = parseInt(process.env.PORT || 8000);
port = parseInt(process.env.PORT || 8000);
var fixed = makeString(20 * 1024, 'C'),
storedBytes = {},
storedBuffer = {},
storedUnicode = {};
console.log('pid ' + process.pid);
var useDomains = process.env.NODE_USE_DOMAINS;
// set up one global domain.
if (useDomains) {
var domain = require('domain');
var gdom = domain.create();
gdom.on('error', function(er) {
console.error('Error on global domain', er);
throw er;
});
gdom.enter();
fixed = ""
for (var i = 0; i < 20*1024; i++) {
fixed += "C";
}
var server = module.exports = http.createServer(function (req, res) {
if (useDomains) {
var dom = domain.create();
dom.add(req);
dom.add(res);
}
stored = {};
storedBuffer = {};
var commands = req.url.split('/');
var server = http.createServer(function (req, res) {
var commands = req.url.split("/");
var command = commands[1];
var body = '';
var body = "";
var arg = commands[2];
var n_chunks = parseInt(commands[3], 10);
var status = 200;
if (command == 'bytes') {
var n = ~~arg;
if (command == "bytes") {
var n = parseInt(arg, 10)
if (n <= 0)
throw new Error('bytes called with n <= 0')
if (storedBytes[n] === undefined) {
storedBytes[n] = makeString(n, 'C');
throw "bytes called with n <= 0"
if (stored[n] === undefined) {
console.log("create stored[n]");
stored[n] = "";
for (var i = 0; i < n; i++) {
stored[n] += "C"
}
}
body = storedBytes[n];
body = stored[n];
} else if (command == 'buffer') {
var n = ~~arg;
if (n <= 0)
throw new Error('buffer called with n <= 0');
} else if (command == "buffer") {
var n = parseInt(arg, 10)
if (n <= 0) throw new Error("bytes called with n <= 0");
if (storedBuffer[n] === undefined) {
console.log("create storedBuffer[n]");
storedBuffer[n] = new Buffer(n);
for (var i = 0; i < n; i++) {
storedBuffer[n][i] = 'C'.charCodeAt(0);
storedBuffer[n][i] = "C".charCodeAt(0);
}
}
body = storedBuffer[n];
} else if (command == 'unicode') {
var n = ~~arg;
if (n <= 0)
throw new Error('unicode called with n <= 0');
if (storedUnicode[n] === undefined) {
storedUnicode[n] = makeString(n, '\u263A');
}
body = storedUnicode[n];
} else if (command == 'quit') {
} else if (command == "quit") {
res.connection.server.close();
body = 'quitting';
body = "quitting";
} else if (command == 'fixed') {
} else if (command == "fixed") {
body = fixed;
} else if (command == 'echo') {
res.writeHead(200, { 'Content-Type': 'text/plain',
'Transfer-Encoding': 'chunked' });
req.pipe(res);
return;
} else {
status = 404;
body = 'not found\n';
body = "not found\n";
}
// example: http://localhost:port/bytes/512/4
// sends a 512 byte body in 4 chunks of 128 bytes
if (n_chunks > 0) {
res.writeHead(status, { 'Content-Type': 'text/plain',
'Transfer-Encoding': 'chunked' });
res.writeHead(status, { "Content-Type": "text/plain",
"Transfer-Encoding": "chunked" });
// send body in chunks
var len = body.length;
var step = Math.floor(len / n_chunks) || 1;
var step = ~~(len / n_chunks) || len;
for (var i = 0, n = (n_chunks - 1); i < n; ++i) {
res.write(body.slice(i * step, i * step + step));
for (var i = 0; i < len; i += step) {
res.write(body.slice(i, i + step));
}
res.end(body.slice((n_chunks - 1) * step));
res.end();
} else {
var content_length = body.length.toString();
res.writeHead(status, { 'Content-Type': 'text/plain',
'Content-Length': content_length });
res.writeHead(status, { "Content-Type": "text/plain",
"Content-Length": content_length });
res.end(body);
}
});
function makeString(size, c) {
var s = '';
while (s.length < size) {
s += c;
}
return s;
}
});
server.listen(port, function () {
if (module === require.main)
console.error('Listening at http://127.0.0.1:'+port+'/');
console.log('Listening at http://127.0.0.1:'+port+'/');
});
process.on('exit', function() {
console.error('libuv counters', process.uvCounters());
});

View File

@@ -1,127 +0,0 @@
//
// Usage:
// node benchmark/http_simple_auto.js <args> <target>
//
// Where:
// <args> Arguments to pass to `ab`.
// <target> Target to benchmark, e.g. `bytes/1024` or `buffer/8192`.
//
var path = require("path");
var http = require("http");
var spawn = require("child_process").spawn;
var port = parseInt(process.env.PORT || 8000);
var fixed = ""
for (var i = 0; i < 20*1024; i++) {
fixed += "C";
}
var stored = {};
var storedBuffer = {};
var server = http.createServer(function (req, res) {
var commands = req.url.split("/");
var command = commands[1];
var body = "";
var arg = commands[2];
var n_chunks = parseInt(commands[3], 10);
var status = 200;
if (command == "bytes") {
var n = parseInt(arg, 10)
if (n <= 0)
throw "bytes called with n <= 0"
if (stored[n] === undefined) {
stored[n] = "";
for (var i = 0; i < n; i++) {
stored[n] += "C"
}
}
body = stored[n];
} else if (command == "buffer") {
var n = parseInt(arg, 10)
if (n <= 0) throw new Error("bytes called with n <= 0");
if (storedBuffer[n] === undefined) {
storedBuffer[n] = new Buffer(n);
for (var i = 0; i < n; i++) {
storedBuffer[n][i] = "C".charCodeAt(0);
}
}
body = storedBuffer[n];
} else if (command == "quit") {
res.connection.server.close();
body = "quitting";
} else if (command == "fixed") {
body = fixed;
} else if (command == "echo") {
res.writeHead(200, { "Content-Type": "text/plain",
"Transfer-Encoding": "chunked" });
req.pipe(res);
return;
} else {
status = 404;
body = "not found\n";
}
// example: http://localhost:port/bytes/512/4
// sends a 512 byte body in 4 chunks of 128 bytes
if (n_chunks > 0) {
res.writeHead(status, { "Content-Type": "text/plain",
"Transfer-Encoding": "chunked" });
// send body in chunks
var len = body.length;
var step = Math.floor(len / n_chunks) || 1;
for (var i = 0, n = (n_chunks - 1); i < n; ++i) {
res.write(body.slice(i * step, i * step + step));
}
res.end(body.slice((n_chunks - 1) * step));
} else {
var content_length = body.length.toString();
res.writeHead(status, { "Content-Type": "text/plain",
"Content-Length": content_length });
res.end(body);
}
});
server.listen(port, function () {
var url = 'http://127.0.0.1:' + port + '/';
var n = process.argv.length - 1;
process.argv[n] = url + process.argv[n];
var cp = spawn('ab', process.argv.slice(2));
cp.stdout.pipe(process.stdout);
cp.stderr.pipe(process.stderr);
cp.on('exit', function() {
server.close();
process.nextTick(dump_mm_stats);
});
});
function dump_mm_stats() {
if (typeof gc != 'function') return;
var before = process.memoryUsage();
for (var i = 0; i < 10; ++i) gc();
var after = process.memoryUsage();
setTimeout(print_stats, 250); // give GC time to settle
function print_stats() {
console.log('\nBEFORE / AFTER GC');
['rss', 'heapTotal', 'heapUsed'].forEach(function(key) {
var a = before[key] / (1024 * 1024);
var b = after[key] / (1024 * 1024);
console.log('%sM / %sM %s', a.toFixed(2), b.toFixed(2), key);
});
}
}

View File

@@ -1,7 +1,7 @@
#!/bin/bash
SERVER=127.0.0.1
PORT=${PORT:=8000}
PORT=8000
# You may want to configure your TCP settings to make many ports available
# to node and ab. On macintosh use:
@@ -19,6 +19,9 @@ if [ $SERVER == "127.0.0.1" ]; then
sleep 1
fi
info=`curl -s http://$SERVER:$PORT/info`
eval $info
date=`date "+%Y%m%d%H%M%S"`
ab_hello_world() {

View File

@@ -1,9 +0,0 @@
var cluster = require('cluster');
var os = require('os');
if (cluster.isMaster) {
console.log('master running on pid %d', process.pid);
for (var i = 0, n = os.cpus().length; i < n; ++i) cluster.fork();
} else {
require(__dirname + '/http_simple.js');
}

View File

@@ -2,89 +2,78 @@
* gcc -o iotest io.c
*/
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/time.h>
#include <assert.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
static int c = 0;
static int tsize = 1000 * 1048576;
static const char* path = "/tmp/wt.dat";
static char buf[65536];
int tsize = 1000 * 1048576;
const char *path = "/tmp/wt.dat";
static uint64_t now(void) {
struct timeval tv;
int c = 0;
if (gettimeofday(&tv, NULL))
abort();
return tv.tv_sec * 1000000ULL + tv.tv_usec;
char* bufit(size_t l)
{
char *p = malloc(l);
memset(p, '!', l);
return p;
}
static void writetest(int size, size_t bsize)
void writetest(int size, size_t bsize)
{
int i;
uint64_t start, end;
char *buf = bufit(bsize);
struct timeval start, end;
double elapsed;
double mbps;
assert(bsize <= sizeof buf);
int fd = open(path, O_CREAT|O_WRONLY, 0644);
if (fd < 0) {
perror("open failed");
exit(254);
}
start = now();
assert(0 == gettimeofday(&start, NULL));
for (i = 0; i < size; i += bsize) {
int rv = write(fd, buf, bsize);
if (c++ % 2000 == 0) fprintf(stderr, ".");
if (rv < 0) {
perror("write failed");
exit(254);
}
}
#ifndef NSYNC
# ifdef __linux__
#ifdef __linux__
fdatasync(fd);
# else
#else
fsync(fd);
# endif
#endif /* SYNC */
#endif
close(fd);
end = now();
elapsed = (end - start) / 1e6;
assert(0 == gettimeofday(&end, NULL));
elapsed = (end.tv_sec - start.tv_sec) + ((double)(end.tv_usec - start.tv_usec))/100000.;
mbps = ((tsize/elapsed)) / 1048576;
fprintf(stderr, "\nWrote %d bytes in %03fs using %ld byte buffers: %03fmB/s\n", size, elapsed, bsize, mbps);
fprintf(stderr, "Wrote %d bytes in %03fs using %ld byte buffers: %03f\n", size, elapsed, bsize, mbps);
free(buf);
}
void readtest(int size, size_t bsize)
{
int i;
uint64_t start, end;
char *buf = bufit(bsize);
struct timeval start, end;
double elapsed;
double mbps;
assert(bsize <= sizeof buf);
int fd = open(path, O_RDONLY, 0644);
if (fd < 0) {
perror("open failed");
exit(254);
}
start = now();
assert(0 == gettimeofday(&start, NULL));
for (i = 0; i < size; i += bsize) {
int rv = read(fd, buf, bsize);
if (rv < 0) {
@@ -93,25 +82,23 @@ void readtest(int size, size_t bsize)
}
}
close(fd);
end = now();
elapsed = (end - start) / 1e6;
assert(0 == gettimeofday(&end, NULL));
elapsed = (end.tv_sec - start.tv_sec) + ((double)(end.tv_usec - start.tv_usec))/100000.;
mbps = ((tsize/elapsed)) / 1048576;
fprintf(stderr, "Read %d bytes in %03fs using %ld byte buffers: %03fmB/s\n", size, elapsed, bsize, mbps);
free(buf);
}
void cleanup() {
unlink(path);
}
int main(int argc, char** argv)
int main()
{
int i;
int bsizes[] = {1024, 4096, 8192, 16384, 32768, 65536, 0};
if (argc > 1) path = argv[1];
for (i = 0; bsizes[i] != 0; i++) {
writetest(tsize, bsizes[i]);
}

109
benchmark/io.js Normal file
View File

@@ -0,0 +1,109 @@
var fs = require('fs');
var util = require('util');
var Buffer = require('buffer').Buffer;
var path = "/tmp/wt.dat";
var tsize = 1000 * 1048576;
var bsizes = [1024, 4096, 8192, 16384, 32768, 65536];
function bufit(size) {
var buf = new Buffer(size);
for (var i = 0; i <buf.length ; i += 1) {
buf[i] = 33;
}
return buf;
}
function once(emitter, name, cb) {
function incb() {
cb.apply(undefined, arguments);
emitter.removeListener(name, incb);
}
emitter.addListener(name, incb);
}
c = 0
function writetest(size, bsize) {
var s = fs.createWriteStream(path, {'flags': 'w', 'mode': 0644});
var remaining = size;
var buf = bufit(bsize);
function dowrite() {
var rv = s.write(buf);
remaining -= buf.length;
if (remaining > 0) {
//if (remaining % 90000 == 0) console.error("remaining: %d", remaining);
//process.nextTick(dowrite);
} else {
s.emit('done')
s.end();
}
}
s.on('drain', function () {
dowrite();
if (c++ % 2000 == 0) util.print(".");
});
dowrite();
return s;
}
function readtest(size, bsize) {
var s = fs.createReadStream(path, {'flags': 'r', 'encoding': 'binary', 'mode': 0644, 'bufferSize': bsize});
s.addListener("data", function (chunk) {
// got a chunk...
});
return s;
}
function wt(tsize, bsize, done) {
var start = Date.now();
s = writetest(tsize, bsizes[0]);
s.addListener('close', function() {
var end = Date.now();
var diff = end - start;
console.log('Wrote '+ tsize +' bytes in '+ diff/1000 +'s using '+ bsize +' byte buffers: '+ ((tsize/(diff/1000)) / 1048576) +' mB/s');
done();
});
}
function rt(tsize, bsize, done) {
var start = Date.now();
s = readtest(tsize, bsizes[0]);
s.addListener('close', function() {
var end = Date.now();
var diff = end - start;
console.log('Read '+ tsize +' bytes in '+ diff/1000 +'s using '+ bsize +' byte buffers: '+ ((tsize/(diff/1000)) / 1048576) +' mB/s');
done();
});
}
var bs= 0;
function nextwt() {
if (bsizes.length <= bs) {
bs = 0;
nextrt();
return;
}
wt(tsize, bsizes[bs], nextwt);
bs += 1;
}
function nextrt() {
if (bsizes.length <= bs) {
fs.unlink(path, function (err) {
if (err) throw err;
console.log('All done!');
});
return;
}
rt(tsize, bsizes[bs], nextrt);
bs += 1;
}
nextwt();

View File

@@ -1,28 +0,0 @@
var common = require('../common.js');
var bench = common.createBenchmark(main, {
len: [64, 256, 1024, 4096, 32768],
dur: [5]
});
var spawn = require('child_process').spawn;
function main(conf) {
bench.start();
var dur = +conf.dur;
var len = +conf.len;
var msg = '"' + Array(len).join('.') + '"';
var options = { 'stdio': ['ignore', 'ipc', 'ignore'] };
var child = spawn('yes', [msg], options);
var bytes = 0;
child.on('message', function(msg) {
bytes += msg.length;
});
setTimeout(function() {
child.kill();
var gbits = (bytes * 8) / (1024 * 1024 * 1024);
bench.end(gbits);
}, dur * 1000);
}

View File

@@ -1 +0,0 @@
build/

View File

@@ -1,2 +0,0 @@
binding:
node-gyp rebuild --nodedir=../../..

View File

@@ -1,18 +0,0 @@
#include <v8.h>
#include <node.h>
using namespace v8;
static int c = 0;
static Handle<Value> Hello(const Arguments& args) {
HandleScope scope;
return scope.Close(Integer::New(c++));
}
extern "C" void init (Handle<Object> target) {
HandleScope scope;
NODE_SET_METHOD(target, "hello", Hello);
}
NODE_MODULE(binding, init);

View File

@@ -1,8 +0,0 @@
{
'targets': [
{
'target_name': 'binding',
'sources': [ 'binding.cc' ]
}
]
}

View File

@@ -1,42 +0,0 @@
// show the difference between calling a short js function
// relative to a comparable C++ function.
// Reports millions of calls per second.
// Note that JS speed goes up, while cxx speed stays about the same.
var assert = require('assert');
var common = require('../../common.js');
// this fails when we try to open with a different version of node,
// which is quite common for benchmarks. so in that case, just
// abort quietly.
try {
var binding = require('./build/Release/binding');
} catch (er) {
console.error('misc/function_call.js Binding failed to load');
process.exit(0);
}
var cxx = binding.hello;
var c = 0;
function js() {
return c++;
}
assert(js() === cxx());
var bench = common.createBenchmark(main, {
type: ['js', 'cxx'],
millions: [1,10,50]
});
function main(conf) {
var n = +conf.millions * 1e6;
var fn = conf.type === 'cxx' ? cxx : js;
bench.start();
for (var i = 0; i < n; i++) {
fn();
}
bench.end(+conf.millions);
}

View File

@@ -1,21 +0,0 @@
var common = require('../common.js');
var bench = common.createBenchmark(main, {
millions: [2]
});
function main(conf) {
var N = +conf.millions * 1e6;
var n = 0;
function cb() {
n++;
if (n === N)
bench.end(n / 1e6);
}
bench.start();
for (var i = 0; i < N; i++) {
process.nextTick(cb);
}
}

View File

@@ -1,40 +0,0 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('../common.js');
var bench = common.createBenchmark(main, {
millions: [2]
});
process.maxTickDepth = Infinity;
function main(conf) {
var n = +conf.millions * 1e6;
bench.start();
process.nextTick(onNextTick);
function onNextTick() {
if (--n)
process.nextTick(onNextTick);
else
bench.end(+conf.millions);
}
}

View File

@@ -1,25 +0,0 @@
var common = require('../common.js');
var bench = common.createBenchmark(main, {
thousands: [1]
});
var spawn = require('child_process').spawn;
function main(conf) {
var len = +conf.thousands * 1000;
bench.start();
go(len, len);
}
function go(n, left) {
if (--left === 0)
return bench.end(n);
var child = spawn('echo', ['hello']);
child.on('exit', function(code) {
if (code)
process.exit(code);
else
go(n, left);
});
}

View File

@@ -1,40 +0,0 @@
var common = require('../common.js');
var spawn = require('child_process').spawn;
var path = require('path');
var emptyJsFile = path.resolve(__dirname, '../../test/fixtures/semicolon.js');
var starts = 100;
var i = 0;
var start;
var bench = common.createBenchmark(startNode, {
dur: [1]
});
function startNode(conf) {
var dur = +conf.dur;
var go = true;
var starts = 0;
var open = 0;
setTimeout(function() {
go = false;
}, dur * 1000);
bench.start();
start();
function start() {
var node = spawn(process.execPath || process.argv[0], [emptyJsFile]);
node.on('exit', function(exitCode) {
if (exitCode !== 0) {
throw new Error('Error during node startup');
}
starts++;
if (go)
start();
else
bench.end(starts);
});
}
}

View File

@@ -1,16 +0,0 @@
var common = require('../common.js');
var bench = common.createBenchmark(main, {
millions: [100]
})
function main(conf) {
var n = +conf.millions * 1e6;
bench.start();
var s;
for (var i = 0; i < n; i++) {
s = '01234567890';
s[1] = "a";
}
bench.end(n / 1e6);
}

View File

@@ -1,40 +0,0 @@
var common = require('../common.js');
var bench = common.createBenchmark(main, {
thousands: [500],
type: ['depth', 'breadth']
});
function main(conf) {
var n = +conf.thousands * 1e3;
if (conf.type === 'breadth')
breadth(n);
else
depth(n);
}
function depth(N) {
var n = 0;
bench.start();
setTimeout(cb);
function cb() {
n++;
if (n === N)
bench.end(N / 1e3);
else
setTimeout(cb);
}
}
function breadth(N) {
var n = 0;
bench.start();
function cb() {
n++;
if (n === N)
bench.end(N / 1e3);
}
for (var i = 0; i < N; i++) {
setTimeout(cb);
}
}

View File

@@ -1,40 +0,0 @@
var url = require('url')
var n = 25 * 100;
var urls = [
'http://nodejs.org/docs/latest/api/url.html#url_url_format_urlobj',
'http://blog.nodejs.org/',
'https://encrypted.google.com/search?q=url&q=site:npmjs.org&hl=en',
'javascript:alert("node is awesome");',
'some.ran/dom/url.thing?oh=yes#whoo'
];
var paths = [
'../foo/bar?baz=boom',
'foo/bar',
'http://nodejs.org',
'./foo/bar?baz'
];
benchmark('parse()', url.parse);
benchmark('format()', url.format);
paths.forEach(function(p) {
benchmark('resolve("' + p + '")', function(u) {
url.resolve(u, p)
});
});
function benchmark(name, fun) {
var timestamp = process.hrtime();
for (var i = 0; i < n; ++i) {
for (var j = 0, k = urls.length; j < k; ++j) fun(urls[j]);
}
timestamp = process.hrtime(timestamp);
var seconds = timestamp[0];
var nanos = timestamp[1];
var time = seconds + nanos / 1e9;
var rate = n / time;
console.log('misc/url.js %s: %s', name, rate.toPrecision(5));
}

View File

@@ -1,18 +0,0 @@
// compare with "google-chrome deps/v8/benchmarks/run.html"
var fs = require('fs');
var path = require('path');
var vm = require('vm');
var dir = path.join(__dirname, '..', '..', 'deps', 'v8', 'benchmarks');
global.print = function(s) {
if (s === '----') return;
console.log('misc/v8_bench.js %s', s);
};
global.load = function (x) {
var source = fs.readFileSync(path.join(dir, x), 'utf8');
vm.runInThisContext(source, x);
}
load('run.js');

View File

@@ -1,61 +0,0 @@
// test UDP send/recv throughput
var common = require('../common.js');
var PORT = common.PORT;
// `num` is the number of send requests to queue up each time.
// Keep it reasonably high (>10) otherwise you're benchmarking the speed of
// event loop cycles more than anything else.
var bench = common.createBenchmark(main, {
len: [1, 64, 256, 1024],
num: [100],
type: ['send', 'recv'],
dur: [5]
});
var dur;
var len;
var num;
var type;
var chunk;
var encoding;
function main(conf) {
dur = +conf.dur;
len = +conf.len;
num = +conf.num;
type = conf.type;
chunk = new Buffer(len);
server();
}
var dgram = require('dgram');
function server() {
var sent = 0;
var received = 0;
var socket = dgram.createSocket('udp4');
function onsend() {
if (sent++ % num == 0)
for (var i = 0; i < num; i++)
socket.send(chunk, 0, chunk.length, PORT, '127.0.0.1', onsend);
}
socket.on('listening', function() {
bench.start();
onsend();
setTimeout(function() {
var bytes = (type === 'send' ? sent : received) * chunk.length;
var gbits = (bytes * 8) / (1024 * 1024 * 1024);
bench.end(gbits);
}, dur * 1000);
});
socket.on('message', function(buf, rinfo) {
received++;
});
socket.bind(PORT);
}

View File

@@ -1,112 +0,0 @@
// test the speed of .pipe() with sockets
var common = require('../common.js');
var PORT = common.PORT;
var bench = common.createBenchmark(main, {
len: [102400, 1024 * 1024 * 16],
type: ['utf', 'asc', 'buf'],
dur: [5],
});
var dur;
var len;
var type;
var chunk;
var encoding;
function main(conf) {
dur = +conf.dur;
len = +conf.len;
type = conf.type;
switch (type) {
case 'buf':
chunk = new Buffer(len);
chunk.fill('x');
break;
case 'utf':
encoding = 'utf8';
chunk = new Array(len / 2 + 1).join('ü');
break;
case 'asc':
encoding = 'ascii';
chunk = new Array(len + 1).join('x');
break;
default:
throw new Error('invalid type: ' + type);
break;
}
server();
}
var net = require('net');
function Writer() {
this.received = 0;
this.writable = true;
}
Writer.prototype.write = function(chunk, encoding, cb) {
this.received += chunk.length;
if (typeof encoding === 'function')
encoding();
else if (typeof cb === 'function')
cb();
return true;
};
// doesn't matter, never emits anything.
Writer.prototype.on = function() {};
Writer.prototype.once = function() {};
Writer.prototype.emit = function() {};
function Reader() {
this.flow = this.flow.bind(this);
this.readable = true;
}
Reader.prototype.pipe = function(dest) {
this.dest = dest;
this.flow();
return dest;
};
Reader.prototype.flow = function() {
var dest = this.dest;
var res = dest.write(chunk, encoding);
if (!res)
dest.once('drain', this.flow);
else
process.nextTick(this.flow);
};
function server() {
var reader = new Reader();
var writer = new Writer();
// the actual benchmark.
var server = net.createServer(function(socket) {
socket.pipe(writer);
});
server.listen(PORT, function() {
var socket = net.connect(PORT);
socket.on('connect', function() {
bench.start();
reader.pipe(socket);
setTimeout(function() {
var bytes = writer.received;
var gbits = (bytes * 8) / (1024 * 1024 * 1024);
bench.end(gbits);
}, dur * 1000);
});
});
}

View File

@@ -1,115 +0,0 @@
// test the speed of .pipe() with sockets
var common = require('../common.js');
var PORT = common.PORT;
var bench = common.createBenchmark(main, {
len: [102400, 1024 * 1024 * 16],
type: ['utf', 'asc', 'buf'],
dur: [5],
});
var dur;
var len;
var type;
var chunk;
var encoding;
function main(conf) {
dur = +conf.dur;
len = +conf.len;
type = conf.type;
switch (type) {
case 'buf':
chunk = new Buffer(len);
chunk.fill('x');
break;
case 'utf':
encoding = 'utf8';
chunk = new Array(len / 2 + 1).join('ü');
break;
case 'asc':
encoding = 'ascii';
chunk = new Array(len + 1).join('x');
break;
default:
throw new Error('invalid type: ' + type);
break;
}
server();
}
var net = require('net');
function Writer() {
this.received = 0;
this.writable = true;
}
Writer.prototype.write = function(chunk, encoding, cb) {
this.received += chunk.length;
if (typeof encoding === 'function')
encoding();
else if (typeof cb === 'function')
cb();
return true;
};
// doesn't matter, never emits anything.
Writer.prototype.on = function() {};
Writer.prototype.once = function() {};
Writer.prototype.emit = function() {};
function Reader() {
this.flow = this.flow.bind(this);
this.readable = true;
}
Reader.prototype.pipe = function(dest) {
this.dest = dest;
this.flow();
return dest;
};
Reader.prototype.flow = function() {
var dest = this.dest;
var res = dest.write(chunk, encoding);
if (!res)
dest.once('drain', this.flow);
else
process.nextTick(this.flow);
};
function server() {
var reader = new Reader();
var writer = new Writer();
// the actual benchmark.
var server = net.createServer(function(socket) {
socket.pipe(socket);
});
server.listen(PORT, function() {
var socket = net.connect(PORT);
socket.on('connect', function() {
bench.start();
reader.pipe(socket);
socket.pipe(writer);
setTimeout(function() {
// multiply by 2 since we're sending it first one way
// then then back again.
var bytes = writer.received * 2;
var gbits = (bytes * 8) / (1024 * 1024 * 1024);
bench.end(gbits);
}, dur * 1000);
});
});
}

View File

@@ -1,112 +0,0 @@
// test the speed of .pipe() with sockets
var common = require('../common.js');
var PORT = common.PORT;
var bench = common.createBenchmark(main, {
len: [102400, 1024 * 1024 * 16],
type: ['utf', 'asc', 'buf'],
dur: [5]
});
var dur;
var len;
var type;
var chunk;
var encoding;
function main(conf) {
dur = +conf.dur;
len = +conf.len;
type = conf.type;
switch (type) {
case 'buf':
chunk = new Buffer(len);
chunk.fill('x');
break;
case 'utf':
encoding = 'utf8';
chunk = new Array(len / 2 + 1).join('ü');
break;
case 'asc':
encoding = 'ascii';
chunk = new Array(len + 1).join('x');
break;
default:
throw new Error('invalid type: ' + type);
break;
}
server();
}
var net = require('net');
function Writer() {
this.received = 0;
this.writable = true;
}
Writer.prototype.write = function(chunk, encoding, cb) {
this.received += chunk.length;
if (typeof encoding === 'function')
encoding();
else if (typeof cb === 'function')
cb();
return true;
};
// doesn't matter, never emits anything.
Writer.prototype.on = function() {};
Writer.prototype.once = function() {};
Writer.prototype.emit = function() {};
function Reader() {
this.flow = this.flow.bind(this);
this.readable = true;
}
Reader.prototype.pipe = function(dest) {
this.dest = dest;
this.flow();
return dest;
};
Reader.prototype.flow = function() {
var dest = this.dest;
var res = dest.write(chunk, encoding);
if (!res)
dest.once('drain', this.flow);
else
process.nextTick(this.flow);
};
function server() {
var reader = new Reader();
var writer = new Writer();
// the actual benchmark.
var server = net.createServer(function(socket) {
reader.pipe(socket);
});
server.listen(PORT, function() {
var socket = net.connect(PORT);
socket.on('connect', function() {
bench.start();
socket.pipe(writer);
setTimeout(function() {
var bytes = writer.received;
var gbits = (bytes * 8) / (1024 * 1024 * 1024);
bench.end(gbits);
}, dur * 1000);
});
});
}

View File

@@ -1,136 +0,0 @@
// In this benchmark, we connect a client to the server, and write
// as many bytes as we can in the specified time (default = 10s)
var common = require('../common.js');
// if there are --dur=N and --len=N args, then
// run the function with those settings.
// if not, then queue up a bunch of child processes.
var bench = common.createBenchmark(main, {
len: [102400, 1024 * 1024 * 16],
type: ['utf', 'asc', 'buf'],
dur: [5]
});
var TCP = process.binding('tcp_wrap').TCP;
var PORT = common.PORT;
var dur;
var len;
var type;
function main(conf) {
dur = +conf.dur;
len = +conf.len;
type = conf.type;
server();
}
function fail(syscall) {
var e = new Error(syscall + ' ' + errno);
e.errno = e.code = errno;
e.syscall = syscall;
throw e;
}
function server() {
var serverHandle = new TCP();
var r = serverHandle.bind('127.0.0.1', PORT);
if (r)
fail('bind');
var r = serverHandle.listen(511);
if (r)
fail('listen');
serverHandle.onconnection = function(clientHandle) {
if (!clientHandle)
fail('connect');
// the meat of the benchmark is right here:
bench.start();
var bytes = 0;
setTimeout(function() {
// report in Gb/sec
bench.end((bytes * 8) / (1024 * 1024 * 1024));
}, dur * 1000);
clientHandle.onread = function(buffer, offset, length) {
// we're not expecting to ever get an EOF from the client.
// just lots of data forever.
if (!buffer)
fail('read');
// don't slice the buffer. the point of this is to isolate, not
// simulate real traffic.
// var chunk = buffer.slice(offset, offset + length);
bytes += length;
};
clientHandle.readStart();
};
client();
}
function client() {
var chunk;
switch (type) {
case 'buf':
chunk = new Buffer(len);
chunk.fill('x');
break;
case 'utf':
chunk = new Array(len / 2 + 1).join('ü');
break;
case 'asc':
chunk = new Array(len + 1).join('x');
break;
default:
throw new Error('invalid type: ' + type);
break;
}
var clientHandle = new TCP();
var connectReq = clientHandle.connect('127.0.0.1', PORT);
if (!connectReq)
fail('connect');
clientHandle.readStart();
connectReq.oncomplete = function() {
while (clientHandle.writeQueueSize === 0)
write();
};
function write() {
var writeReq
switch (type) {
case 'buf':
writeReq = clientHandle.writeBuffer(chunk);
break;
case 'utf':
writeReq = clientHandle.writeUtf8String(chunk);
break;
case 'asc':
writeReq = clientHandle.writeAsciiString(chunk);
break;
}
if (!writeReq)
fail('write');
writeReq.oncomplete = afterWrite;
}
function afterWrite(status, handle, req) {
if (status)
fail('write');
while (clientHandle.writeQueueSize === 0)
write();
}
}

View File

@@ -1,149 +0,0 @@
// In this benchmark, we connect a client to the server, and write
// as many bytes as we can in the specified time (default = 10s)
var common = require('../common.js');
// if there are --dur=N and --len=N args, then
// run the function with those settings.
// if not, then queue up a bunch of child processes.
var bench = common.createBenchmark(main, {
len: [102400, 1024 * 1024 * 16],
type: ['utf', 'asc', 'buf'],
dur: [5]
});
var TCP = process.binding('tcp_wrap').TCP;
var PORT = common.PORT;
var dur;
var len;
var type;
function main(conf) {
dur = +conf.dur;
len = +conf.len;
type = conf.type;
server();
}
function fail(syscall) {
var e = new Error(syscall + ' ' + errno);
e.errno = e.code = errno;
e.syscall = syscall;
throw e;
}
function server() {
var serverHandle = new TCP();
var r = serverHandle.bind('127.0.0.1', PORT);
if (r)
fail('bind');
var r = serverHandle.listen(511);
if (r)
fail('listen');
serverHandle.onconnection = function(clientHandle) {
if (!clientHandle)
fail('connect');
clientHandle.onread = function(buffer, offset, length) {
// we're not expecting to ever get an EOF from the client.
// just lots of data forever.
if (!buffer)
fail('read');
var chunk = buffer.slice(offset, offset + length);
var writeReq = clientHandle.writeBuffer(chunk);
if (!writeReq)
fail('write');
writeReq.oncomplete = function(status, handle, req) {
if (status)
fail('write');
};
};
clientHandle.readStart();
};
client();
}
function client() {
var chunk;
switch (type) {
case 'buf':
chunk = new Buffer(len);
chunk.fill('x');
break;
case 'utf':
chunk = new Array(len / 2 + 1).join('ü');
break;
case 'asc':
chunk = new Array(len + 1).join('x');
break;
default:
throw new Error('invalid type: ' + type);
break;
}
var clientHandle = new TCP();
var connectReq = clientHandle.connect('127.0.0.1', PORT);
var bytes = 0;
if (!connectReq)
fail('connect');
clientHandle.readStart();
clientHandle.onread = function(buffer, start, length) {
if (!buffer)
fail('read');
bytes += length;
};
connectReq.oncomplete = function() {
bench.start();
setTimeout(function() {
// multiply by 2 since we're sending it first one way
// then then back again.
bench.end(2 * (bytes * 8) / (1024 * 1024 * 1024));
}, dur * 1000);
while (clientHandle.writeQueueSize === 0)
write();
};
function write() {
var writeReq
switch (type) {
case 'buf':
writeReq = clientHandle.writeBuffer(chunk);
break;
case 'utf':
writeReq = clientHandle.writeUtf8String(chunk);
break;
case 'asc':
writeReq = clientHandle.writeAsciiString(chunk);
break;
}
if (!writeReq)
fail('write');
writeReq.oncomplete = afterWrite;
}
function afterWrite(status, handle, req) {
if (status)
fail('write');
while (clientHandle.writeQueueSize === 0)
write();
}
}

View File

@@ -1,136 +0,0 @@
// In this benchmark, we connect a client to the server, and write
// as many bytes as we can in the specified time (default = 10s)
var common = require('../common.js');
// if there are dur=N and len=N args, then
// run the function with those settings.
// if not, then queue up a bunch of child processes.
var bench = common.createBenchmark(main, {
len: [102400, 1024 * 1024 * 16],
type: ['utf', 'asc', 'buf'],
dur: [5]
});
var TCP = process.binding('tcp_wrap').TCP;
var PORT = common.PORT;
var dur;
var len;
var type;
function main(conf) {
dur = +conf.dur;
len = +conf.len;
type = conf.type;
server();
}
function fail(syscall) {
var e = new Error(syscall + ' ' + errno);
e.errno = e.code = errno;
e.syscall = syscall;
throw e;
}
function server() {
var serverHandle = new TCP();
var r = serverHandle.bind('127.0.0.1', PORT);
if (r)
fail('bind');
var r = serverHandle.listen(511);
if (r)
fail('listen');
serverHandle.onconnection = function(clientHandle) {
if (!clientHandle)
fail('connect');
var chunk;
switch (type) {
case 'buf':
chunk = new Buffer(len);
chunk.fill('x');
break;
case 'utf':
chunk = new Array(len / 2 + 1).join('ü');
break;
case 'asc':
chunk = new Array(len + 1).join('x');
break;
default:
throw new Error('invalid type: ' + type);
break;
}
clientHandle.readStart();
while (clientHandle.writeQueueSize === 0)
write();
function write() {
var writeReq
switch (type) {
case 'buf':
writeReq = clientHandle.writeBuffer(chunk);
break;
case 'utf':
writeReq = clientHandle.writeUtf8String(chunk);
break;
case 'asc':
writeReq = clientHandle.writeAsciiString(chunk);
break;
}
if (!writeReq)
fail('write');
writeReq.oncomplete = afterWrite;
}
function afterWrite(status, handle, req) {
if (status)
fail('write');
while (clientHandle.writeQueueSize === 0)
write();
}
};
client();
}
function client() {
var clientHandle = new TCP();
var connectReq = clientHandle.connect('127.0.0.1', PORT);
if (!connectReq)
fail('connect');
connectReq.oncomplete = function() {
var bytes = 0;
clientHandle.onread = function(buffer, offset, length) {
// we're not expecting to ever get an EOF from the client.
// just lots of data forever.
if (!buffer)
fail('read');
// don't slice the buffer. the point of this is to isolate, not
// simulate real traffic.
// var chunk = buffer.slice(offset, offset + length);
bytes += length;
};
clientHandle.readStart();
// the meat of the benchmark is right here:
bench.start();
setTimeout(function() {
// report in Gb/sec
bench.end((bytes * 8) / (1024 * 1024 * 1024));
}, dur * 1000);
};
}

19
benchmark/process_loop.js Normal file
View File

@@ -0,0 +1,19 @@
var util = require("util"),
childProcess = require("child_process");
function next (i) {
if (i <= 0) return;
var child = childProcess.spawn("echo", ["hello"]);
child.stdout.addListener("data", function (chunk) {
util.print(chunk);
});
child.addListener("exit", function (code) {
if (code != 0) process.exit(-1);
next(i - 1);
});
}
next(500);

31
benchmark/run.js Normal file
View File

@@ -0,0 +1,31 @@
var path = require("path");
var util = require("util");
var childProcess = require("child_process");
var benchmarks = [ "timers.js"
, "process_loop.js"
, "static_http_server.js"
];
var benchmarkDir = path.dirname(__filename);
function exec (script, callback) {
var start = new Date();
var child = childProcess.spawn(process.argv[0], [path.join(benchmarkDir, script)]);
child.addListener("exit", function (code) {
var elapsed = new Date() - start;
callback(elapsed, code);
});
}
function runNext (i) {
if (i >= benchmarks.length) return;
util.print(benchmarks[i] + ": ");
exec(benchmarks[i], function (elapsed, code) {
if (code != 0) {
console.log("ERROR ");
}
console.log(elapsed);
runNext(i+1);
});
};
runNext(0);

15
benchmark/settimeout.js Normal file
View File

@@ -0,0 +1,15 @@
console.log("wait...");
var done = 0;
var N = 5000000;
var begin = new Date();
for (var i = 0; i < N; i++) {
setTimeout(function () {
if (++done == N) {
var end = new Date();
console.log("smaller is better");
console.log("startup: %d", start - begin);
console.log("done: %d", end - start);
}
}, 1000);
}
var start = new Date();

26
benchmark/startup.js Normal file
View File

@@ -0,0 +1,26 @@
var spawn = require('child_process').spawn,
path = require('path'),
emptyJsFile = path.join(__dirname, '../test/fixtures/semicolon.js'),
starts = 100,
i = 0,
start;
function startNode() {
var node = spawn(process.execPath || process.argv[0], [emptyJsFile]);
node.on('exit', function(exitCode) {
if (exitCode !== 0) {
throw new Error('Error during node startup');
}
i++;
if (i < starts) {
startNode();
} else{
var duration = +new Date - start;
console.log('Started node %d times in %s ms. %d ms / start.', starts, duration, duration / starts);
}
});
}
start = +new Date;
startNode();

View File

@@ -1,44 +1,48 @@
var http = require('http');
var http = require("http");
var concurrency = 30;
var port = 12346;
var n = 700;
var n = 7; // several orders of magnitude slower
var bytes = 1024*5;
var requests = 0;
var responses = 0;
var body = '';
var body = "";
for (var i = 0; i < bytes; i++) {
body += 'C';
body += "C";
}
var server = http.createServer(function(req, res) {
var server = http.createServer(function (req, res) {
res.writeHead(200, {
'Content-Type': 'text/plain',
'Content-Length': body.length
"Content-Type": "text/plain",
"Content-Length": body.length
});
res.end(body);
res.write(body);
res.close();
})
server.listen(port);
server.listen(port, function() {
var agent = new http.Agent();
agent.maxSockets = concurrency;
function responseListener (res) {
res.addListener("end", function () {
if (requests < n) {
var req = res.client.request("/");
req.addListener('response', responseListener);
req.close();
requests++;
}
for (var i = 0; i < n; i++) {
var req = http.get({
port: port,
path: '/',
agent: agent
}, function(res) {
res.resume();
res.on('end', function() {
if (++responses === n) {
server.close();
}
});
});
req.id = i;
requests++;
}
});
if (++responses == n) {
server.close();
}
});
}
for (var i = 0; i < concurrency; i++) {
var client = http.createClient(port);
client.id = i;
var req = client.request("/");
req.addListener('response', responseListener);
req.close();
requests++;
}

View File

@@ -0,0 +1,6 @@
for (var i = 0; i < 9e7; i++) {
s = '01234567890';
s[1] = "a";
}

5
benchmark/timers.js Normal file
View File

@@ -0,0 +1,5 @@
function next (i) {
if (i <= 0) return;
setTimeout(function () { next(i-1); }, 1);
}
next(700);

View File

@@ -1,74 +0,0 @@
var common = require('../common.js');
var bench = common.createBenchmark(main, {
dur: [5],
type: ['buf', 'asc', 'utf'],
size: [2, 1024, 1024 * 1024]
});
var dur, type, encoding, size;
var server;
var path = require('path');
var fs = require('fs');
var cert_dir = path.resolve(__dirname, '../../test/fixtures');
var options;
var tls = require('tls');
function main(conf) {
dur = +conf.dur;
type = conf.type;
size = +conf.size;
var chunk;
switch (type) {
case 'buf':
chunk = new Buffer(size);
chunk.fill('b');
break;
case 'asc':
chunk = new Array(size + 1).join('a');
encoding = 'ascii';
break;
case 'utf':
chunk = new Array(size/2 + 1).join('ü');
encoding = 'utf8';
break;
default:
throw new Error('invalid type');
}
options = { key: fs.readFileSync(cert_dir + '/test_key.pem'),
cert: fs.readFileSync(cert_dir + '/test_cert.pem'),
ca: [ fs.readFileSync(cert_dir + '/test_ca.pem') ] };
server = tls.createServer(options, onConnection);
setTimeout(done, dur * 1000);
server.listen(common.PORT, function() {
var opt = { port: common.PORT, rejectUnauthorized: false };
var conn = tls.connect(opt, function() {
bench.start();
conn.on('drain', write);
write();
});
function write() {
var i = 0;
while (false !== conn.write(chunk, encoding));
}
});
var received = 0;
function onConnection(conn) {
conn.on('data', function(chunk) {
received += chunk.length;
});
}
function done() {
var mbits = (received * 8) / (1024 * 1024);
bench.end(mbits);
conn.destroy();
server.close();
}
}

View File

@@ -1,63 +0,0 @@
var assert = require('assert'),
fs = require('fs'),
path = require('path'),
tls = require('tls');
var common = require('../common.js');
var bench = common.createBenchmark(main, {
concurrency: [1, 10],
dur: [5]
});
var clientConn = 0;
var serverConn = 0;
var server;
var dur;
var concurrency;
var running = true;
function main(conf) {
dur = +conf.dur;
concurrency = +conf.concurrency;
var cert_dir = path.resolve(__dirname, '../../test/fixtures'),
options = { key: fs.readFileSync(cert_dir + '/test_key.pem'),
cert: fs.readFileSync(cert_dir + '/test_cert.pem'),
ca: [ fs.readFileSync(cert_dir + '/test_ca.pem') ] };
server = tls.createServer(options, onConnection);
server.listen(common.PORT, onListening);
}
function onListening() {
setTimeout(done, dur * 1000);
bench.start();
for (var i = 0; i < concurrency; i++)
makeConnection();
}
function onConnection(conn) {
serverConn++;
}
function makeConnection() {
var conn = tls.connect({ port: common.PORT,
rejectUnauthorized: false }, function() {
clientConn++;
conn.on('error', function(er) {
console.error('client error', er);
throw er;
});
conn.end();
if (running) makeConnection();
});
}
function done() {
running = false;
// it's only an established connection if they both saw it.
// because we destroy the server somewhat abruptly, these
// don't always match. Generally, serverConn will be
// the smaller number, but take the min just to be sure.
bench.end(Math.min(serverConn, clientConn));
}

15
benchmark/v8_bench.js Normal file
View File

@@ -0,0 +1,15 @@
// compare with "google-chrome deps/v8/benchmarks/run.html"
var fs = require('fs');
var path = require('path');
var vm = require('vm');
var dir = path.join(__dirname, '..', 'deps', 'v8', 'benchmarks');
global.print = console.log;
global.load = function (x) {
var source = fs.readFileSync(path.join(dir, x), 'utf8');
vm.runInThisContext(source, x);
}
load('run.js');

4
cmake/CTestCustom.cmake Normal file
View File

@@ -0,0 +1,4 @@
set(CTEST_CUSTOM_PRE_TEST "sh -c \"rm -rf ../test/tmp && mkdir ../test/tmp\"")
set(CTEST_CUSTOM_POST_TEST ${CTEST_CUSTOM_PRE_TEST})
set(CTEST_CUSTOM_PRE_MEMCHECK ${CTEST_CUSTOM_PRE_TEST})
set(CTEST_CUSTOM_POST_MEMCHECK ${CTEST_CUSTOM_PRE_TEST})

View File

@@ -0,0 +1,22 @@
set(toolchain_dir #SET THIS TO YOUR TOOLCHAIN PATH)
set(toolchain_bin_dir ${toolchain_dir}/bin)
set(toolchain_libc_dir ${toolchain_dir}/arm-none-linux-gnueabi/libc)
set(toolchain_inc_dir ${toolchain_libc_dir}/include)
set(toolchain_lib_dir ${toolchain_libc_dir}/usr/lib)
set(CMAKE_SYSTEM_NAME Linux CACHE INTERNAL "system name")
set(CMAKE_SYSTEM_PROCESSOR arm CACHE INTERNAL "processor")
set(CMAKE_C_COMPILER ${toolchain_bin_dir}/arm-none-linux-gnueabi-gcc)
set(CMAKE_CXX_COMPILER ${toolchain_bin_dir}/arm-none-linux-gnueabi-g++)
set(CMAKE_C_FLAGS "-isystem ${toolchain_inc_dir}" CACHE INTERNAL "c compiler flags")
set(CMAKE_CXX_FLAGS "-isystem ${toolchain_inc_dir}" CACHE INTERNAL "cxx compiler flags")
set(link_flags -L${toolchain_lib_dir})
set(CMAKE_EXE_LINKER_FLAGS ${link_flags} CACHE INTERNAL "exe link flags")
set(CMAKE_MODULE_LINKER_FLAGS ${link_flags} CACHE INTERNAL "module link flags")
set(CMAKE_SHARED_LINKER_FLAGS ${link_flags} CACHE INTERNAL "shared lnk flags")
set(CMAKE_FIND_ROOT_PATH ${toolchain_libc_dir} CACHE INTERNAL "cross root directory")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH CACHE INTERNAL "")
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY CACHE INTERNAL "")
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY CACHE INTERNAL "")

114
cmake/configure.cmake Normal file
View File

@@ -0,0 +1,114 @@
#
# configure node for building
#
include(CheckFunctionExists)
if(NOT "v${CMAKE_BUILD_TYPE}" MATCHES vDebug)
set(CMAKE_BUILD_TYPE "Release")
endif()
string(TOLOWER ${CMAKE_SYSTEM_NAME} node_platform)
if(${node_platform} MATCHES darwin)
execute_process(COMMAND sw_vers -productVersion OUTPUT_VARIABLE OSX_VERSION)
string(REGEX REPLACE "^([0-9]+\\.[0-9]+).*$" "\\1" OSX_VERSION "${OSX_VERSION}")
if(OSX_VERSION GREATER 10.5)
# 10.6 builds are 64-bit
set(CMAKE_SYSTEM_PROCESSOR x86_64)
endif()
endif()
# Get system architecture
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES i686*)
set(node_arch x86)
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES i386*)
set(node_arch x86)
else()
set(node_arch ${CMAKE_SYSTEM_PROCESSOR})
endif()
if(${node_arch} MATCHES unknown)
set(node_arch x86)
endif()
set(NODE_INCLUDE_PREFIX ${CMAKE_INSTALL_PREFIX})
# Copy tools directory for out-of-source build
string(COMPARE EQUAL $(PROJECT_BINARY_DIR) ${PROJECT_SOURCE_DIR} in_source_build)
if(NOT in_source_build)
execute_process(COMMAND cmake -E copy_directory ${PROJECT_SOURCE_DIR}/tools ${PROJECT_BINARY_DIR}/tools)
configure_file(${PROJECT_SOURCE_DIR}/deps/v8/tools/jsmin.py ${PROJECT_BINARY_DIR}/tools COPYONLY)
endif()
# Set some compiler/linker flags..
set(CMAKE_C_FLAGS_DEBUG "-O0 -Wall -g -Wextra -DDEBUG $ENV{CFLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -Wall -g -Wextra -DDEBUG $ENV{CXXFLAGS}")
set(CMAKE_C_FLAGS_RELEASE "-g -O3 -DNDEBUG $ENV{CFLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 -DNDEBUG $ENV{CXXFLAGS}")
if(NOT ${node_platform} MATCHES windows)
add_definitions(-D__POSIX__=1)
endif()
if(${node_platform} MATCHES sunos)
add_definitions(-threads)
elseif(NOT ${node_platform} MATCHES cygwin*)
add_definitions(-pthread)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -rdynamic")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread")
endif()
if(${node_platform} MATCHES darwin)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework Carbon")
# explicitly set this so that we don't check again when building libeio
set(HAVE_FDATASYNC 0)
else()
# OSX fdatasync() check wrong: http://public.kitware.com/Bug/view.php?id=10044
check_function_exists(fdatasync HAVE_FDATASYNC)
endif()
if(HAVE_FDATASYNC)
add_definitions(-DHAVE_FDATASYNC=1)
else()
add_definitions(-DHAVE_FDATASYNC=0)
endif()
if(DTRACE)
if(NOT ${node_platform} MATCHES sunos)
message(FATAL_ERROR "DTrace support only currently available on Solaris")
endif()
find_program(dtrace_bin dtrace)
if(NOT dtrace_bin)
message(FATAL_ERROR "DTrace binary not found")
endif()
add_definitions(-DHAVE_DTRACE=1)
endif()
add_definitions(
-DPLATFORM="${node_platform}"
-DX_STACKSIZE=65536
-D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64
-DEV_MULTIPLICITY=0
-D_FORTIFY_SOURCE=2
)
# set the exec output path to be compatible with the current waf build system
if(${CMAKE_BUILD_TYPE} MATCHES Debug)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/debug/)
else()
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/default/)
endif()
#
## ---------------------------------------------------------
#
file(GLOB js2c_files ${PROJECT_SOURCE_DIR}/lib/*.js)
set(js2c_files ${PROJECT_SOURCE_DIR}/src/node.js ${js2c_files})
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/src)

80
cmake/docs.cmake Normal file
View File

@@ -0,0 +1,80 @@
#
# docs
#
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/doc)
set(node_binary ${PROJECT_BINARY_DIR}/default/node)
set(doctool tools/doctool/doctool.js)
set(changelog_html ${PROJECT_BINARY_DIR}/doc/changelog.html)
file(GLOB_RECURSE doc_sources RELATIVE ${PROJECT_SOURCE_DIR} doc/*)
foreach(FILE ${doc_sources})
string(REGEX REPLACE "(.*)api_assets(.*)" "\\1api/assets\\2" OUT_FILE ${FILE})
add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/${OUT_FILE}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_SOURCE_DIR}/${FILE} ${PROJECT_BINARY_DIR}/${OUT_FILE}
DEPENDS ${PROJECT_SOURCE_DIR}/${FILE}
)
list(APPEND doc_sources_copy ${PROJECT_BINARY_DIR}/${OUT_FILE})
endforeach()
file(GLOB_RECURSE api_markdown RELATIVE ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/doc/api/*)
foreach(file ${api_markdown})
string(REGEX REPLACE "(.*)\\.markdown" "\\1" tmp ${file})
set(api_basenames ${api_basenames} ${tmp})
endforeach()
foreach(api ${api_basenames})
set(api_html ${api_html} ${PROJECT_BINARY_DIR}/${api}.html)
add_custom_command(
OUTPUT "${PROJECT_BINARY_DIR}/${api}.html"
COMMAND ${node_binary} ${doctool} ${PROJECT_BINARY_DIR}/doc/template.html "${PROJECT_BINARY_DIR}/${api}.markdown" > "${PROJECT_BINARY_DIR}/${api}.html"
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
DEPENDS node ${doctool} ${doc_sources_copy}
VERBATIM
)
endforeach()
add_custom_target(
doc
DEPENDS node ${doc_sources_copy} ${api_html} ${changelog_html}
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
)
#add_custom_command(
# OUTPUT ${PROJECT_BINARY_DIR}/doc/api.html
# COMMAND ${PROJECT_BINARY_DIR}/default/node tools/ronnjs/bin/ronn.js --fragment doc/api.markdown
# | sed "s/<h2>\\\(.*\\\)<\\/h2>/<h2 id=\"\\1\">\\1<\\/h2>/g"
# | cat doc/api_header.html - doc/api_footer.html > ${PROJECT_BINARY_DIR}/doc/api.html
# WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
# DEPENDS node doc/api.markdown doc/api_header.html doc/api_footer.html
# VERBATIM
# )
add_custom_command(
OUTPUT ${changelog_html}
COMMAND ${node_binary} ${doctool} doc/template.html ChangeLog
| sed "s|assets/|api/assets/|g"
| sed "s|<body>|<body id=\"changelog\">|g" > ${changelog_html}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
DEPENDS ChangeLog node ${doctool} ${doc_sources_copy}
VERBATIM
)
#add_custom_command(
# OUTPUT ${PROJECT_BINARY_DIR}/doc/changelog.html
# COMMAND cat doc/changelog_header.html ChangeLog doc/changelog_footer.html > ${PROJECT_BINARY_DIR}/doc/changelog.html
# WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
# DEPENDS ChangeLog doc/changelog_header.html doc/changelog_footer.html
# VERBATIM
# )
#add_custom_command(
# OUTPUT ${PROJECT_BINARY_DIR}/doc/node.1
# COMMAND ${PROJECT_BINARY_DIR}/default/node tools/ronnjs/bin/ronn.js --roff doc/api.markdown > ${PROJECT_BINARY_DIR}/doc/node.1
# WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
# DEPENDS node doc/api.markdown tools/ronnjs/bin/ronn.js
# VERBATIM
# )

18
cmake/libc-ares.cmake Normal file
View File

@@ -0,0 +1,18 @@
if(SHARED_CARES)
find_library(LIBCARES_LIBRARY NAMES cares)
find_path(LIBCARES_INCLUDE_DIR ares.h
PATH_SUFFIXES include
) # Find header
find_package_handle_standard_args(libcares DEFAULT_MSG LIBCARES_LIBRARY LIBCARES_INCLUDE_DIR)
else()
set(cares_arch ${node_arch})
if(${node_arch} MATCHES x86_64)
set(cares_arch x64)
elseif(${node_arch} MATCHES x86)
set(cares_arch ia32)
endif()
add_subdirectory(deps/c-ares)
set(LIBCARES_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/deps/c-ares ${CMAKE_SOURCE_DIR}/deps/c-ares/${node_platform}-${cares_arch})
endif()

10
cmake/libev.cmake Normal file
View File

@@ -0,0 +1,10 @@
if(SHARED_LIBEV)
find_library(LIBEV_LIBRARY NAMES ev)
find_path(LIBEV_INCLUDE_DIR ev.h
PATH_SUFFIXES include/ev include
) # Find header
find_package_handle_standard_args(libev DEFAULT_MSG LIBEV_LIBRARY LIBEV_INCLUDE_DIR)
else()
add_subdirectory(deps/libev)
set(LIBEV_INCLUDE_DIR deps/libev)
endif()

55
cmake/libs.cmake Normal file
View File

@@ -0,0 +1,55 @@
#
# libraries
#
include(CheckLibraryExists)
include(FindPackageHandleStandardArgs)
set(HAVE_CONFIG_H True)
add_definitions(-DHAVE_CONFIG_H=1)
find_package(OpenSSL QUIET)
find_package(Threads)
find_library(RT rt)
find_library(DL dl)
check_library_exists(socket socket "" HAVE_SOCKET_LIB)
check_library_exists(nsl gethostbyname "" HAVE_NSL_LIB)
check_library_exists(util openpty "" HAVE_UTIL_LIB)
if(RT)
set(extra_libs ${extra_libs} ${RT})
endif()
if(DL)
set(extra_libs ${extra_libs} ${DL})
endif()
if(${node_platform} MATCHES freebsd)
find_library(KVM NAMES kvm)
set(extra_libs ${extra_libs} KVM)
endif()
if(${HAVE_SOCKET_LIB})
set(extra_libs ${extra_libs} socket)
endif()
if(${HAVE_NSL_LIB})
set(extra_libs ${extra_libs} nsl)
endif()
if(HAVE_UTIL_LIB)
set(extra_libs ${extra_libs} util)
endif()
if(OPENSSL_FOUND)
add_definitions(-DHAVE_OPENSSL=1)
set(HAVE_OPENSSL True)
set(node_extra_src ${node_extra_src} src/node_crypto.cc)
set(extra_libs ${extra_libs} ${OPENSSL_LIBRARIES})
endif()
include("cmake/libc-ares.cmake")
include("cmake/libev.cmake")
include("cmake/libv8.cmake")
add_subdirectory(deps/libeio)
add_subdirectory(deps/http_parser)

25
cmake/libv8.cmake Normal file
View File

@@ -0,0 +1,25 @@
set(V8_INCLUDE_NAMES v8.h v8-debug.h v8-profiler.h v8stdint.h)
set(V8_LIBRARY_NAMES v8)
if(SHARED_V8)
find_path(V8_INCLUDE_DIR NAMES ${V8_INCLUDE_NAMES})
find_library(V8_LIBRARY_PATH NAMES ${V8_LIBRARY_NAMES} NO_CMAKE_PATH)
else()
set(V8_INCLUDE_DIR "${PROJECT_BINARY_DIR}/deps/v8/include")
if(${CMAKE_BUILD_TYPE} MATCHES Debug)
set(v8_fn "libv8_g.a")
else()
set(v8_fn "libv8.a")
endif()
set(V8_LIBRARY_PATH "${PROJECT_BINARY_DIR}/deps/v8/${v8_fn}")
install(DIRECTORY
## Do NOT remove the trailing slash
## it is required so that v8 headers are
## copied directly into include/node
## rather than in a subdirectory
## See CMake's install(DIRECTORY) manual for details
${V8_INCLUDE_DIR}/
DESTINATION include/node
)
endif()

146
cmake/node_build.cmake Normal file
View File

@@ -0,0 +1,146 @@
#
# node build stuff
#
set(macros_file ${PROJECT_BINARY_DIR}/macros.py)
# replace debug(x) and assert(x) with nothing in release build
if(${CMAKE_BUILD_TYPE} MATCHES Release)
file(APPEND ${macros_file} "macro debug(x) = void(0);\n")
file(APPEND ${macros_file} "macro assert(x) = void(0);\n")
endif()
if(NOT DTRACE)
set(dtrace_probes
DTRACE_HTTP_CLIENT_REQUEST
DTRACE_HTTP_CLIENT_RESPONSE
DTRACE_HTTP_SERVER_REQUEST
DTRACE_HTTP_SERVER_RESPONSE
DTRACE_NET_SERVER_CONNECTION
DTRACE_NET_STREAM_END
DTRACE_NET_SOCKET_READ
DTRACE_NET_SOCKET_WRITE)
foreach(probe ${dtrace_probes})
file(APPEND ${macros_file} "macro ${probe}(x) = void(0);\n")
endforeach()
endif()
# Sort the JS files being built into natives so that the build is
# deterministic
list(SORT js2c_files)
# include macros file in generation
set(js2c_files ${js2c_files} ${macros_file})
add_custom_command(
OUTPUT ${PROJECT_BINARY_DIR}/src/node_natives.h
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_BINARY_DIR}/tools/js2c.py ${PROJECT_BINARY_DIR}/src/node_natives.h ${js2c_files}
DEPENDS ${js2c_files})
set(node_platform_src "src/platform_${node_platform}.cc")
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/${node_platform_src})
set(node_extra_src ${node_extra_src} "src/platform_none.cc")
else()
set(node_extra_src ${node_extra_src} ${node_platform_src})
endif()
set(node_sources
src/node_main.cc
src/node.cc
src/node_buffer.cc
src/node_javascript.cc
src/node_extensions.cc
src/node_http_parser.cc
src/node_net.cc
src/node_io_watcher.cc
src/node_child_process.cc
src/node_constants.cc
src/node_cares.cc
src/node_events.cc
src/node_file.cc
src/node_signal_watcher.cc
src/node_stat_watcher.cc
src/node_stdio.cc
src/node_timer.cc
src/node_script.cc
src/node_os.cc
src/node_dtrace.cc
src/node_string.cc
src/node_natives.h
${node_extra_src})
# Set up PREFIX, CCFLAGS, and CPPFLAGS for node_config.h
set(PREFIX ${CMAKE_INSTALL_PREFIX})
if(${CMAKE_BUILD_TYPE} MATCHES Debug)
set(CCFLAGS "${CMAKE_C_FLAGS_DEBUG} ${CMAKE_C_FLAGS}")
else()
set(CCFLAGS "${CMAKE_C_FLAGS_RELEASE} ${CMAKE_C_FLAGS}")
endif()
get_directory_property(compile_defs COMPILE_DEFINITIONS)
foreach(def ${compile_defs})
set(CPPFLAGS "${CPPFLAGS} -D${def}")
endforeach()
configure_file(src/node_config.h.in ${PROJECT_BINARY_DIR}/src/node_config.h ESCAPE_QUOTES)
configure_file(config.h.cmake ${PROJECT_BINARY_DIR}/config.h)
include_directories(
src
deps/libeio
deps/http_parser
${V8_INCLUDE_DIR}
${LIBEV_INCLUDE_DIR}
${LIBCARES_INCLUDE_DIR}
${PROJECT_BINARY_DIR}
${PROJECT_BINARY_DIR}/src
)
if(DTRACE)
add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src/node_provider.h
COMMAND ${dtrace_bin} -x nolibs -h -o ${PROJECT_BINARY_DIR}/src/node_provider.h -s ${PROJECT_SOURCE_DIR}/src/node_provider.d
DEPENDS ${PROJECT_SOURCE_DIR}/src/node_provider.d)
set(node_sources ${node_sources} src/node_provider.o)
set(node_sources src/node_provider.h ${node_sources})
endif()
add_executable(node ${node_sources})
set_target_properties(node PROPERTIES DEBUG_POSTFIX "_g")
target_link_libraries(node
ev
eio
cares
http_parser
${V8_LIBRARY_PATH}
${CMAKE_THREAD_LIBS_INIT}
${extra_libs})
if(DTRACE)
# manually gather up the object files for dtrace
get_property(sourcefiles TARGET node PROPERTY SOURCES)
foreach(src_file ${sourcefiles})
if(src_file MATCHES ".*\\.cc$")
set(node_objs ${node_objs} ${PROJECT_BINARY_DIR}/CMakeFiles/node.dir/${src_file}.o)
endif()
endforeach()
add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src/node_provider.o
#COMMAND cmake -E echo ${node_objs}
COMMAND ${dtrace_bin} -G -x nolibs -s ${PROJECT_SOURCE_DIR}/src/node_provider.d -o ${PROJECT_BINARY_DIR}/src/node_provider.o ${node_objs}
DEPENDS ${node_objs})
endif()
install(TARGETS node RUNTIME DESTINATION bin)
install(FILES
${PROJECT_BINARY_DIR}/config.h
src/node.h
src/node_object_wrap.h
src/node_buffer.h
src/node_events.h
src/node_version.h
${PROJECT_BINARY_DIR}/src/node_config.h
DESTINATION ${NODE_INCLUDE_PREFIX}/include/node
)

39
cmake/package.cmake Normal file
View File

@@ -0,0 +1,39 @@
#
# package
#
# Allow absolute paths when installing
# see http://www.cmake.org/pipermail/cmake/2008-July/022958.html
set(CPACK_SET_DESTDIR "ON")
if(${node_platform} MATCHES darwin)
set(CPACK_GENERATOR "TGZ;PackageMaker")
# CPack requires the files to end in .txt
configure_file(LICENSE ${PROJECT_BINARY_DIR}/LICENSE.txt COPYONLY)
configure_file(ChangeLog ${PROJECT_BINARY_DIR}/ChangeLog.txt COPYONLY)
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_BINARY_DIR}/LICENSE.txt")
set(CPACK_RESOURCE_FILE_README "${PROJECT_BINARY_DIR}/ChangeLog.txt")
#set(CPACK_RESOURCE_FILE_WELCOME "")
elseif(${node_platform} MATCHES linux)
set(CPACK_GENERATOR "TGZ;DEB;RPM")
else()
set(CPACK_GENERATOR "TGZ")
endif()
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Tom Hughes <tom.hughes@palm.com>")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Evented I/O for V8 JavaScript.")
set(CPACK_PACKAGE_DESCRIPTION "Evented I/O for V8 JavaScript.
Node's goal is to provide an easy way to build scalable network programs.
Node is similar in design to and influenced by systems like Ruby's Event
Machine or Python's Twisted. Node takes the event model a bit further—it
presents the event loop as a language construct instead of as a library.")
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION}")
set(CPACK_DEBIAN_PACKAGE_SECTION "web")
file(READ ${PROJECT_SOURCE_DIR}/src/node_version.h node_version_h OFFSET 0)
string(REGEX REPLACE ".*NODE_MAJOR_VERSION[ ]*([0-9]+).*" "\\1" CPACK_PACKAGE_VERSION_MAJOR "${node_version_h}")
string(REGEX REPLACE ".*NODE_MINOR_VERSION[ ]*([0-9]+).*" "\\1" CPACK_PACKAGE_VERSION_MINOR "${node_version_h}")
string(REGEX REPLACE ".*NODE_PATCH_VERSION[ ]*([0-9]+).*" "\\1" CPACK_PACKAGE_VERSION_PATCH "${node_version_h}")
set(node_version_string "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
# Note: this is intentionally at the bottom so that the above CPACK variables
# are used by CPack.
include(CPack)

102
cmake/v8_build.cmake Normal file
View File

@@ -0,0 +1,102 @@
#
# v8 build stuff
#
string(TOLOWER ${CMAKE_BUILD_TYPE} v8mode)
set(v8arch ${node_arch})
if(${node_arch} MATCHES x86_64)
set(v8arch x64)
elseif(${node_arch} MATCHES x86)
set(v8arch ia32)
endif()
if(NOT SHARED_V8)
if(V8_SNAPSHOT)
set(v8_snapshot snapshot=on)
endif()
if(V8_OPROFILE)
set(v8_oprofile prof=oprofile)
endif()
if(V8_GDBJIT)
set(v8_gdbjit gdbjit=on)
endif()
if(${node_platform} MATCHES darwin)
execute_process(COMMAND hwprefs cpu_count OUTPUT_VARIABLE cpu_count)
elseif(${node_platform} MATCHES linux)
execute_process(COMMAND sh -c "cat /proc/cpuinfo | grep processor | sort | uniq | wc -l"
OUTPUT_VARIABLE cpu_count)
elseif(${node_platform} MATCHES sunos)
execute_process(COMMAND sh -c "psrinfo | wc -l" OUTPUT_VARIABLE cpu_count)
else()
set(cpu_count 1)
endif()
if(${cpu_count} GREATER 1)
math(EXPR parallel_jobs ${cpu_count}*2)
else()
set(parallel_jobs 1)
endif()
add_library(v8 STATIC IMPORTED)
set_property(TARGET v8
PROPERTY IMPORTED_LOCATION ${PROJECT_BINARY_DIR}/deps/v8/${v8_fn})
set(compile_env_vars "CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} CFLAGS=\"${CMAKE_C_FLAGS}\" CXXFLAGS=\"${CMAKE_CXX_FLAGS}\" LDFLAGS=\"${CMAKE_EXE_LINKER_FLAGS}\"")
set(compile_cmd "${compile_env_vars} ${PYTHON_EXECUTABLE} ${PROJECT_BINARY_DIR}/tools/scons/scons.py -j ${parallel_jobs} visibility=default mode=${v8mode} arch=${v8arch} library=static ${v8_snapshot} ${v8_oprofile} ${v8_gdbjit} verbose=on")
if(CMAKE_VERSION VERSION_GREATER 2.8 OR CMAKE_VERSION VERSION_EQUAL 2.8)
# use ExternalProject for CMake >2.8
include(ExternalProject)
ExternalProject_Add(v8_extprj
URL ${PROJECT_SOURCE_DIR}/deps/v8
BUILD_IN_SOURCE True
BUILD_COMMAND sh -c "${compile_cmd}"
SOURCE_DIR ${PROJECT_BINARY_DIR}/deps/v8
# ignore this stuff, it's not needed for building v8 but ExternalProject
# demands these steps
CONFIGURE_COMMAND "true" # fake configure
INSTALL_COMMAND "true" # fake install
)
add_dependencies(node v8_extprj)
else()
# copy v8 sources inefficiently with CMake versions <2.8
file(GLOB_RECURSE v8_sources RELATIVE ${PROJECT_SOURCE_DIR} deps/v8/*)
if(NOT ${in_source_build})
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/deps/v8)
foreach(FILE ${v8_sources})
add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/${FILE}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_SOURCE_DIR}/${FILE} ${PROJECT_BINARY_DIR}/${FILE}
DEPENDS ${PROJECT_SOURCE_DIR}/${FILE}
)
list(APPEND v8_sources_dest ${PROJECT_BINARY_DIR}/${FILE})
endforeach()
else()
set(v8_sources_dest ${v8_sources})
endif()
add_custom_command(
OUTPUT ${PROJECT_BINARY_DIR}/deps/v8/${v8_fn}
COMMAND sh -c "${compile_cmd}"
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/deps/v8/
DEPENDS ${v8_sources_dest}
)
add_custom_target(v8_stock ALL DEPENDS ${PROJECT_BINARY_DIR}/deps/v8/${v8_fn})
set_property(TARGET v8 PROPERTY
IMPORTED_LOCATION ${PROJECT_BINARY_DIR}/deps/v8/${v8_fn})
add_dependencies(node v8_stock)
endif()
endif()

View File

@@ -1,246 +0,0 @@
{
'variables': {
'werror': '', # Turn off -Werror in V8 build.
'visibility%': 'hidden', # V8's visibility setting
'target_arch%': 'ia32', # set v8's target architecture
'host_arch%': 'ia32', # set v8's host architecture
'want_separate_host_toolset%': 0, # V8 should not build target and host
'library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds
'component%': 'static_library', # NB. these names match with what V8 expects
'msvs_multi_core_compile': '0', # we do enable multicore compiles, but not using the V8 way
'gcc_version%': 'unknown',
'clang%': 0,
'python%': 'python',
# Turn on optimizations that may trigger compiler bugs.
# Use at your own risk. Do *NOT* report bugs if this option is enabled.
'node_unsafe_optimizations%': 0,
# Enable V8's post-mortem debugging only on unix flavors.
'conditions': [
['OS != "win"', {
'v8_postmortem_support': 'true'
}],
['GENERATOR == "ninja" or OS== "mac"', {
'OBJ_DIR': '<(PRODUCT_DIR)/obj',
'V8_BASE': '<(PRODUCT_DIR)/libv8_base.a',
}, {
'OBJ_DIR': '<(PRODUCT_DIR)/obj.target',
'V8_BASE': '<(PRODUCT_DIR)/obj.target/deps/v8/tools/gyp/libv8_base.a',
}],
],
},
'target_defaults': {
'default_configuration': 'Release',
'configurations': {
'Debug': {
'defines': [ 'DEBUG', '_DEBUG' ],
'cflags': [ '-g', '-O0' ],
'conditions': [
['target_arch=="x64"', {
'msvs_configuration_platform': 'x64',
}],
],
'msvs_settings': {
'VCCLCompilerTool': {
'RuntimeLibrary': 1, # static debug
'Optimization': 0, # /Od, no optimization
'MinimalRebuild': 'false',
'OmitFramePointers': 'false',
'BasicRuntimeChecks': 3, # /RTC1
},
'VCLinkerTool': {
'LinkIncremental': 2, # enable incremental linking
},
},
'xcode_settings': {
'GCC_OPTIMIZATION_LEVEL': '0', # stop gyp from defaulting to -Os
},
},
'Release': {
'conditions': [
['target_arch=="x64"', {
'msvs_configuration_platform': 'x64',
}],
['node_unsafe_optimizations==1', {
'cflags': [ '-O3', '-ffunction-sections', '-fdata-sections' ],
'ldflags': [ '-Wl,--gc-sections' ],
}, {
'cflags': [ '-O2', '-fno-strict-aliasing' ],
'cflags!': [ '-O3', '-fstrict-aliasing' ],
'conditions': [
# Required by the dtrace post-processor. Unfortunately,
# some gcc/binutils combos generate bad code when
# -ffunction-sections is enabled. Let's hope for the best.
['OS=="solaris"', {
'cflags': [ '-ffunction-sections', '-fdata-sections' ],
}, {
'cflags!': [ '-ffunction-sections', '-fdata-sections' ],
}],
['clang == 0 and gcc_version >= 40', {
'cflags': [ '-fno-tree-vrp' ],
}],
['clang == 0 and gcc_version <= 44', {
'cflags': [ '-fno-tree-sink' ],
}],
],
}],
['OS=="solaris"', {
# pull in V8's postmortem metadata
'ldflags': [ '-Wl,-z,allextract' ]
}],
['OS!="mac" and OS!="win"', {
'cflags': [ '-fno-omit-frame-pointer' ],
}],
],
'msvs_settings': {
'VCCLCompilerTool': {
'RuntimeLibrary': 0, # static release
'Optimization': 3, # /Ox, full optimization
'FavorSizeOrSpeed': 1, # /Ot, favour speed over size
'InlineFunctionExpansion': 2, # /Ob2, inline anything eligible
'WholeProgramOptimization': 'true', # /GL, whole program optimization, needed for LTCG
'OmitFramePointers': 'true',
'EnableFunctionLevelLinking': 'true',
'EnableIntrinsicFunctions': 'true',
'RuntimeTypeInfo': 'false',
'ExceptionHandling': '0',
'AdditionalOptions': [
'/MP', # compile across multiple CPUs
],
},
'VCLibrarianTool': {
'AdditionalOptions': [
'/LTCG', # link time code generation
],
},
'VCLinkerTool': {
'LinkTimeCodeGeneration': 1, # link-time code generation
'OptimizeReferences': 2, # /OPT:REF
'EnableCOMDATFolding': 2, # /OPT:ICF
'LinkIncremental': 1, # disable incremental linking
},
},
}
},
'msvs_settings': {
'VCCLCompilerTool': {
'StringPooling': 'true', # pool string literals
'DebugInformationFormat': 3, # Generate a PDB
'WarningLevel': 3,
'BufferSecurityCheck': 'true',
'ExceptionHandling': 1, # /EHsc
'SuppressStartupBanner': 'true',
'WarnAsError': 'false',
},
'VCLibrarianTool': {
},
'VCLinkerTool': {
'conditions': [
['target_arch=="x64"', {
'TargetMachine' : 17 # /MACHINE:X64
}],
],
'GenerateDebugInformation': 'true',
'RandomizedBaseAddress': 2, # enable ASLR
'DataExecutionPrevention': 2, # enable DEP
'AllowIsolation': 'true',
'SuppressStartupBanner': 'true',
'target_conditions': [
['_type=="executable"', {
'SubSystem': 1, # console executable
}],
],
},
},
'conditions': [
['OS == "win"', {
'msvs_cygwin_shell': 0, # prevent actions from trying to use cygwin
'defines': [
'WIN32',
# we don't really want VC++ warning us about
# how dangerous C functions are...
'_CRT_SECURE_NO_DEPRECATE',
# ... or that C implementations shouldn't use
# POSIX names
'_CRT_NONSTDC_NO_DEPRECATE',
'BUILDING_V8_SHARED=1',
'BUILDING_UV_SHARED=1',
],
}],
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
'cflags': [ '-Wall', '-Wextra', '-Wno-unused-parameter', '-pthread', ],
'cflags_cc': [ '-fno-rtti', '-fno-exceptions' ],
'ldflags': [ '-pthread', '-rdynamic' ],
'target_conditions': [
['_type=="static_library"', {
'standalone_static_library': 1, # disable thin archive which needs binutils >= 2.19
}],
],
'conditions': [
[ 'target_arch=="ia32"', {
'cflags': [ '-m32' ],
'ldflags': [ '-m32' ],
}],
[ 'target_arch=="x64"', {
'cflags': [ '-m64' ],
'ldflags': [ '-m64' ],
}],
[ 'OS=="solaris"', {
'cflags': [ '-pthreads' ],
'ldflags': [ '-pthreads' ],
'cflags!': [ '-pthread' ],
'ldflags!': [ '-pthread' ],
}],
],
}],
['OS=="mac"', {
'defines': ['_DARWIN_USE_64_BIT_INODE=1'],
'xcode_settings': {
'ALWAYS_SEARCH_USER_PATHS': 'NO',
'GCC_CW_ASM_SYNTAX': 'NO', # No -fasm-blocks
'GCC_DYNAMIC_NO_PIC': 'NO', # No -mdynamic-no-pic
# (Equivalent to -fPIC)
'GCC_ENABLE_CPP_EXCEPTIONS': 'NO', # -fno-exceptions
'GCC_ENABLE_CPP_RTTI': 'NO', # -fno-rtti
'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings
'GCC_THREADSAFE_STATICS': 'NO', # -fno-threadsafe-statics
'PREBINDING': 'NO', # No -Wl,-prebind
'MACOSX_DEPLOYMENT_TARGET': '10.5', # -mmacosx-version-min=10.5
'USE_HEADERMAP': 'NO',
'OTHER_CFLAGS': [
'-fno-strict-aliasing',
],
'WARNING_CFLAGS': [
'-Wall',
'-Wendif-labels',
'-W',
'-Wno-unused-parameter',
],
},
'target_conditions': [
['_type!="static_library"', {
'xcode_settings': {'OTHER_LDFLAGS': ['-Wl,-search_paths_first']},
}],
],
'conditions': [
['target_arch=="ia32"', {
'xcode_settings': {'ARCHS': ['i386']},
}],
['target_arch=="x64"', {
'xcode_settings': {'ARCHS': ['x86_64']},
}],
],
}],
['OS=="freebsd" and node_use_dtrace=="true"', {
'libraries': [ '-lelf' ],
}],
['OS=="freebsd"', {
'ldflags': [
'-Wl,--export-dynamic',
],
}]
],
}
}

2
config.h.cmake Normal file
View File

@@ -0,0 +1,2 @@
#cmakedefine HAVE_OPENSSL 1
#cmakedefine HAVE_CONFIG_H 1

744
configure vendored
View File

@@ -1,733 +1,21 @@
#!/usr/bin/env python
import optparse
import os
import pprint
import re
import shlex
import subprocess
import sys
#! /bin/sh
CC = os.environ.get('CC', 'cc')
# v8 doesn't like ccache
if [ ! -z "`echo $CC | grep ccache`" ]; then
echo "Error: V8 doesn't like cache. Please set your CC env var to 'gcc'"
echo " (ba)sh: export CC=gcc"
exit 1
fi
root_dir = os.path.dirname(__file__)
sys.path.insert(0, os.path.join(root_dir, 'tools', 'gyp', 'pylib'))
from gyp.common import GetFlavor
CUR_DIR=$PWD
# parse our options
parser = optparse.OptionParser()
#possible relative path
WORKINGDIR=`dirname $0`
cd "$WORKINGDIR"
#abs path
WORKINGDIR=`pwd`
cd "$CUR_DIR"
parser.add_option("--debug",
action="store_true",
dest="debug",
help="Also build debug build")
"${WORKINGDIR}/tools/waf-light" --jobs=1 configure $*
parser.add_option("--prefix",
action="store",
dest="prefix",
help="Select the install prefix (defaults to /usr/local)")
parser.add_option("--without-npm",
action="store_true",
dest="without_npm",
help="Don\'t install the bundled npm package manager")
parser.add_option("--without-ssl",
action="store_true",
dest="without_ssl",
help="Build without SSL")
parser.add_option("--without-snapshot",
action="store_true",
dest="without_snapshot",
help="Build without snapshotting V8 libraries. You might want to set"
" this for cross-compiling. [Default: False]")
parser.add_option("--shared-v8",
action="store_true",
dest="shared_v8",
help="Link to a shared V8 DLL instead of static linking")
parser.add_option("--shared-v8-includes",
action="store",
dest="shared_v8_includes",
help="Directory containing V8 header files")
parser.add_option("--shared-v8-libpath",
action="store",
dest="shared_v8_libpath",
help="A directory to search for the shared V8 DLL")
parser.add_option("--shared-v8-libname",
action="store",
dest="shared_v8_libname",
help="Alternative lib name to link to (default: 'v8')")
parser.add_option("--shared-openssl",
action="store_true",
dest="shared_openssl",
help="Link to a shared OpenSSl DLL instead of static linking")
parser.add_option("--shared-openssl-includes",
action="store",
dest="shared_openssl_includes",
help="Directory containing OpenSSL header files")
parser.add_option("--shared-openssl-libpath",
action="store",
dest="shared_openssl_libpath",
help="A directory to search for the shared OpenSSL DLLs")
parser.add_option("--shared-openssl-libname",
action="store",
dest="shared_openssl_libname",
help="Alternative lib name to link to (default: 'crypto,ssl')")
parser.add_option("--openssl-no-asm",
action="store_true",
dest="openssl_no_asm",
help="Do not build optimized assembly for OpenSSL")
# deprecated
parser.add_option("--openssl-use-sys",
action="store_true",
dest="shared_openssl",
help=optparse.SUPPRESS_HELP)
# deprecated
parser.add_option("--openssl-includes",
action="store",
dest="shared_openssl_includes",
help=optparse.SUPPRESS_HELP)
# deprecated
parser.add_option("--openssl-libpath",
action="store",
dest="shared_openssl_libpath",
help=optparse.SUPPRESS_HELP)
# TODO document when we've decided on what the tracing API and its options will
# look like
parser.add_option("--systemtap-includes",
action="store",
dest="systemtap_includes",
help=optparse.SUPPRESS_HELP)
parser.add_option("--without-ssl2",
action="store_true",
dest="ssl2",
help="Disable SSL v2")
parser.add_option("--without-ssl3",
action="store_true",
dest="ssl3",
help="Disable SSL v3")
parser.add_option("--shared-zlib",
action="store_true",
dest="shared_zlib",
help="Link to a shared zlib DLL instead of static linking")
parser.add_option("--shared-zlib-includes",
action="store",
dest="shared_zlib_includes",
help="Directory containing zlib header files")
parser.add_option("--shared-zlib-libpath",
action="store",
dest="shared_zlib_libpath",
help="A directory to search for the shared zlib DLL")
parser.add_option("--shared-zlib-libname",
action="store",
dest="shared_zlib_libname",
help="Alternative lib name to link to (default: 'z')")
parser.add_option("--shared-http-parser",
action="store_true",
dest="shared_http_parser",
help="Link to a shared http_parser DLL instead of static linking")
parser.add_option("--shared-http-parser-includes",
action="store",
dest="shared_http_parser_includes",
help="Directory containing http_parser header files")
parser.add_option("--shared-http-parser-libpath",
action="store",
dest="shared_http_parser_libpath",
help="A directory to search for the shared http_parser DLL")
parser.add_option("--shared-http-parser-libname",
action="store",
dest="shared_http_parser_libname",
help="Alternative lib name to link to (default: 'http_parser')")
parser.add_option("--shared-cares",
action="store_true",
dest="shared_cares",
help="Link to a shared cares DLL instead of static linking")
parser.add_option("--shared-cares-includes",
action="store",
dest="shared_cares_includes",
help="Directory containing cares header files")
parser.add_option("--shared-cares-libpath",
action="store",
dest="shared_cares_libpath",
help="A directory to search for the shared cares DLL")
parser.add_option("--shared-cares-libname",
action="store",
dest="shared_cares_libname",
help="Alternative lib name to link to (default: 'cares')")
parser.add_option("--shared-libuv",
action="store_true",
dest="shared_libuv",
help="Link to a shared libuv DLL instead of static linking")
parser.add_option("--shared-libuv-includes",
action="store",
dest="shared_libuv_includes",
help="Directory containing libuv header files")
parser.add_option("--shared-libuv-libpath",
action="store",
dest="shared_libuv_libpath",
help="A directory to search for the shared libuv DLL")
parser.add_option("--shared-libuv-libname",
action="store",
dest="shared_libuv_libname",
help="Alternative lib name to link to (default: 'uv')")
parser.add_option("--with-dtrace",
action="store_true",
dest="with_dtrace",
help="Build with DTrace (default is true on sunos)")
parser.add_option("--without-dtrace",
action="store_true",
dest="without_dtrace",
help="Build without DTrace")
parser.add_option("--with-etw",
action="store_true",
dest="with_etw",
help="Build with ETW (default is true on Windows)")
parser.add_option("--without-etw",
action="store_true",
dest="without_etw",
help="Build without ETW")
parser.add_option("--with-perfctr",
action="store_true",
dest="with_perfctr",
help="Build with performance counters (default is true on Windows)")
parser.add_option("--without-perfctr",
action="store_true",
dest="without_perfctr",
help="Build without performance counters")
# CHECKME does this still work with recent releases of V8?
parser.add_option("--gdb",
action="store_true",
dest="gdb",
help="add gdb support")
parser.add_option("--dest-cpu",
action="store",
dest="dest_cpu",
help="CPU architecture to build for. Valid values are: arm, ia32, x64")
parser.add_option("--dest-os",
action="store",
dest="dest_os",
help="Operating system to build for. Valid values are: "
"win, mac, solaris, freebsd, openbsd, linux")
parser.add_option("--no-ifaddrs",
action="store_true",
dest="no_ifaddrs",
help="Use on deprecated SunOS systems that do not support ifaddrs.h")
parser.add_option("--with-arm-float-abi",
action="store",
dest="arm_float_abi",
help="Specifies which floating-point ABI to use. Valid values are: "
"soft, softfp, hard")
parser.add_option("--with-mips-float-abi",
action="store",
dest="mips_float_abi",
help="Specifies which floating-point ABI to use. Valid values are: "
"soft, hard")
parser.add_option("--ninja",
action="store_true",
dest="use_ninja",
help="Generate files for the ninja build system")
# Using --unsafe-optimizations voids your warranty.
parser.add_option("--unsafe-optimizations",
action="store_true",
dest="unsafe_optimizations",
help=optparse.SUPPRESS_HELP)
parser.add_option("--xcode",
action="store_true",
dest="use_xcode",
help="Generate build files for use with xcode")
parser.add_option("--tag",
action="store",
dest="tag",
help="Custom build tag")
(options, args) = parser.parse_args()
def b(value):
"""Returns the string 'true' if value is truthy, 'false' otherwise."""
if value:
return 'true'
else:
return 'false'
def pkg_config(pkg):
cmd = os.popen('pkg-config --libs %s' % pkg, 'r')
libs = cmd.readline().strip()
ret = cmd.close()
if (ret): return None
cmd = os.popen('pkg-config --cflags %s' % pkg, 'r')
cflags = cmd.readline().strip()
ret = cmd.close()
if (ret): return None
return (libs, cflags)
def cc_macros():
"""Checks predefined macros using the CC command."""
try:
p = subprocess.Popen(shlex.split(CC) + ['-dM', '-E', '-'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
except OSError:
print '''Node.js configure error: No acceptable C compiler found!
Please make sure you have a C compiler installed on your system and/or
consider adjusting the CC environment variable if you installed
it in a non-standard prefix.
'''
sys.exit()
p.stdin.write('\n')
out = p.communicate()[0]
out = str(out).split('\n')
k = {}
for line in out:
lst = shlex.split(line)
if len(lst) > 2:
key = lst[1]
val = lst[2]
k[key] = val
return k
def is_arch_armv7():
"""Check for ARMv7 instructions"""
cc_macros_cache = cc_macros()
return ('__ARM_ARCH_7__' in cc_macros_cache or
'__ARM_ARCH_7A__' in cc_macros_cache or
'__ARM_ARCH_7R__' in cc_macros_cache or
'__ARM_ARCH_7M__' in cc_macros_cache)
def is_arm_neon():
"""Check for ARM NEON support"""
return '__ARM_NEON__' in cc_macros()
def arm_hard_float_abi():
"""Check for hardfloat or softfloat eabi on ARM"""
# GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify
# the Floating Point ABI used (PCS stands for Procedure Call Standard).
# We use these as well as a couple of other defines to statically determine
# what FP ABI used.
# GCC versions 4.4 and below don't support hard-fp.
# GCC versions 4.5 may support hard-fp without defining __ARM_PCS or
# __ARM_PCS_VFP.
if compiler_version() >= (4, 6, 0):
return '__ARM_PCS_VFP' in cc_macros()
elif compiler_version() < (4, 5, 0):
return False
elif '__ARM_PCS_VFP' in cc_macros():
return True
elif ('__ARM_PCS' in cc_macros() or
'__SOFTFP' in cc_macros() or
not '__VFP_FP__' in cc_macros()):
return False
else:
print '''Node.js configure error: Your version of GCC does not report
the Floating-Point ABI to compile for your hardware
Please manually specify which floating-point ABI to use with the
--with-arm-float-abi option.
'''
sys.exit()
def host_arch_cc():
"""Host architecture check using the CC command."""
k = cc_macros()
matchup = {
'__x86_64__' : 'x64',
'__i386__' : 'ia32',
'__arm__' : 'arm',
'__mips__' : 'mips',
}
rtn = 'ia32' # default
for i in matchup:
if i in k and k[i] != '0':
rtn = matchup[i]
break
return rtn
def host_arch_win():
"""Host architecture check using environ vars (better way to do this?)"""
arch = os.environ.get('PROCESSOR_ARCHITECTURE', 'x86')
matchup = {
'AMD64' : 'x64',
'x86' : 'ia32',
'arm' : 'arm',
'mips' : 'mips',
}
return matchup.get(arch, 'ia32')
def compiler_version():
try:
proc = subprocess.Popen(shlex.split(CC) + ['--version'], stdout=subprocess.PIPE)
except WindowsError:
return (0, False)
is_clang = 'clang' in proc.communicate()[0].split('\n')[0]
proc = subprocess.Popen(shlex.split(CC) + ['-dumpversion'], stdout=subprocess.PIPE)
version = tuple(map(int, proc.communicate()[0].split('.')))
return (version, is_clang)
def configure_arm(o):
# V8 on ARM requires that armv7 is set. CPU Model detected by
# the presence of __ARM_ARCH_7__ and the like defines in compiler
if options.arm_float_abi:
hard_float = options.arm_float_abi == 'hard'
else:
hard_float = arm_hard_float_abi()
armv7 = is_arch_armv7()
# CHECKME VFPv3 implies ARMv7+ but is the reverse true as well?
fpu = 'vfpv3' if armv7 else 'vfpv2'
o['variables']['armv7'] = int(armv7)
o['variables']['arm_fpu'] = fpu
o['variables']['arm_neon'] = int(is_arm_neon())
o['variables']['v8_use_arm_eabi_hardfloat'] = b(hard_float)
def configure_mips(o):
if options.mips_float_abi:
if options.mips_float_abi in ('soft', 'hard'):
o['variables']['v8_use_mips_abi_hardfloat'] = b(
options.mips_float_abi == 'hard')
else:
raise Exception(
'Invalid mips-float-abi value. Valid values are: soft, hard')
def configure_node(o):
o['variables']['v8_enable_gdbjit'] = 1 if options.gdb else 0
o['variables']['v8_no_strict_aliasing'] = 1 # work around compiler bugs
o['variables']['node_prefix'] = os.path.expanduser(options.prefix or '')
o['variables']['node_install_npm'] = b(not options.without_npm)
o['variables']['node_unsafe_optimizations'] = (
1 if options.unsafe_optimizations else 0)
o['default_configuration'] = 'Debug' if options.debug else 'Release'
host_arch = host_arch_win() if os.name == 'nt' else host_arch_cc()
target_arch = options.dest_cpu or host_arch
o['variables']['host_arch'] = host_arch
o['variables']['target_arch'] = target_arch
if target_arch != host_arch and not options.without_snapshot:
o['variables']['want_separate_host_toolset'] = 1
else:
o['variables']['want_separate_host_toolset'] = 0
if target_arch == 'arm':
configure_arm(o)
elif target_arch in ('mips', 'mipsel'):
configure_mips(o)
cc_version, is_clang = compiler_version()
o['variables']['clang'] = 1 if is_clang else 0
if not is_clang and cc_version != 0:
o['variables']['gcc_version'] = 10 * cc_version[0] + cc_version[1]
# clang has always supported -fvisibility=hidden, right?
if not is_clang and cc_version < (4,0,0):
o['variables']['visibility'] = ''
# By default, enable DTrace on SunOS systems. Don't allow it on other
# systems, since it won't work. (The MacOS build process is different than
# SunOS, and we haven't implemented it.)
if flavor in ('solaris', 'mac'):
o['variables']['node_use_dtrace'] = b(not options.without_dtrace)
elif flavor == 'freebsd':
o['variables']['node_use_dtrace'] = b(options.with_dtrace)
elif flavor == 'linux':
o['variables']['node_use_dtrace'] = 'false'
o['variables']['node_use_systemtap'] = b(options.with_dtrace)
if options.systemtap_includes:
o['include_dirs'] += [options.systemtap_includes]
elif options.with_dtrace:
raise Exception(
'DTrace is currently only supported on SunOS, MacOS or Linux systems.')
else:
o['variables']['node_use_dtrace'] = 'false'
o['variables']['node_use_systemtap'] = 'false'
if options.no_ifaddrs:
o['defines'] += ['SUNOS_NO_IFADDRS']
# By default, enable ETW on Windows.
if flavor == 'win':
o['variables']['node_use_etw'] = b(not options.without_etw);
elif options.with_etw:
raise Exception('ETW is only supported on Windows.')
else:
o['variables']['node_use_etw'] = 'false'
# By default, enable Performance counters on Windows.
if flavor == 'win':
o['variables']['node_use_perfctr'] = b(not options.without_perfctr);
elif options.with_perfctr:
raise Exception('Performance counter is only supported on Windows.')
else:
o['variables']['node_use_perfctr'] = 'false'
if options.tag:
o['variables']['node_tag'] = '-' + options.tag
else:
o['variables']['node_tag'] = ''
def configure_libz(o):
o['variables']['node_shared_zlib'] = b(options.shared_zlib)
# assume shared_zlib if one of these is set?
if options.shared_zlib_libpath:
o['libraries'] += ['-L%s' % options.shared_zlib_libpath]
if options.shared_zlib_libname:
o['libraries'] += ['-l%s' % options.shared_zlib_libname]
elif options.shared_zlib:
o['libraries'] += ['-lz']
if options.shared_zlib_includes:
o['include_dirs'] += [options.shared_zlib_includes]
def configure_http_parser(o):
o['variables']['node_shared_http_parser'] = b(options.shared_http_parser)
# assume shared http_parser if one of these is set?
if options.shared_http_parser_libpath:
o['libraries'] += ['-L%s' % options.shared_http_parser_libpath]
if options.shared_http_parser_libname:
o['libraries'] += ['-l%s' % options.shared_http_parser_libname]
elif options.shared_http_parser:
o['libraries'] += ['-lhttp_parser']
if options.shared_http_parser_includes:
o['include_dirs'] += [options.shared_http_parser_includes]
def configure_cares(o):
o['variables']['node_shared_cares'] = b(options.shared_cares)
# assume shared cares if one of these is set?
if options.shared_cares_libpath:
o['libraries'] += ['-L%s' % options.shared_cares_libpath]
if options.shared_cares_libname:
o['libraries'] += ['-l%s' % options.shared_cares_libname]
elif options.shared_cares:
o['libraries'] += ['-lcares']
if options.shared_cares_includes:
o['include_dirs'] += [options.shared_cares_includes]
def configure_libuv(o):
o['variables']['node_shared_libuv'] = b(options.shared_libuv)
# assume shared libuv if one of these is set?
if options.shared_libuv_libpath:
o['libraries'] += ['-L%s' % options.shared_libuv_libpath]
if options.shared_libuv_libname:
o['libraries'] += ['-l%s' % options.shared_libuv_libname]
elif options.shared_libuv:
o['libraries'] += ['-luv']
if options.shared_libuv_includes:
o['include_dirs'] += [options.shared_libuv_includes]
def configure_v8(o):
o['variables']['v8_use_snapshot'] = b(not options.without_snapshot)
o['variables']['node_shared_v8'] = b(options.shared_v8)
# assume shared_v8 if one of these is set?
if options.shared_v8_libpath:
o['libraries'] += ['-L%s' % options.shared_v8_libpath]
if options.shared_v8_libname:
o['libraries'] += ['-l%s' % options.shared_v8_libname]
elif options.shared_v8:
o['libraries'] += ['-lv8']
if options.shared_v8_includes:
o['include_dirs'] += [options.shared_v8_includes]
def configure_openssl(o):
o['variables']['node_use_openssl'] = b(not options.without_ssl)
o['variables']['node_shared_openssl'] = b(options.shared_openssl)
o['variables']['openssl_no_asm'] = (
1 if options.openssl_no_asm else 0)
if options.without_ssl:
return
if options.ssl2:
o['defines'] += ['OPENSSL_NO_SSL2=1']
if options.ssl3:
o['defines'] += ['OPENSSL_NO_SSL3=1']
if options.shared_openssl:
(libs, cflags) = pkg_config('openssl') or ('-lssl -lcrypto', '')
if options.shared_openssl_libpath:
o['libraries'] += ['-L%s' % options.shared_openssl_libpath]
if options.shared_openssl_libname:
libnames = options.shared_openssl_libname.split(',')
o['libraries'] += ['-l%s' % s for s in libnames]
else:
o['libraries'] += libs.split()
if options.shared_openssl_includes:
o['include_dirs'] += [options.shared_openssl_includes]
else:
o['cflags'] += cflags.split()
def configure_winsdk(o):
if flavor != 'win':
return
winsdk_dir = os.environ.get("WindowsSdkDir")
if winsdk_dir and os.path.isfile(winsdk_dir + '\\bin\\ctrpp.exe'):
print "Found ctrpp in WinSDK--will build generated files into tools/msvs/genfiles."
o['variables']['node_has_winsdk'] = 'true'
return
print "ctrpp not found in WinSDK path--using pre-gen files from tools/msvs/genfiles."
# determine the "flavor" (operating system) we're building for,
# leveraging gyp's GetFlavor function
flavor_params = {};
if (options.dest_os):
flavor_params['flavor'] = options.dest_os;
flavor = GetFlavor(flavor_params);
output = {
'variables': { 'python': sys.executable },
'include_dirs': [],
'libraries': [],
'defines': [],
'cflags': [],
}
configure_node(output)
configure_libz(output)
configure_http_parser(output)
configure_cares(output)
configure_libuv(output)
configure_v8(output)
configure_openssl(output)
configure_winsdk(output)
# variables should be a root level element,
# move everything else to target_defaults
variables = output['variables']
del output['variables']
output = {
'variables': variables,
'target_defaults': output
}
pprint.pprint(output, indent=2)
def write(filename, data):
filename = os.path.join(root_dir, filename)
print "creating ", filename
f = open(filename, 'w+')
f.write(data)
write('config.gypi', "# Do not edit. Generated by the configure script.\n" +
pprint.pformat(output, indent=2) + "\n")
config = {
'BUILDTYPE': 'Debug' if options.debug else 'Release',
'USE_NINJA': str(int(options.use_ninja or 0)),
'USE_XCODE': str(int(options.use_xcode or 0)),
'PYTHON': sys.executable,
}
config = '\n'.join(map('='.join, config.iteritems())) + '\n'
write('config.mk',
'# Do not edit. Generated by the configure script.\n' + config)
gyp_args = [sys.executable, 'tools/gyp_node.py', '--no-parallel']
if options.use_ninja:
gyp_args += ['-f', 'ninja-' + flavor]
elif options.use_xcode:
gyp_args += ['-f', 'xcode']
elif flavor == 'win':
gyp_args += ['-f', 'msvs', '-G', 'msvs_version=auto']
else:
gyp_args += ['-f', 'make-' + flavor]
gyp_args += args
sys.exit(subprocess.call(gyp_args))
exit $?

Some files were not shown because too many files have changed in this diff Show More